-
Notifications
You must be signed in to change notification settings - Fork 324
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
Report affected rows for DML statements #883
Report affected rows for DML statements #883
Conversation
Codecov Report
@@ Coverage Diff @@
## master #883 +/- ##
============================================
- Coverage 65.13% 64.71% -0.42%
Complexity 85 85
============================================
Files 232 231 -1
Lines 9878 9662 -216
Branches 1326 1282 -44
============================================
- Hits 6434 6253 -181
+ Misses 3050 3025 -25
+ Partials 394 384 -10
Continue to review full report at Codecov.
|
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.
Looks good overall. Some minor comments. Also, please format the code you added.
for (int i = 0; i < array.length; i++) { | ||
affectedCount += array[i]; | ||
} | ||
} |
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.
Extract public static method, annotate with @VisibleForAdvice
and reuse in ExecuteWithoutQueryInstrumentation
. As only Java core types are used, there are no classloader issues.
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 get that- those APIs return either int
or long
, not arrays...
When fixing, you will need to create two separate advices.
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.
should be fixed now
@Advice.Thrown @Nullable Throwable t) throws SQLException { | ||
if (span != null) { | ||
if( t == null){ | ||
span.getContext().getDb().withAffectedRowsCount(statement.getUpdateCount()); |
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.
The javadoc for getUpdateCount
says: "This method should be called only once per result". I believe this means we cannot call it here.
Db db = reporter.getFirstSpan().getContext().getDb(); | ||
assertThat(db.getStatement()).isEqualTo(insert); | ||
assertThat(db.getAffectedRowsCount()) | ||
.isEqualTo(statement.getUpdateCount()) |
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.
Hmm, it seems all drivers DO support multiple invocations of getUpdateCount
despite the javadoc. Still not sure if it is safe enough to use it...
for (int i = 0; i < array.length; i++) { | ||
affectedCount += array[i]; | ||
} | ||
} |
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 get that- those APIs return either int
or long
, not arrays...
When fixing, you will need to create two separate advices.
...apm-jdbc-plugin/src/test/java/co/elastic/apm/agent/jdbc/AbstractJdbcInstrumentationTest.java
Show resolved
Hide resolved
Also - this new value should be serialized into DB span events as part of the implementation of elastic/apm#112 |
Adding a label for each datasource provider makes it easier to know which datasource connection pool is being tested
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.
Awesome!! Well done!
Only not 100% about invoking getUpdateCount()
in the instrumentation...
Otherwise LGTM, so approving and leave that to you.
|
||
long expectedAffected = 2; | ||
if (isKnownDatabase("MySQL", "10.")) { | ||
// for an unknown reason mariadb 10 has unexpected but somehow consistent behavior 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.
The javadoc says:
* <LI>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the command was
* processed successfully but that the number of rows affected is
* unknown
where the constant java.sql.Statement#SUCCESS_NO_INFO
is -2.
span.getContext() | ||
.getDb() | ||
// getUpdateCount javadoc indicates that this method should be called only once | ||
// however in practice adding this extra call seem to not have noticeable side effects |
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 am still not sure about that. On the one hand, the testMultipleRowsModifiedStatement
passes, so should be OK for at least most of the cases. On the other hand, breaking the application in the other rare cases is embarrassing...
@felixbarny WDYT? Does the added value of this field worth the risk?
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 have found this SO post which seems relevant: https://stackoverflow.com/questions/9984468/getresultset-should-be-called-only-once-per-result
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, with ResulstSets that hold open cursors, concurrent usages can be very unpleasant. It would even make sense to enforce not allowing multiple invocations of this API.
However, the update count can be easily cached and I assume that's what most drivers do, so not sure why it has the same limitation.
Fixes #707
Reports the number of rows affected by a DML statement (INSERT,DELETE,UPDATE) in database span.
Checklist
Update documentationUpdate supported-technologies.asciidocAdded an API method or config option? Document in which version this will be introduced.