Skip to content

Conversation

@GrzegorzDrozd
Copy link
Contributor

  • add duration tracking
  • add returned rows tracking
  • add pending operations metric
  • add active connections metric
  • minor code fixes

@codecov
Copy link

codecov bot commented Jun 16, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.41%. Comparing base (42f350a) to head (d835a35).

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##               main     #391      +/-   ##
============================================
+ Coverage     73.42%   82.41%   +8.99%     
- Complexity      134     2348    +2214     
============================================
  Files            11      165     +154     
  Lines           459     8904    +8445     
============================================
+ Hits            337     7338    +7001     
- Misses          122     1566    +1444     
Flag Coverage Δ
Aws 93.37% <ø> (?)
Context/Swoole 0.00% <ø> (?)
Exporter/Instana 49.80% <ø> (?)
Instrumentation/AwsSdk 82.00% <ø> (?)
Instrumentation/CakePHP 20.42% <ø> (?)
Instrumentation/CodeIgniter 79.31% <ø> (+0.31%) ⬆️
Instrumentation/Curl 87.15% <ø> (?)
Instrumentation/Doctrine 92.82% <ø> (?)
Instrumentation/ExtAmqp 88.80% <ø> (?)
Instrumentation/ExtRdKafka 86.13% <ø> (?)
Instrumentation/Guzzle 76.25% <ø> (?)
Instrumentation/HttpAsyncClient 78.94% <ø> (?)
Instrumentation/IO 0.00% <ø> (ø)
Instrumentation/Laravel 71.65% <ø> (?)
Instrumentation/MongoDB 76.84% <ø> (?)
Instrumentation/MySqli 93.39% <ø> (?)
Instrumentation/OpenAIPHP 86.71% <ø> (?)
Instrumentation/PostgreSql 91.36% <ø> (?)
Instrumentation/Psr14 77.41% <ø> (?)
Instrumentation/Psr15 89.74% <ø> (?)
Instrumentation/Psr16 97.43% <ø> (?)
Instrumentation/Psr18 79.41% <ø> (+1.94%) ⬆️
Instrumentation/Psr3 67.70% <ø> (?)
Instrumentation/Psr6 97.56% <ø> (?)
Instrumentation/ReactPHP 99.41% <ø> (?)
Instrumentation/Session 94.28% <ø> (-0.24%) ⬇️
Instrumentation/Slim 84.21% <ø> (?)
Instrumentation/Symfony 84.79% <ø> (?)
Instrumentation/Yii 83.33% <ø> (?)
Logs/Monolog 100.00% <ø> (?)
Propagation/CloudTrace 90.69% <ø> (+0.92%) ⬆️
Propagation/Instana 98.07% <ø> (?)
Propagation/ServerTiming 94.73% <ø> (?)
Propagation/TraceResponse 94.73% <ø> (?)
ResourceDetectors/Azure 91.66% <ø> (?)
ResourceDetectors/Container 93.02% <ø> (ø)
ResourceDetectors/DigitalOcean 100.00% <ø> (?)
Sampler/RuleBased 32.14% <ø> (?)
Sampler/Xray 78.38% <ø> (?)
Shims/OpenTracing 92.99% <ø> (?)
SqlCommenter 95.58% <ø> (?)
Symfony 88.14% <ø> (?)
Utils/Test 87.79% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 160 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 42f350a...d835a35. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@brettmc
Copy link
Contributor

brettmc commented Jun 27, 2025

@GrzegorzDrozd I've finally had some time to look at metrics generation. I started down the path of tracking everything in pre and post hooks, in #396 - when I got something working I started to realise that I was duplicating a lot of effort from tracing (and some attributes were really hard to get for a metric since you can start a span and add to it while it's in progress, whereas a metric is a single call).

Since in my case (an HTTP server span), everything I need seems to be already stored in a span, I tried a different approach (I guess loosely based on span metrics connector and implemented a Span Processor to emit metrics: https://github.com/open-telemetry/opentelemetry-php/pull/1651/files#diff-9ed562697c2c477790ec9394f926eeb261f2433f39fb3eeca3e7999ee7c390dbR54

Looking at your implementation here, I see a similar pattern:

  1. start a span
  2. start some timers and track some objects
  3. end a span
  4. calculate duration/s and counts from timers and trackers, gather attributes, emit metric/s

The metrics are closely related to the spans generated nearby.

Given that duration and most of the attributes you're interested in are already in a span, do you think you could achieve your goals with a span processor?

@GrzegorzDrozd
Copy link
Contributor Author

GrzegorzDrozd commented Jul 20, 2025

@GrzegorzDrozd I've finally had some time to look at metrics generation. I started down the path of tracking everything in pre and post hooks, in #396 - when I got something working I started to realise that I was duplicating a lot of effort from tracing (and some attributes were really hard to get for a metric since you can start a span and add to it while it's in progress, whereas a metric is a single call).

Since in my case (an HTTP server span), everything I need seems to be already stored in a span, I tried a different approach (I guess loosely based on span metrics connector and implemented a Span Processor to emit metrics: https://github.com/open-telemetry/opentelemetry-php/pull/1651/files#diff-9ed562697c2c477790ec9394f926eeb261f2433f39fb3eeca3e7999ee7c390dbR54

Looking at your implementation here, I see a similar pattern:

1. start a span

2. start some timers and track some objects

3. end a span

4. calculate duration/s and counts from timers and trackers, gather attributes, emit metric/s

The metrics are closely related to the spans generated nearby.

Given that duration and most of the attributes you're interested in are already in a span, do you think you could achieve your goals with a span processor?

But that would force someone to use spans with metrics? What if they want only to use metrics? What about sampling? So with this argument I think I should move my code outside of hooks with spans and create separate code, so that we would allow using metrics without spans ...

@brettmc
Copy link
Contributor

brettmc commented Jul 21, 2025

But that would force someone to use spans with metrics? What if they want only to use metrics? What about sampling? So with this argument I think I should move my code outside of hooks with spans and create separate code, so that we would allow using metrics without spans ...

Yes it would...but we're creating spans anyway (even if they're no-op). Anyway, I'm not saying we have to do it that way, I just want to make sure we need the extra tracking/timing classes before accepting the ongoing maintenance.

$parent = Context::getCurrent();

$instrumentation->meter()
->createUpDownCounter('db.client.connection.count', '1')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be creating a new instrument each time, or one that is reused?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All examples I found always created new meter. I assume this is a cheap operation. Re-using that would be much more complicated I think.

): void {
$parent = Context::getCurrent();
$instrumentation->meter()
->createHistogram('db.client.operation.duration', 'ms')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The db.client.operation.duration metric should use seconds s as the unit.

# Conflicts:
#	src/Instrumentation/PDO/src/PDOInstrumentation.php
@GrzegorzDrozd
Copy link
Contributor Author

GrzegorzDrozd commented Oct 26, 2025

Hi @brettmc

Question (I am tagging you because you answered in my PR but if you think this is a topic for more wide audience please tag people that need to see it):
There is not much metric related code in contrib modules, and because of that: do we want to add metrics to existing span processing or create separate files to allow developers to chose if they want to use metrics, spans or metrics + spans?
In this example: PDOInstrumentation should contain code for both or should I create PDOMetrics with separate hook and register and deal with metrics just there?
I have no idea how other languages handle those :/ I could not find much in go-contrib, java-contrib. In js-contrib i see that PostgreSQL exposes duration and code is included in main instrumentation flow.

If you wish I can create a thread in Slack for more interactive discussion.

@brettmc
Copy link
Contributor

brettmc commented Oct 27, 2025

do we want to add metrics to existing span processing or create separate files to allow developers to chose if they want to use metrics, spans or metrics + spans

Great question. I think it makes sense to include them in the existing instrumentation modules (pdo, postgres, etc). Perhaps initially with an opt-in by env var?

- code update, dependency update
- fix duration metric
@GrzegorzDrozd
Copy link
Contributor Author

@brettmc Please take a look again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants