parse db name from JDBC string#2642
Conversation
| .withConnectionInstance(safeGetCatalog(connection)) | ||
| .withConnectionUser(metaData.getUserName()) |
There was a problem hiding this comment.
[for reviewer] this makes the db name from parsed URL having higher priority that the runtime value returned by getCatalog().
| testUrl("jdbc:h2:file:/data/sample", "h2", "localhost", -1); | ||
| testUrl("jdbc:h2:mem:", "h2", "localhost", -1); | ||
| testUrl("jdbc:h2:mem:test_mem", "h2", "localhost", -1); | ||
| testUrl("jdbc:h2:tcp://localhost/mem:test", "h2", "localhost", -1); |
There was a problem hiding this comment.
[for reviewer] using localhost here for testing is a bad idea as localhost will be the default value when unable to properly parse the url.
...ugins/apm-jdbc-plugin/src/main/java/co/elastic/apm/agent/jdbc/helper/ConnectionMetaData.java
Show resolved
Hide resolved
|
/test |
...s/apm-jdbc-plugin/src/test/java/co/elastic/apm/agent/jdbc/helper/ConnectionMetaDataTest.java
Show resolved
Hide resolved
...s/apm-jdbc-plugin/src/test/java/co/elastic/apm/agent/jdbc/helper/ConnectionMetaDataTest.java
Show resolved
Hide resolved
...ugins/apm-jdbc-plugin/src/main/java/co/elastic/apm/agent/jdbc/helper/ConnectionMetaData.java
Outdated
Show resolved
Hide resolved
jackshirazi
left a comment
There was a problem hiding this comment.
Wow that parsing looks like it was painful to implement! Well done
@SylvainJuge Wanted to understand for a use case of observability which relies on a similar approach as far as I could think of. |
|
The database name that is being captured is the one we get from the application perspective, so if the underlying database or the network alias (for example in docker) is identical we don't have any way to distinguish from the application side where the agent is running. Using an opentelemetry-based agent like https://github.com/elastic/elastic-otel-java/ can help to capture more attributes on the span, however the default mapping you will see in the map and the dependencies in APM are likely to remain the same. What you could do however is combining extra otel attributes with an ingest pipeline, or even an intermediate otel collector/processor to transform the captured data. For example, you could compute a dedicated value for |
|
@SylvainJuge Thank you for the response. Please illustrate from the application perspective. In my case, both driver URL have different IPs, but the same database name. Is that not a primary consideration when identifying a cluster? and |
|
In this case the URL is different and should have a distinct network host, as we can see in the unit tests that relate to this JDBC url parsing here : https://github.com/elastic/apm-agent-java/blob/main/apm-agent-plugins/apm-jdbc-plugin/src/test/java/co/elastic/apm/agent/jdbc/helper/ConnectionMetaDataTest.java However, the host part is not used when building the map and the dependencies, only the database name, hence what you see on the UI side. What I am suggesting here is that maybe using an opentelemetry agent can help here as it would capture similar attributes (which are defined in otel semantic conventions), and because otel makes it quite easy to modify the data through a custom collector/processor then you could easily transform the attribute that currently contains the database name to include the host. As an alternative without switching to OTel, using ingest-pipelines with APM could also be done, but this is trickier to implement as you will have to modify the traces and the metrics for this to work properly, so I would recommend trying it with OTel first. |
|
@SylvainJuge Thank you again for your response. Though OTel doesn't seem straightforward for me to try out as this might need integration changes across applications, I would try out the route via ingest-pipeline. |
What does this PR do?
Fixes #1841
This would be a "potentially breaking change" as the granularity for dependencies will be higher and include the database name, the
span.destination.service.resourceincludes the database name when it is part of the JDBC connection string.On the implementation side, there are quite a few variants to parse and because the information we collect is not always captured together (for example host name and port), it's more convenient to have a builder.
Checklist
Added an API method or config option? Document in which version this will be introducedI have made corresponding changes to the documentationThings to clarify during review
SIDare case-sensitive (related stackoverflow post).Things to discuss for follow-up issues / PRs.
::1[::1]java.sql.DriverManager#getConnection(java.lang.String, java.util.Properties): not discussed, but let's implement this only if required later.