-
Notifications
You must be signed in to change notification settings - Fork 117
feat: sqlcommenter for PDO, MySqli, PostgreSql (pdo_mysql, pdo_pgsql) #442
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: sqlcommenter for PDO, MySqli, PostgreSql (pdo_mysql, pdo_pgsql) #442
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #442 +/- ##
============================================
+ Coverage 81.17% 82.52% +1.35%
- Complexity 1454 2414 +960
============================================
Files 102 167 +65
Lines 5439 9711 +4272
============================================
+ Hits 4415 8014 +3599
- Misses 1024 1697 +673 Flags with carried forward coverage won't be shown. Click here to find out more.
... and 69 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
{ | ||
use LogsMessagesTrait; | ||
|
||
public function create(): ?TextMapPropagatorInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not understanding the point of this (actually, the entire src/ContextPropagator
)... isn't that what open-telemetry/opentelemetry-php#1712 does?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are not the same.
The response propagator in open-telemetry/opentelemetry-php#1712 supports propagating context in the http response.
(e.g. Propagate server-timing and traceresponse in the http response of slim instrumentation).
< HTTP/1.1 200 OK
< Host: localhost:8080
< Date: Thu, 11 Sep 2025 23:28:27 GMT
< Connection: close
< X-Powered-By: PHP/8.3.6
< server-timing: traceparent;desc=00-73dbf0f78c24b08faf273fee7ae5d77b-76c077b8629b08d1-01
< traceresponse: 00-73dbf0f78c24b08faf273fee7ae5d77b-76c077b8629b08d1-01
< Content-type: text/html; charset=UTF-8
The context propagator in this PR works quite similar to the propagator OTEL_PROPAGATORS
in the SDK. However, they are not the same.
OTEL_PROPAGATORS=baggage,tracecontext
propagates baggage and tracecontext from one service to another service.
The context propagator propagates context from one service to the database (via sqlcommenter & query statement). The spec mentioned the instrumentation should allow user to pass a propagator to overwrite the global propagator. This context propagator maintains a list of propagator to serve that purpose.
e.g.
OTEL_EXPERIMENTAL_RESPONSE_PROPAGATORS=servertiming,traceresponse OTEL_PROPAGATORS=b3,baggage,tracecontext OTEL_PHP_INSTRUMENTATION_CONTEXT_PROPAGATORS=tracecontext
means
- Propagating
server-timing
&traceresponse
in http instrumentation library (e.g. slim...) - Propagating
b3
,baggage
&tracecontext
across service - Propagating
tracecontext
to database
OTEL_EXPERIMENTAL_RESPONSE_PROPAGATORS=servertiming,traceresponse OTEL_PROPAGATORS=b3,baggage,tracecontext
means
- Propagating
server-timing
&traceresponse
in http instrumentation library (e.g. slim...) - Propagating
b3
,baggage
&tracecontext
across service and database
Let me know if it is making sense to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the previous PR #406 ContextPropagator
was under the PDO Instrumentation and thus naming made some sense. If we move it out like proposed in this PR, it should be renamed to something like SqlCommenterContext...
. Also, any reason this class can't just be part of the SqlCommenter i.e under the proposed src/SqlCommenter
directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beside sqlcommenter, there are other ways to propagate the context to database. e.g. https://opentelemetry.io/docs/specs/semconv/database/sql-server/#set-context_info & open-telemetry/semantic-conventions#2610
So I think it would be better to decouple the context propagator logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SET_CONTEXT_INFO and V$SESSION.ACTION work pretty differently from SQL Commenting and are prescriptive in the value type/size that can be injected, meaning i don't think they'd take a composite list of propagators. The example implementations i can find so far do not introduce a generic "database context propagator" concept:
- [Instrumentation.SqlClient] Introducing context propagation to SQL Server opentelemetry-dotnet-contrib#2709
- [jdbc] Oracle database context propagation signalfx/splunk-otel-java#2405
Or maybe i misunderstand your intention with this ContextPropagator
package--how do you envision using it for SET_CONTEXT_INFO / V$SESSION.ACTION propagation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I envision ContextPropagator acts as the source of the database context and put the information into a list, and SqlCommenter / SET_CONTEXT_INFO / V$SESSION.ACTION propagation can retrieve the required information from the list and propagate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... mentioned the instrumentation should allow user to pass a propagator to overwrite the global propagator
So can we describe this component as a "per-service context propagator override", and give it a more meaningful name? (It's too similar to the core context propagation concept, IMO, and will cause confusion).
The reason I call out "per-service" (or per system/component/something), is to allow for a scenario where an application connects to multiple databases, and wants to propagate context to each of them in a different way. That doesn't seem unreasonable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, "per-service / per-system / per-component / something context propagator override" seems reasonable to me.
To clarify more and make sure we are on the same page.
Says we have an application using PDO to connect multiple databases
- MySqli (
pdo_mysql
) - PostgreSQL (
pdo_pgsql
) - Oracle Database (
pdo_oci
) - SQL Server (
pdo_sqlsrv
) - IBM DB2 (
pdo_ibm
) - Firebird (
pdo_firebird
)
Ways of context propagation
- As all above database supports C-style comments, the context could be propagated via sqlcommenter
e.g.
SELECT * FROM songs /*traceparent='00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01',tracestate='congo%3Dt61rcWkgMzE%2Crojo%3D00f067aa0ba902b7'*/
- SQL Server could use SET CONTEXT_INFO way to propagate traceparent (55 bytes) only (128 bytes length limitation)
e.g.
DECLARE @traceparent varbinary(55);
SET @traceparent = CAST('00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01' AS varbinary(55));
SET CONTEXT_INFO @traceparent;
Then run the query
4. Oracle database opts for V$SESSION.ACTION way to propagate traceparent
e.g.
BEGIN
DBMS_APPLICATION_INFO.SET_ACTION('00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01');
END;
Then run the query
Questions
- Does it mean the "context propagator overrides" in this case should be
per-component
?
e.g. I tried to mock up the names for illustrations.
OTEL_DATABASE_CONTEXT_PROPAGATORS_FOR_SQLCOMMENTER=tracecontext
OTEL_DATABASE_CONTEXT_PROPAGATORS_FOR_SET_CONTEXT_INFO=tracecontext
OTEL_DATABASE_CONTEXT_PROPAGATORS_FOR_SET_ACTION=tracecontext
- Should Oracle database (pdo_oci) opt for
V$SESSION.ACTION
(highest priority) >SET CONTEXT_INFO
>sqlcommenter
(least priority )? - Should MySqli (pdo_mysql) opt for
sqlcommenter
only as it doesn't support other propagation ways?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brettmc I moved the propagator logic into SqlCommenter namespace so as to describe that as a "per sqlcommenter (component) context propagator override". Please take a look to see if I get your point correctly. Thanks!
|
||
self::addTransactionLink($tracker, $span, $mysqli); | ||
|
||
if (class_exists('OpenTelemetry\Contrib\SqlCommenter\SqlCommenter') && $query !== self::UNDEFINED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the previous PR #406 the SQL Commenter feature was enabled via an explicit configuration. This PR proposes instead the customers opt-in by installing the sqlcommenter
package, correct? Can the READMEs for each database instrumentation be updated to provide usage / configuration info?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the opt-in is by installing the sqlcommenter & context-propagator.
Updated the README.md per each database instrumentation library.
if (class_exists('OpenTelemetry\Contrib\SqlCommenter\SqlCommenter')) { | ||
$query = \OpenTelemetry\Contrib\SqlCommenter\SqlCommenter::inject($query, $comments); | ||
} | ||
if (class_exists('OpenTelemetry\Contrib\ContextPropagator\ContextPropagation') && \OpenTelemetry\Contrib\ContextPropagator\ContextPropagation::isAttributeEnabled()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit and personal opinion, this should be a SqlCommenter (not ContextPropagation) configuration option, whether the db query text attribute reflects value pre-or-post comment injection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There could be other ways (e.g. SET_CONTEXT_INFO / V$SESSION.ACTION) to inject comments into query but we have one way to manage context propagator.
I think it would be better to do that in context propagator package.
$span = self::startSpan($spanName, $instrumentation, $class, $function, $filename, $lineno, []); | ||
$mysqli = $obj ? $obj : $params[0]; | ||
self::addTransactionLink($tracker, $span, $mysqli); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious why this prehook was added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is for multi_query
scenario where it works so differently when compared to query
and real_query
.
In order to reflect the db query text attribute for pre-or-post comment injection, I need to move the assignment of DB_QUERY_TEXT from post hook to pre hook. query
and real_query
works in this way.
For multi_query
, the DB_QUERY_TEXT is set at the post hook and also the next_result
post hook. There is no easy way to maintain the same QueryPrehook
for multi_query
. So I added a pre hook.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still not seeing what this added code is doing for multi query, can you explain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments to the function to explain.
In short, multi_query shared the same pre-hook function QueryPreHook
as query and real_query. I need to create a new pre hook to keep multi_query works the same logic as before.
Enable context propagation for database queries by installing the following packages: | ||
```shell | ||
composer require open-telemetry/opentelemetry-context-propagator | ||
composer require open-telemetry/opentelemetry-sqlcommenter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now it would be enabled for both postgresql
or mysql
under PDO, can we add a config to enable only specific driver?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brettmc / @open-telemetry/php-maintainers Do you think it is a good idea to create a config to enable only specific driver?
e.g.
OTEL_PHP_SQLCOMMENTER_OPT_IN_DATABASE
where default value = mysql and valid values are { mysql, postgresql }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For more information, the hardcoding logic https://github.com/jerrytfleung/opentelemetry-php-contrib/blob/service_name_propagator/src/Instrumentation/PDO/src/PDOInstrumentation.php#L135-L137 was approved in #406
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be happy to wait for somebody to ask for it, this is a 0.1
release
plz add a .gitsplit.yaml entry for the new sql commenter package |
was added in Is the PR looking good to merge? |
It is a followup / replacement of #406
Description:
Currently, there isn't any sqlcommenter for the database instrumentation library that allows customers to correlate their span with the database query. This PR adds the implementation for sqlcommenter according to open-telemetry/semantic-conventions#2495
open-telemetry/opentelemetry-sqlcommenter
Testing:
Unit Testing:
Manual Testing:
Once requiring
open-telemetry/opentelemetry-sqlcommenter
, the sqlcommenter feature is enabled.The following extracted the span attributes.
PDO
MySqli
PostgreSql