feat(metrics): add Doctrine DBAL metrics#31
Merged
Conversation
Wraps DBAL connections through a sibling of TraceableMiddleware to emit db.client.operation.duration (Histogram, seconds, semconv Stable) for every query, exec, prepared statement execution and transaction control call. Per-connection context (db.system.name, db.namespace, server.*) is resolved once at connect time. Supports DBAL 3 and DBAL 4. Recording failures are swallowed so a broken meter provider can never replace the original DBAL exception. Introduces Util\ErrorTypeResolver to share the FQCN/anonymous-class fallback used by the metric recorder; the existing inline copy in OpenTelemetryMetricsMiddleware is left untouched and can be migrated in a follow-up cleanup once this lands.
Adds unit tests for DbMetricRecorder, MeteredConnectionDbal4, MeteredStatementDbal4 and MeteredDriver. Verifies attribute extraction (operation/collection), error.type FQCN with anonymous-class fallback, second-based bucket boundaries, transaction control aggregation, and that recording failures never mask DBAL exceptions.
Documents the new metrics.doctrine.enabled flag, lists db.client.operation.duration alongside the existing messaging metrics, and clarifies that no SQL text is recorded — only the leading keyword and an extracted table name when unambiguous.
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Adds MeteredMiddlewareTest, DBAL 3 connection/statement tests (group dbal3, validated by the existing CI matrix), failure-path tests for exec/begin/commit/rollBack on the DBAL 4 connection, dbSystem resolver data provider on MeteredDriver, and BundleBootTest cases for the doctrine metrics wiring.
jstojiljkovic
self-requested a review
May 10, 2026 08:51
jstojiljkovic
approved these changes
May 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Instruments
db.client.operation.duration(Histogram,s) — semconv StableAttributes:
db.system.name,db.namespace,server.address,server.port,db.operation.name(leading SQL keyword),db.collection.name(primary table whenunambiguous),
error.typeon failure.Config
Behaviour
(db.system.name from the driver string, db.namespace from dbname, server address/port from
connection params) once at connect time and binds it to a single DbMetricRecorder shared by
the connection wrapper and its prepared statements.
Statement::execute(), and the transaction control methods
(beginTransaction/commit/rollBack).
both reused from the existing SqlOperationExtractor to keep cardinality bounded.
Notes
fallback, histogram declares second-based buckets, every recording path is wrapped in a
swallowing try/catch so a broken meter provider cannot mask the original DBAL exception.
MeteredConnectionDbal3/MeteredStatementDbal3 pair mirrors the existing
TraceableConnectionDbal3/TraceableStatementDbal3 split and is excluded from PHPStan analysis
the same way (validated via the DBAL 3 CI matrix instead).
merges first lands it on master, the others rebase clean.
aggregation, anonymous-class fallback, bucket boundaries, broken-recorder swallow.