-
Notifications
You must be signed in to change notification settings - Fork 1k
Added instrumentation for transaction commit/rollback in jdbc #13709
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
Changes from 3 commits
83795a3
140583e
54fee2e
fb74aa2
fb22764
2de16b2
12b544b
510c1b0
ac5ea54
114ccac
1336ab2
5a4a0d2
7bccecd
a928021
542f4b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| # Settings for the JDBC instrumentation | ||
|
|
||
| | System property | Type | Default | Description | | ||
| |---------------------------------------------------------|---------|---------|----------------------------------------| | ||
| | `otel.instrumentation.jdbc.statement-sanitizer.enabled` | Boolean | `true` | Enables the DB statement sanitization. | | ||
| | System property | Type | Default | Description | | ||
| |---------------------------------------------------------|---------|---------|-------------------------------------------------------| | ||
| | `otel.instrumentation.jdbc.statement-sanitizer.enabled` | Boolean | `true` | Enables the DB statement sanitization. | | ||
| | `otel.instrumentation.jdbc.experimental.txn.enabled` | Boolean | `false` | Enables the experimental transaction instrumentation. | | ||
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |
| import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; | ||
| import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION_BATCH_SIZE; | ||
| import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION_NAME; | ||
| import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_QUERY_TEXT; | ||
| import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SQL_TABLE; | ||
| import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; | ||
| import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; | ||
|
|
@@ -1632,4 +1633,152 @@ void testPreparedBatch(String system, Connection connection, String username, St | |
| DB_OPERATION_BATCH_SIZE, | ||
| emitStableDatabaseSemconv() ? 2L : null)))); | ||
| } | ||
|
|
||
| @ParameterizedTest | ||
| @MethodSource("transactionOperationsStream") | ||
| void testCommitTransaction(String system, Connection connection, String username, String url) | ||
| throws SQLException { | ||
|
|
||
| String tableName = "TXN_COMMIT_TEST_" + system.toUpperCase(Locale.ROOT); | ||
| Statement createTable = connection.createStatement(); | ||
| createTable.execute("CREATE TABLE " + tableName + " (id INTEGER not NULL, PRIMARY KEY ( id ))"); | ||
| cleanup.deferCleanup(createTable); | ||
|
|
||
| boolean originalAutoCommit = connection.getAutoCommit(); | ||
| connection.setAutoCommit(false); | ||
|
|
||
| testing.waitForTraces(1); | ||
| testing.clearData(); | ||
|
|
||
| try { | ||
| Statement insertStatement = connection.createStatement(); | ||
| cleanup.deferCleanup(insertStatement); | ||
|
|
||
| testing.runWithSpan( | ||
| "parent", | ||
| () -> { | ||
| insertStatement.executeUpdate("INSERT INTO " + tableName + " VALUES(1)"); | ||
| connection.commit(); | ||
| }); | ||
|
|
||
| testing.waitAndAssertTraces( | ||
| trace -> | ||
| trace.hasSpansSatisfyingExactly( | ||
| span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), | ||
| span -> | ||
| span.hasName("INSERT jdbcunittest." + tableName) | ||
| .hasKind(SpanKind.CLIENT) | ||
| .hasParent(trace.getSpan(0)) | ||
| .hasAttributesSatisfyingExactly( | ||
| equalTo(maybeStable(DB_SYSTEM), maybeStableDbSystemName(system)), | ||
| equalTo(maybeStable(DB_NAME), dbNameLower), | ||
| equalTo(DB_USER, emitStableDatabaseSemconv() ? null : username), | ||
| equalTo( | ||
| DB_CONNECTION_STRING, emitStableDatabaseSemconv() ? null : url), | ||
| equalTo( | ||
| maybeStable(DB_STATEMENT), | ||
| "INSERT INTO " + tableName + " VALUES(?)"), | ||
| equalTo(maybeStable(DB_OPERATION), "INSERT"), | ||
| equalTo(maybeStable(DB_SQL_TABLE), tableName)), | ||
| span -> | ||
| span.hasName("COMMIT " + dbNameLower) | ||
| .hasKind(SpanKind.CLIENT) | ||
| .hasParent(trace.getSpan(0)) | ||
| .hasAttributesSatisfyingExactly( | ||
| equalTo(maybeStable(DB_SYSTEM), maybeStableDbSystemName(system)), | ||
| equalTo(maybeStable(DB_NAME), dbNameLower), | ||
| equalTo(DB_USER, emitStableDatabaseSemconv() ? null : username), | ||
| equalTo(DB_STATEMENT, emitStableDatabaseSemconv() ? null : "COMMIT"), | ||
| equalTo(DB_QUERY_TEXT, emitStableDatabaseSemconv() ? "COMMIT" : null), | ||
|
||
| equalTo( | ||
| DB_CONNECTION_STRING, emitStableDatabaseSemconv() ? null : url), | ||
| equalTo(maybeStable(DB_OPERATION), "COMMIT")))); | ||
| } finally { | ||
| connection.setAutoCommit(originalAutoCommit); | ||
stillya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
| @ParameterizedTest | ||
| @MethodSource("transactionOperationsStream") | ||
| void testRollbackTransaction(String system, Connection connection, String username, String url) | ||
| throws SQLException { | ||
|
|
||
| String tableName = "TXN_ROLLBACK_TEST_" + system.toUpperCase(Locale.ROOT); | ||
| Statement createTable = connection.createStatement(); | ||
| createTable.execute("CREATE TABLE " + tableName + " (id INTEGER not NULL, PRIMARY KEY ( id ))"); | ||
| cleanup.deferCleanup(createTable); | ||
|
|
||
| boolean originalAutoCommit = connection.getAutoCommit(); | ||
| connection.setAutoCommit(false); | ||
|
|
||
| testing.waitForTraces(1); | ||
| testing.clearData(); | ||
|
|
||
| try { | ||
| Statement insertStatement = connection.createStatement(); | ||
| cleanup.deferCleanup(insertStatement); | ||
|
|
||
| testing.runWithSpan( | ||
| "parent", | ||
| () -> { | ||
| insertStatement.executeUpdate("INSERT INTO " + tableName + " VALUES(1)"); | ||
| connection.rollback(); | ||
| }); | ||
|
|
||
| testing.waitAndAssertTraces( | ||
| trace -> | ||
| trace.hasSpansSatisfyingExactly( | ||
| span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), | ||
| span -> | ||
| span.hasName("INSERT jdbcunittest." + tableName) | ||
| .hasKind(SpanKind.CLIENT) | ||
| .hasParent(trace.getSpan(0)) | ||
| .hasAttributesSatisfyingExactly( | ||
| equalTo(maybeStable(DB_SYSTEM), maybeStableDbSystemName(system)), | ||
| equalTo(maybeStable(DB_NAME), dbNameLower), | ||
| equalTo(DB_USER, emitStableDatabaseSemconv() ? null : username), | ||
| equalTo( | ||
| DB_CONNECTION_STRING, emitStableDatabaseSemconv() ? null : url), | ||
| equalTo( | ||
| maybeStable(DB_STATEMENT), | ||
| "INSERT INTO " + tableName + " VALUES(?)"), | ||
| equalTo(maybeStable(DB_OPERATION), "INSERT"), | ||
| equalTo(maybeStable(DB_SQL_TABLE), tableName)), | ||
| span -> | ||
| span.hasName("ROLLBACK " + dbNameLower) | ||
| .hasKind(SpanKind.CLIENT) | ||
| .hasParent(trace.getSpan(0)) | ||
| .hasAttributesSatisfyingExactly( | ||
| equalTo(maybeStable(DB_SYSTEM), maybeStableDbSystemName(system)), | ||
| equalTo(maybeStable(DB_NAME), dbNameLower), | ||
| equalTo(DB_USER, emitStableDatabaseSemconv() ? null : username), | ||
| equalTo( | ||
| DB_STATEMENT, emitStableDatabaseSemconv() ? null : "ROLLBACK"), | ||
| equalTo( | ||
| DB_QUERY_TEXT, emitStableDatabaseSemconv() ? "ROLLBACK" : null), | ||
| equalTo( | ||
| DB_CONNECTION_STRING, emitStableDatabaseSemconv() ? null : url), | ||
| equalTo(maybeStable(DB_OPERATION), "ROLLBACK")))); | ||
|
|
||
| Statement selectStatement = connection.createStatement(); | ||
| cleanup.deferCleanup(selectStatement); | ||
| ResultSet resultSet = selectStatement.executeQuery("SELECT COUNT(*) FROM " + tableName); | ||
| resultSet.next(); | ||
| assertThat(resultSet.getInt(1)).isEqualTo(0); | ||
|
||
| } finally { | ||
| connection.setAutoCommit(originalAutoCommit); | ||
| } | ||
| } | ||
|
|
||
| static Stream<Arguments> transactionOperationsStream() throws SQLException { | ||
| return Stream.of( | ||
| Arguments.of("h2", new org.h2.Driver().connect(jdbcUrls.get("h2"), null), null, "h2:mem:"), | ||
| Arguments.of( | ||
| "derby", | ||
| new EmbeddedDriver().connect(jdbcUrls.get("derby"), null), | ||
| "APP", | ||
| "derby:memory:"), | ||
| Arguments.of( | ||
| "hsqldb", new JDBCDriver().connect(jdbcUrls.get("hsqldb"), null), "SA", "hsqldb:mem:")); | ||
| } | ||
| } | ||
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.
might as well test some of
xa commithttps://dev.mysql.com/doc/refman/8.4/en/xa-statements.htmlcommit workhttps://www.ibm.com/docs/en/informix-servers/14.10.0?topic=statements-commit-work-statementcommit tranhttps://learn.microsoft.com/en-us/sql/t-sql/language-elements/commit-transaction-transact-sql?view=sql-server-ver16commit preparedhttps://www.postgresql.org/docs/current/sql-commit-prepared.htmlThere 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 dropped it - commit/rollback isn't part of the SQL statement parsing anymore.