-
Notifications
You must be signed in to change notification settings - Fork 791
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
MongoDB 4 driver instrumentation #2046
Conversation
Signed-off-by: Sergei Malafeev <sergei@malafeev.org>
Signed-off-by: Sergei Malafeev <sergei@malafeev.org>
Signed-off-by: Sergei Malafeev <sergei@malafeev.org>
pass { | ||
group = "org.mongodb" | ||
module = "mongodb-driver-core" | ||
// this instrumentation is backwards compatible with early versions of the new API that shipped in 3.7 |
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 sure if this complicates matters, but the upcoming 4.2.0 release will allow construction of a legacy com.mongodb.MongoClient
with a com.mongodb.MongoClientSettings
. See mongodb/mongo-java-driver@15b70cf#diff-9edd83ced1b6f12502db95a96af13ed57e647efd84d2ddf5d040af4a653fb1edR211 (you have to expand the MongoClient diffs as they are large)
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
public static void injectTraceListener( | ||
@Advice.This MongoClientSettings.Builder builder, | ||
@Advice.FieldValue("commandListeners") List<CommandListener> commandListeners) { |
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.
We generally prefer to use public API instead of fields to reduce the chance that testLatestDeps will fail when implementation details change :)
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 consistent with all other mongo versions instrumentations, I updated matcher.
.getClass() | ||
.getName() | ||
.startsWith("io.opentelemetry.")) { | ||
// we'll replace it, since it could be the 3.x async driver which is bundled with driver 4 |
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.
So we'd want to filter out calls to the API to add listeners rather than filter here
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.
removed that code
| IllegalAccessException | ||
| InvocationTargetException | ||
| NoSuchMethodException ignored) { | ||
} |
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.
What happens if this is null, is it ok?
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.
no, null is not ok, we will get NPE later. But null shouldn't happen because constructor with boolean exists prior version 4.0. And since 4.0 there is a builder only.
...va/io/opentelemetry/javaagent/instrumentation/mongo/v4/MongoClientInstrumentationModule.java
Outdated
Show resolved
Hide resolved
...va/io/opentelemetry/javaagent/instrumentation/mongo/v4/MongoClientInstrumentationModule.java
Outdated
Show resolved
Hide resolved
if (!commandListeners.isEmpty() | ||
&& commandListeners | ||
.get(commandListeners.size() - 1) | ||
.getClass() | ||
.getName() | ||
.startsWith("io.opentelemetry.")) { | ||
// we'll replace it, since it could be the 3.x async driver which is bundled with driver 4 | ||
commandListeners.remove(commandListeners.size() - 1); | ||
} |
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.
Is the code above needed? I think the code below will prevent double registration?
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.
removed
…elemetry/javaagent/instrumentation/mongo/v4/MongoClientInstrumentationModule.java Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
…elemetry/javaagent/instrumentation/mongo/v4/MongoClientInstrumentationModule.java Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Signed-off-by: Sergei Malafeev <sergei@malafeev.org>
Signed-off-by: Sergei Malafeev <sergei@malafeev.org>
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
public static void injectTraceListener( | ||
@Advice.This MongoClientSettings.Builder builder, | ||
@Advice.FieldValue("commandListeners") List<CommandListener> commandListeners) { |
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.
Thanks for using the public method - for suppression we would want to instrument addCommandListener
instead to avoid accessing this private field. However, we've generally been skipping handling duplicate registration in an effort to come with a more general pattern so you don't have to worry about it either if it's tedious.
Is anything else should be done in this PR? |
@malafeev Do you think you can address #2046 (comment)? We should avoid accessing the private field. I believe you changed to instrumenting |
@anuraaga , no, as I understand, we intercept only
|
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.
@malafeev sorry, was reading the type matcher, not the transformer!
In other agents we aren't really doing any deduping, so we could possibly remove it here too, but I guess if it causes a problem with testLatestDeps we could do so later too.
versions = "[3.7,)" | ||
assertInverse = true |
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 think it would be cleaner to
versions = "[3.7,)" | |
assertInverse = true | |
versions = "[4.0,)" |
@trask @mateuszrzeszutek WDYT?
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.
but before 4.0 non-uber jars have also been published, that's why 3.7 is here
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 don't follow, sorry. If this module is meant for mongo 4.0+, then why do we want to verify muzzle for 3.7?
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 are 2 types of mongo jars:
- uber jar. But it doesn't exist since version 4.0.
- non-uber jar which exists since version 3.7 up to current version.
DD named module to support non-uber jar mongo-4
.
Should I rename this one to mongo-non-uber-3.7
? There is already mongo-3.7
module to support uber jars.
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.
Wait, so actual instrumentations are the same, right? The only difference is, essentially, the collection of packages used for testing? So this is not a new module for instrumentation, but a new module for testing? Like glassfish-testing
?
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.
How does it differ from already existing io.opentelemetry.javaagent.instrumentation.mongo.v3_7.MongoClientInstrumentationModule
? Instrumentation looks the same to me.
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, instrumentation looks the same.
but mongo-3.7 will not work for mongodb-driver-core
3.7 jar because of muzzle.
mongo-3.7
depends on mongo-java-driver
mongo-4.0
depends on mongodb-driver-core
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.
Instead of copying the 3.7 instrumentation, would it be possible to add another muzzle task there and just move the tests to a separate 4.0/uberjar testing module?
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.
Adding
pass {
group = "org.mongodb"
module = "mongodb-driver-core"
// this instrumentation is backwards compatible with early versions of the new API that shipped in 3.7
// the legacy API instrumented in mongo-3.1 continues to be shipped in 4.x, but doesn't conflict here
// because they are triggered by different types: MongoClientSettings(new) vs MongoClientOptions(legacy)
versions = "[3.7,)"
extraDependency "org.mongodb:bson:3.7.0"
assertInverse = true
}
to the 3.7 muzzle task definition should cover all the uberjar releases.
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.
@mateuszrzeszutek done in 5e5ea23
instrumentation/mongo/mongo-4.0/javaagent/mongo-4.0-javaagent.gradle
Outdated
Show resolved
Hide resolved
.../io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientInstrumentationModule.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Sergei Malafeev <sergei@malafeev.org>
Signed-off-by: Sergei Malafeev <sergei@malafeev.org>
Signed-off-by: Sergei Malafeev <sergei@malafeev.org>
Based on https://github.com/DataDog/dd-trace-java/tree/master/dd-java-agent/instrumentation/mongo/driver-4