Add R2dbc statement javaagent instrumentation#7977
Conversation
|
|
||
| @Override | ||
| public boolean isHelperClass(String className) { | ||
| return className.startsWith("io.r2dbc.proxy"); |
There was a problem hiding this comment.
The drawback of doing it this way is that when the application also contains the r2dbc-proxy library there may be incompatibilities unless the library bundled in the agent has the same version that the application has.
There was a problem hiding this comment.
Thanks for your feedback.
So the alternative would be to basically reimplement the r2dbc-proxy library in order to get Query Listeners just to not use r2dbx-proxy directly? It just seemed a bit redundant to me, but I get your point.
After @marcingrzejszczak #7977 (comment), should I be simply using the existing ObservationProxyExecutionListener or stick to the manually implemented TraceProxyListener, or even move away entirely from r2dbc-proxy for the auto instrumentation?
There was a problem hiding this comment.
We could shade the r2dbc-proxy library under a different package so it wouldn't conflict with whatever is in the application. I think this isn't super important, we can always fix it later. @marcingrzejszczak is one of the authors of micrometer tracing. As for his suggestion I'm not quite sure what he means. It could be either that he is suggesting to implement some sort of bridge with micrometer api so that their instrumentations could be automatically used or he might be hinting that instead of implementing this instrumentation for opentelemetry you could be using micrometer tracing where this instrumentation already exists.
There was a problem hiding this comment.
Yeah I'm suggesting that since the instrumentation is there providing a bridge would mean you have nothing to do 🤷 Otherwise you can just replicate the same code but use the OTel API.
There was a problem hiding this comment.
We could shade the
r2dbc-proxylibrary under a different package so it wouldn't conflict with whatever is in the application.
We're doing a similar thing in the couchbase instrumentation. @PhilKes you could probably implement it in a somewhat similar manner.
There was a problem hiding this comment.
We could shade the
r2dbc-proxylibrary under a different package so it wouldn't conflict with whatever is in the application.We're doing a similar thing in the couchbase instrumentation. @PhilKes you could probably implement it in a somewhat similar manner.
@mateuszrzeszutek I tried to shade the r2dbc-proxy the same way as in the couchbase instrumentation, but I ran into a problem when running the tests:
R2dbcStatementTest > testQueries(Parameter) > io.opentelemetry.javaagent.instrumentation.r2dbc.v1_0.R2dbcStatementTest.testQueries(Parameter)[8] FAILED
java.util.ServiceConfigurationError: io.r2dbc.spi.ConnectionFactoryProvider: Provider io.r2dbc.proxy.ProxyConnectionFactoryProvider not found
at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:593)
at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1219)
at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)
at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
at io.r2dbc.spi.ConnectionFactories.find(ConnectionFactories.java:108)
at io.opentelemetry.javaagent.instrumentation.r2dbc.v1_0.AbstractR2dbcStatementTest.createProxyConnectionFactory(AbstractR2dbcStatementTest.java:93)
at io.opentelemetry.javaagent.instrumentation.r2dbc.v1_0.R2dbcStatementTest.createProxyConnectionFactory(R2dbcStatementTest.java:44)I dont get why ConnectionFactoryProvider looks for the io.r2dbc.proxy package, the shaded imports work everywhere else and the ServiceLoader should find the ProxyConnectionFactoryProvider in the io.opentelemetry.javaagent.instrumentation.r2dbc.v1_0.shaded.io.r2dbc.proxy package, or is there something wrong with the shaded r2dbc-proxy?
There was a problem hiding this comment.
@PhilKes I think it is better to to rename packages only in the code that gets embedded in the agent and leave the library module unshaded. I created a pr that applies on top of your pr for that Crustack#1
|
BTW you can use Micrometer Observation API that is already there in R2DBC proxy (https://github.com/r2dbc/r2dbc-proxy/tree/main/src/main/java/io/r2dbc/proxy/observation) to have the instrumentation done for you. |
No, you shouldn't worry about keeping it 1:1 with JDBC.
I think both of the |
| ConnectionFactory proxiedFactory = | ||
| ProxyConnectionFactory.builder(originalConnectionFactory) | ||
| .listener(new TraceProxyListener(instrumenterBuilder.build(), connectionFactoryOptions)) | ||
| .build(); |
There was a problem hiding this comment.
I think this part should live in the R2dbcTelemetry class - instead of the getConnectionFactory method there should be a wrapConnectionFactory(ConnectionFactory, ConnectionFactoryOptions) (or similar name) that takes any connection factory and returns a decorated instance. The R2dbcTelemetry class should include any actual connection factory, it should be possible to use R2dbcTelemetry to decorate multiple connection factories - at least that's how we're doing it in all other library instrumentations.
There was a problem hiding this comment.
I moved it into the R2dbcTelemetry as suggested, so that any number of ConnectionFactory can be wrapped.
| .setStatementSanitizationEnabled( | ||
| ConfigPropertiesUtil.getBoolean( | ||
| "otel.instrumentation.common.db-statement-sanitizer.enabled", true)) |
There was a problem hiding this comment.
In general, usually we don't use properties in library instrumentations - instead, we expose a builder method that allows users to configure the setting by themselves. The JDBC library instrumentation is not a good example of that because it utilizes the Driver decorator approach - where it's not possible to have a builder to configure a setting.
See the CassandraTelemetryBuilder for an example.
There was a problem hiding this comment.
I added the the flag as a builder method
|
|
||
| @Override | ||
| public boolean isHelperClass(String className) { | ||
| return className.startsWith("io.r2dbc.proxy"); |
There was a problem hiding this comment.
We could shade the
r2dbc-proxylibrary under a different package so it wouldn't conflict with whatever is in the application.
We're doing a similar thing in the couchbase instrumentation. @PhilKes you could probably implement it in a somewhat similar manner.
|
Hey @PhilKes , can you rebase (or clean merge) your branch with |
…o.ValuesStore instead of Map
b379e2f to
b1009e7
Compare
Sorry for that, I fixed the rebase |
Relocate bundled r2dbc-proxy
|
@PhilKes to get rid of the muzzle failure https://github.com/open-telemetry/opentelemetry-java-instrumentation/actions/runs/4425709289/jobs/7761112434 Try adding |
|
Hello all. Thank you so much for your work on supporting thi! I'm unable to get R2DBC tracing on a Spring Boot application running with the javaagent (using the proxy). Is there any particular configuration that is required for this to work? |
|
hi @juandaco! can you open a new issue? you shouldn't need to make any code changes if you are using the javaagent (e.g. you shouldn't need to use a proxy) and if you can post a minimal repro that is usually the easiest way for folks to understand and help out |


This PR resolves #2515 .
It adds javaagent instrumentation for r2dbc-spi >= v1.0
As suggested by @mp911de in #2515 (comment) I used the r2dbc-proxy
ProxyConnectionFactoryto intercept Database query executions and create according spans.Example span from example project using spring-boot-starter-data-r2dbc Application:
