Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: open-telemetry/opentelemetry-java-instrumentation
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 910493091d63fbb262a8cf16f76b169f34f6687e
Choose a base ref
..
head repository: open-telemetry/opentelemetry-java-instrumentation
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 27f17cdd34808eadb4976424eba09585a957e834
Choose a head ref
Showing with 742 additions and 168 deletions.
  1. +9 −0 ...tion-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java
  2. +53 −0 ...api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/db/DbAttributesExtractor.java
  3. +65 −0 ...n-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/db/DbSpanNameExtractor.java
  4. +63 −0 ...pi/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/db/SqlAttributesExtractor.java
  5. +93 −0 ...src/test/java/io/opentelemetry/instrumentation/api/instrumenter/db/DbAttributesExtractorTest.java
  6. +121 −0 ...i/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/db/DbSpanNameExtractorTest.java
  7. +117 −0 ...rc/test/java/io/opentelemetry/instrumentation/api/instrumenter/db/SqlAttributesExtractorTest.java
  8. +2 −0 instrumentation/jaxws/jaxws-2.0-metro-2.2/javaagent/jaxws-2.0-metro-2.2-javaagent.gradle
  9. +42 −0 ...ation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/DbRequest.java
  10. +49 −0 ...aagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/JdbcAttributesExtractor.java
  11. +37 −0 ...bc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/JdbcInstrumenters.java
  12. +37 −0 ...ent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/JdbcNetAttributesExtractor.java
  13. +0 −151 ...tion/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/JdbcTracer.java
  14. +35 −1 ...ation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/JdbcUtils.java
  15. +8 −8 ...c/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java
  16. +8 −8 ...agent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/StatementInstrumentation.java
  17. +3 −0 instrumentation/jdbc/javaagent/src/test/groovy/JdbcInstrumentationTest.groovy
Original file line number Diff line number Diff line change
@@ -110,6 +110,15 @@ public Instrumenter<REQUEST, RESPONSE> newInstrumenter() {
return newInstrumenter(InstrumenterConstructor.internal(), SpanKindExtractor.alwaysInternal());
}

/**
* Returns a new {@link Instrumenter} which will create spans with kind determined by the passed
* {@code spanKindExtractor} and do no context propagation.
*/
public Instrumenter<REQUEST, RESPONSE> newInstrumenter(
SpanKindExtractor<? super REQUEST> spanKindExtractor) {
return newInstrumenter(InstrumenterConstructor.internal(), spanKindExtractor);
}

private Instrumenter<REQUEST, RESPONSE> newInstrumenter(
InstrumenterConstructor<REQUEST, RESPONSE> constructor,
SpanKindExtractor<? super REQUEST> spanKindExtractor) {
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter.db;

import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* Extractor of <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md">database
* attributes</a>. Instrumentations of database libraries should extend this class, defining {@link
* REQUEST} with the actual request type of the instrumented library. If an attribute is not
* available in this library, it is appropriate to return {@code null} from the protected attribute
* methods, but implement as many as possible for best compliance with the OpenTelemetry
* specification.
*/
public abstract class DbAttributesExtractor<REQUEST> extends AttributesExtractor<REQUEST, Void> {
@Override
protected void onStart(AttributesBuilder attributes, REQUEST request) {
set(attributes, SemanticAttributes.DB_SYSTEM, dbSystem(request));
set(attributes, SemanticAttributes.DB_USER, dbUser(request));
set(attributes, SemanticAttributes.DB_NAME, dbName(request));
set(attributes, SemanticAttributes.DB_CONNECTION_STRING, dbConnectionString(request));
set(attributes, SemanticAttributes.DB_STATEMENT, dbStatement(request));
set(attributes, SemanticAttributes.DB_OPERATION, dbOperation(request));
}

@Override
protected final void onEnd(AttributesBuilder attributes, REQUEST request, Void unused) {}

@Nullable
protected abstract String dbSystem(REQUEST request);

@Nullable
protected abstract String dbUser(REQUEST request);

@Nullable
protected abstract String dbName(REQUEST request);

@Nullable
protected abstract String dbConnectionString(REQUEST request);

@Nullable
protected abstract String dbStatement(REQUEST request);

@Nullable
protected abstract String dbOperation(REQUEST request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter.db;

import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import org.checkerframework.checker.nullness.qual.Nullable;

public final class DbSpanNameExtractor<REQUEST> implements SpanNameExtractor<REQUEST> {
/**
* Returns a {@link SpanNameExtractor} that constructs the span name according to DB semantic
* conventions: {@code <db.operation> <db.name><table>}.
*
* @see DbAttributesExtractor#dbOperation(Object) used to extract {@code <db.operation>}.
* @see DbAttributesExtractor#dbName(Object) used to extract {@code <db.name>}.
* @see SqlAttributesExtractor#dbTable(Object) used to extract {@code <db.table>}.
*/
public static <REQUEST> SpanNameExtractor<REQUEST> create(
DbAttributesExtractor<REQUEST> attributesExtractor) {
return new DbSpanNameExtractor<>(attributesExtractor);
}

private static final String DEFAULT_SPAN_NAME = "DB Query";

private final DbAttributesExtractor<REQUEST> attributesExtractor;

private DbSpanNameExtractor(DbAttributesExtractor<REQUEST> attributesExtractor) {
this.attributesExtractor = attributesExtractor;
}

@Override
public String extract(REQUEST request) {
String operation = attributesExtractor.dbOperation(request);
String dbName = attributesExtractor.dbName(request);
if (operation == null) {
return dbName == null ? DEFAULT_SPAN_NAME : dbName;
}

String table = getTableName(request);
StringBuilder name = new StringBuilder(operation);
if (dbName != null || table != null) {
name.append(' ');
}
if (dbName != null) {
name.append(dbName);
if (table != null) {
name.append('.');
}
}
if (table != null) {
name.append(table);
}
return name.toString();
}

@Nullable
private String getTableName(REQUEST request) {
if (attributesExtractor instanceof SqlAttributesExtractor) {
return ((SqlAttributesExtractor<REQUEST>) attributesExtractor).dbTable(request);
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter.db;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.instrumentation.api.db.SqlStatementInfo;
import io.opentelemetry.instrumentation.api.db.SqlStatementSanitizer;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* Extractor of <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md">database
* attributes</a>. This class is designed with SQL (or SQL-like) database clients in mind. Aside
* from adding the same attributes as {@link DbAttributesExtractor}, it has two more features:
*
* <ul>
* <li>It sanitizes the raw SQL query and removes all parameters;
* <li>It enables adding the table name extracted by the sanitizer as a parameter.
* </ul>
*/
public abstract class SqlAttributesExtractor<REQUEST> extends DbAttributesExtractor<REQUEST> {

@Override
protected final void onStart(AttributesBuilder attributes, REQUEST request) {
super.onStart(attributes, request);
AttributeKey<String> dbTable = dbTableAttribute();
if (dbTable != null) {
set(attributes, dbTable, dbTable(request));
}
}

@Nullable
@Override
protected final String dbStatement(REQUEST request) {
return sanitize(request).getFullStatement();
}

@Nullable
@Override
protected final String dbOperation(REQUEST request) {
return sanitize(request).getOperation();
}

@Nullable
protected final String dbTable(REQUEST request) {
return sanitize(request).getTable();
}

private SqlStatementInfo sanitize(REQUEST request) {
// sanitized statement is cached
return SqlStatementSanitizer.sanitize(rawDbStatement(request));
}

@Nullable
protected abstract AttributeKey<String> dbTableAttribute();

@Nullable
protected abstract String rawDbStatement(REQUEST request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter.db;

import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.entry;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;

class DbAttributesExtractorTest {
DbAttributesExtractor<Map<String, String>> underTest =
new DbAttributesExtractor<Map<String, String>>() {
@Override
protected String dbSystem(Map<String, String> map) {
return map.get("db.system");
}

@Override
protected String dbUser(Map<String, String> map) {
return map.get("db.user");
}

@Override
protected String dbName(Map<String, String> map) {
return map.get("db.name");
}

@Override
protected String dbConnectionString(Map<String, String> map) {
return map.get("db.connection_string");
}

@Override
protected String dbStatement(Map<String, String> map) {
return map.get("db.statement");
}

@Override
protected String dbOperation(Map<String, String> map) {
return map.get("db.operation");
}
};

@Test
void shouldExtractAllAvailableAttributes() {
// given
Map<String, String> request = new HashMap<>();
request.put("db.system", "myDb");
request.put("db.user", "username");
request.put("db.name", "potatoes");
request.put("db.connection_string", "mydb:///potatoes");
request.put("db.statement", "SELECT * FROM potato");
request.put("db.operation", "SELECT");

// when
AttributesBuilder startAttributes = Attributes.builder();
underTest.onStart(startAttributes, request);

AttributesBuilder endAttributes = Attributes.builder();
underTest.onEnd(endAttributes, request, null);

// then
assertThat(startAttributes.build())
.containsOnly(
entry(SemanticAttributes.DB_SYSTEM, "myDb"),
entry(SemanticAttributes.DB_USER, "username"),
entry(SemanticAttributes.DB_NAME, "potatoes"),
entry(SemanticAttributes.DB_CONNECTION_STRING, "mydb:///potatoes"),
entry(SemanticAttributes.DB_STATEMENT, "SELECT * FROM potato"),
entry(SemanticAttributes.DB_OPERATION, "SELECT"));

assertThat(endAttributes.build().isEmpty()).isTrue();
}

@Test
void shouldExtractNoAttributesIfNoneAreAvailable() {
// when
AttributesBuilder attributes = Attributes.builder();
underTest.onStart(attributes, Collections.emptyMap());

// then
assertThat(attributes.build().isEmpty()).isTrue();
}
}
Loading