|
1 | 1 | package datadog.trace.instrumentation.jdbc;
|
2 | 2 |
|
3 | 3 | import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
|
| 4 | +import static datadog.trace.bootstrap.instrumentation.api.InstrumentationTags.DBM_TRACE_INJECTED; |
| 5 | +import static datadog.trace.bootstrap.instrumentation.api.InstrumentationTags.INSTRUMENTATION_TIME_MS; |
4 | 6 | import static datadog.trace.bootstrap.instrumentation.api.Tags.*;
|
5 | 7 |
|
6 | 8 | import datadog.trace.api.Config;
|
@@ -53,6 +55,8 @@ public class JDBCDecorator extends DatabaseClientDecorator<DBInfo> {
|
53 | 55 | || DBM_PROPAGATION_MODE.equals(DBM_PROPAGATION_MODE_STATIC);
|
54 | 56 | private static final boolean INJECT_TRACE_CONTEXT =
|
55 | 57 | DBM_PROPAGATION_MODE.equals(DBM_PROPAGATION_MODE_FULL);
|
| 58 | + public static final boolean DBM_TRACE_PREPARED_STATEMENTS = |
| 59 | + Config.get().isDBMTracePreparedStatements(); |
56 | 60 |
|
57 | 61 | private volatile boolean warnedAboutDBMPropagationMode = false; // to log a warning only once
|
58 | 62 |
|
@@ -248,6 +252,10 @@ public String traceParent(AgentSpan span, int samplingPriority) {
|
248 | 252 | return sb.toString();
|
249 | 253 | }
|
250 | 254 |
|
| 255 | + public boolean isPostgres(final DBInfo dbInfo) { |
| 256 | + return dbInfo.getType().startsWith("postgres"); |
| 257 | + } |
| 258 | + |
251 | 259 | public boolean isSqlServer(final DBInfo dbInfo) {
|
252 | 260 | return "sqlserver".equals(dbInfo.getType());
|
253 | 261 | }
|
@@ -312,6 +320,44 @@ public long setContextInfo(Connection connection, DBInfo dbInfo) {
|
312 | 320 | return spanID;
|
313 | 321 | }
|
314 | 322 |
|
| 323 | + /** |
| 324 | + * Executes `SET application_name` statement on the Postgres DB to set the trace parent in |
| 325 | + * `pg_stat_activity.application_name`. This is used for prepared statements where it isn't |
| 326 | + * possible to propagate trace parent with the comment. Downside: makes an additional round trip |
| 327 | + * to the database. |
| 328 | + * |
| 329 | + * @param span The span of the instrumented statement |
| 330 | + * @param connection The same connection as the one that will be used for the actual statement |
| 331 | + */ |
| 332 | + public void setApplicationName(AgentSpan span, Connection connection) { |
| 333 | + final long startTime = System.currentTimeMillis(); |
| 334 | + try { |
| 335 | + |
| 336 | + Integer priority = span.forceSamplingDecision(); |
| 337 | + if (priority == null) { |
| 338 | + return; |
| 339 | + } |
| 340 | + final String traceParent = DECORATE.traceParent(span, priority); |
| 341 | + final String traceContext = "_DD_" + traceParent; |
| 342 | + |
| 343 | + connection.setClientInfo("ApplicationName", traceContext); |
| 344 | + } catch (Throwable e) { |
| 345 | + if (log.isDebugEnabled()) { |
| 346 | + log.debug( |
| 347 | + "Failed to set extra DBM data in application_name for trace {}. " |
| 348 | + + "To disable this behavior, set trace_prepared_statements to 'false'. " |
| 349 | + + "See https://docs.datadoghq.com/database_monitoring/connect_dbm_and_apm/ for more info.{}", |
| 350 | + span.getTraceId().toHexString(), |
| 351 | + e); |
| 352 | + } |
| 353 | + DECORATE.onError(span, e); |
| 354 | + } finally { |
| 355 | + span.setTag(DBM_TRACE_INJECTED, true); |
| 356 | + final long elapsed = System.currentTimeMillis() - startTime; |
| 357 | + span.setTag(INSTRUMENTATION_TIME_MS, elapsed); |
| 358 | + } |
| 359 | + } |
| 360 | + |
315 | 361 | @Override
|
316 | 362 | protected void postProcessServiceAndOperationName(
|
317 | 363 | AgentSpan span, DatabaseClientDecorator.NamingEntry namingEntry) {
|
|
0 commit comments