Skip to content

Commit 92e57d0

Browse files
committed
Add full APM/DBM mode to Oracle
1 parent d7a0014 commit 92e57d0

File tree

4 files changed

+61
-12
lines changed

4 files changed

+61
-12
lines changed

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/jdbc/DBInfo.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ public Builder type(String type) {
9393
this.type = type;
9494
// Those DBs use the full text of the query including the comments as a cache key,
9595
// so we disable full propagation support for them to avoid destroying the cache.
96-
if (type.equals("oracle")) this.fullPropagationSupport = false;
9796
return this;
9897
}
9998

dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,19 @@ public static AgentScope onEnter(@Advice.This final Statement statement) {
8080
connection, InstrumentationContext.get(Connection.class, DBInfo.class));
8181
final boolean injectTraceContext = DECORATE.shouldInjectTraceContext(dbInfo);
8282

83-
if (INJECT_COMMENT && injectTraceContext && DECORATE.isSqlServer(dbInfo)) {
84-
// The span ID is pre-determined so that we can reference it when setting the context
85-
final long spanID = DECORATE.setContextInfo(connection, dbInfo);
86-
// we then force that pre-determined span ID for the span covering the actual query
87-
span = AgentTracer.get().buildSpan(DATABASE_QUERY).withSpanId(spanID).start();
88-
span.setTag(DBM_TRACE_INJECTED, true);
83+
if (INJECT_COMMENT && injectTraceContext) {
84+
if (DECORATE.isSqlServer(dbInfo)) {
85+
// The span ID is pre-determined so that we can reference it when setting the context
86+
final long spanID = DECORATE.setContextInfo(connection, dbInfo);
87+
// we then force that pre-determined span ID for the span covering the actual query
88+
span = AgentTracer.get().buildSpan(DATABASE_QUERY).withSpanId(spanID).start();
89+
span.setTag(DBM_TRACE_INJECTED, true);
90+
} else if (DECORATE.isOracle(dbInfo)) {
91+
span = startSpan(DATABASE_QUERY);
92+
DECORATE.setAction(span, connection);
93+
} else {
94+
span = startSpan(DATABASE_QUERY);
95+
}
8996
} else {
9097
span = startSpan(DATABASE_QUERY);
9198
}

dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ public boolean isSqlServer(final DBInfo dbInfo) {
252252
return "sqlserver".equals(dbInfo.getType());
253253
}
254254

255+
public boolean isOracle(final DBInfo dbInfo) {
256+
return "oracle".equals(dbInfo.getType());
257+
}
258+
255259
/**
256260
* Executes a `SET CONTEXT_INFO` statement on the DB with the active trace ID and the given span
257261
* ID. This context will be "attached" to future queries on the same connection. See <a
@@ -312,6 +316,38 @@ public long setContextInfo(Connection connection, DBInfo dbInfo) {
312316
return spanID;
313317
}
314318

319+
/**
320+
* Executes `connection.setClientInfo("OCSID.ACTION", traceContext)` statement on the Oracle DB to
321+
* set the trace parent in `v$session.action`. This is used because it isn't possible to propagate
322+
* trace parent with the comment.
323+
*
324+
* @param span The span of the instrumented statement
325+
* @param connection The same connection as the one that will be used for the actual statement
326+
*/
327+
public void setAction(AgentSpan span, Connection connection) {
328+
try {
329+
330+
Integer priority = span.forceSamplingDecision();
331+
if (priority == null) {
332+
return;
333+
}
334+
final String traceContext = "_DD_" + DECORATE.traceParent(span, priority);
335+
336+
connection.setClientInfo("OCSID.ACTION", traceContext);
337+
338+
} catch (Throwable e) {
339+
log.debug(
340+
"Failed to set extra DBM data in application_name for trace {}. "
341+
+ "To disable this behavior, set trace_prepared_statements to 'false'. "
342+
+ "See https://docs.datadoghq.com/database_monitoring/connect_dbm_and_apm/ for more info.{}",
343+
span.getTraceId().toHexString(),
344+
e);
345+
DECORATE.onError(span, e);
346+
} finally {
347+
span.setTag("_dd.dbm_trace_injected", true);
348+
}
349+
}
350+
315351
@Override
316352
protected void postProcessServiceAndOperationName(
317353
AgentSpan span, DatabaseClientDecorator.NamingEntry namingEntry) {

dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,18 @@ public static AgentScope onEnter(
8888
final AgentSpan span;
8989
final boolean isSqlServer = DECORATE.isSqlServer(dbInfo);
9090

91-
if (isSqlServer && INJECT_COMMENT && injectTraceContext) {
92-
// The span ID is pre-determined so that we can reference it when setting the context
93-
final long spanID = DECORATE.setContextInfo(connection, dbInfo);
94-
// we then force that pre-determined span ID for the span covering the actual query
95-
span = AgentTracer.get().buildSpan(DATABASE_QUERY).withSpanId(spanID).start();
91+
if (INJECT_COMMENT && injectTraceContext) {
92+
if (isSqlServer) {
93+
// The span ID is pre-determined so that we can reference it when setting the context
94+
final long spanID = DECORATE.setContextInfo(connection, dbInfo);
95+
// we then force that pre-determined span ID for the span covering the actual query
96+
span = AgentTracer.get().buildSpan(DATABASE_QUERY).withSpanId(spanID).start();
97+
} else if (DECORATE.isOracle(dbInfo)) {
98+
span = startSpan(DATABASE_QUERY);
99+
DECORATE.setAction(span, connection);
100+
} else {
101+
span = startSpan(DATABASE_QUERY);
102+
}
96103
} else {
97104
span = startSpan(DATABASE_QUERY);
98105
}

0 commit comments

Comments
 (0)