Extract db.namespace from DSN in AttributesFromDSN#608
Extract db.namespace from DSN in AttributesFromDSN#608cyrille-leclerc wants to merge 28 commits intoXSAM:mainfrom
db.namespace from DSN in AttributesFromDSN#608Conversation
093ef23 to
c77428e
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #608 +/- ##
=======================================
+ Coverage 86.4% 86.8% +0.4%
=======================================
Files 16 16
Lines 752 778 +26
=======================================
+ Hits 650 676 +26
Misses 75 75
Partials 27 27 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
c77428e to
e4d5e0e
Compare
db.namespace from DSN in AttributesFromDSNdb.namespace and db.system.name from DSN in AttributesFromDSN
XSAM
left a comment
There was a problem hiding this comment.
@cyrille-leclerc, thanks for raising the PR! I like the idea of adding db.namespace, but several comments need to be addressed.
# Conflicts: # CHANGELOG.md
AttributesFromDSN no longer captures the db.system.name attribute, as callers are better positioned to set it based on the driver in use. The dbSystemFromScheme helper and its scheme map are removed accordingly.
db.namespace and db.system.name from DSN in AttributesFromDSNdb.namespace from DSN in AttributesFromDSN
|
@XSAM I removed the extraction of the |
|
@XSAM I have integrated all your feedback, please review |
There was a problem hiding this comment.
I just realized SQL Server has a different URL schema than other databases. It uses sqlserver://username:password@host/instance?...&database=master.... So the db.namespace from AttributesFromDSN could be an instance name, instead of a db name.
Given how unreliable it could become after adding this new logic to AttributesFromDSN, it might not be worth a breaking change.
Could you move the extraction of db.namespace to a new method DBNamespaceFromDSN returning string, with "" meaning “unknown"? Thank you!
# Conflicts: # CHANGELOG.md
parseDSN now extracts the query string before parsing the path, and handles sqlserver DSNs specifically: the path segment is treated as the instance name (not the database name), and db.namespace is read from the "database" query param instead. Also fixes a bug where a bare "host:port?param=val" DSN (no path) would leave the query string attached to the host, causing net.SplitHostPort to drop the port.
Replace the manual &-split loop with url.ParseQuery, which always returns a non-nil map even on error, making the err check unnecessary.
|
@XSAM the extraction of db.namespace, server.address, and server.port is tightly coupled, as shown in this PR. Would you prefer introducing a dedicated Note that I think the logic to extract the database name is robust. I did extensive research on DSN patterns for Golang |
I think the logic for
For that, we don't need to touch
Oracledb has a similar concept like sqlserver. For instance, an OracleDB string: |
|
Thanks @XSAM , I'll follow your guidance. |
|
I am exploring 2 solutions: this PR and: |
…lexity - Extract parseHostPort() helper so parseDSN cyclomatic complexity drops from 13 to 8 (limit is 10) - Replace the catch-all else branch with an explicit switch: db.namespace is extracted from the URL path only for "postgresql", "postgres", "mysql", and "clickhouse" schemes; "sqlserver"/"mssql" continue to use the ?database= query param; all other schemes and scheme-less DSNs produce no db.namespace - Update test expectations accordingly
- Document supported schemes and bug fixes in [Unreleased] - Add test case for missing closing parenthesis with no path/query string
| } | ||
|
|
||
| // [user[:password]@][protocol([addr])]/dbname[?param1=value1¶mN=valueN] | ||
| // [user[:password]@][protocol([addr])][/path][?param1=value1¶mN=valueN] |
There was a problem hiding this comment.
We see with sqlserver and oracle that the /path is not always the dbname
|
|
||
| func getDummyAttributesGetter() AttributesGetter { | ||
| return func(_ context.Context, method Method, query string, args []driver.NamedValue) []attribute.KeyValue { | ||
| //nolint:prealloc |
There was a problem hiding this comment.
Running locally make command removes //nolint:prealloc and breaks CI so I preferred to fix the root cause.
|
@XSAM I have now 2 PRs showing 2 slightly different user experiences. Would you mind reviewing them? In all cases, we extract Solutions:
|
Summary
I explore 2 solutions to add
db.namespace.In all cases, we extract
db.namespaceonly for well-known DSN patterns to avoid mapping it to incorrect values. Well-known DSN patterns: “postgresql”, “postgres”, “mysql”, “clickhouse”, “sqlserver”, or “mssql”.Solutions:
In this PR,
db.namespaceis parsed in theAttributesFromDSNfunction, no code change for users to benefit of it. The downside is a change of the existing behaviour. Code style remains:In PR Add DBNamespaceFromDSN helper and fix AttributesFromDSN bugs #623, we introduce an additional helper function
DBNamespaceFromDSN, and users have to change their code to benefit of this improvement. New code style looks like:PR Summary
AttributesFromDSNnow extracts the database name for the schemesmysql,postgresql,postgres,clickhouse,sqlserver, andmssql, and sets it as thedb.namespaceattribute (semconv.DBNamespaceKey)AttributesFromDSNwhen the closing protocolparenthesis is missing and the DSN has no path nor query string,
server.portparsing when the DSN has a query string but no path.Fixes:
db.namespacesemconv attribute to DB client spans and metrics #605