dd-trace 5.97.0 → 5.99.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/LICENSE-3rdparty.csv +0 -1
  2. package/ext/tags.js +1 -0
  3. package/index.d.ts +35 -3
  4. package/package.json +48 -46
  5. package/packages/datadog-instrumentations/src/crypto.js +45 -0
  6. package/packages/datadog-instrumentations/src/cucumber.js +65 -3
  7. package/packages/datadog-instrumentations/src/cypress-config.js +153 -53
  8. package/packages/datadog-instrumentations/src/dns.js +24 -56
  9. package/packages/datadog-instrumentations/src/graphql.js +1 -1
  10. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +74 -0
  11. package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +4 -1
  12. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  13. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +10 -3
  14. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
  15. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/modelcontextprotocol-sdk.js +59 -0
  16. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +11 -2
  17. package/packages/datadog-instrumentations/src/jest.js +104 -12
  18. package/packages/datadog-instrumentations/src/mocha/utils.js +8 -0
  19. package/packages/datadog-instrumentations/src/modelcontextprotocol-sdk.js +7 -0
  20. package/packages/datadog-instrumentations/src/pino.js +4 -28
  21. package/packages/datadog-instrumentations/src/playwright-browser-scripts.js +27 -0
  22. package/packages/datadog-instrumentations/src/playwright.js +5 -17
  23. package/packages/datadog-instrumentations/src/redis.js +12 -6
  24. package/packages/datadog-instrumentations/src/stripe.js +38 -24
  25. package/packages/datadog-instrumentations/src/vitest.js +32 -4
  26. package/packages/datadog-instrumentations/src/zlib.js +29 -0
  27. package/packages/datadog-plugin-aws-sdk/src/base.js +2 -3
  28. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -0
  29. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
  30. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
  31. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -0
  32. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -0
  33. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
  34. package/packages/datadog-plugin-azure-event-hubs/src/producer.js +8 -15
  35. package/packages/datadog-plugin-azure-service-bus/src/producer.js +4 -9
  36. package/packages/datadog-plugin-cucumber/src/index.js +8 -2
  37. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +114 -6
  38. package/packages/datadog-plugin-cypress/src/index.js +59 -2
  39. package/packages/datadog-plugin-cypress/src/source-map-utils.js +48 -1
  40. package/packages/datadog-plugin-fs/src/index.js +1 -1
  41. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -1
  42. package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +2 -7
  43. package/packages/datadog-plugin-http/src/client.js +1 -1
  44. package/packages/datadog-plugin-http/src/server.js +21 -13
  45. package/packages/datadog-plugin-http2/src/client.js +1 -1
  46. package/packages/datadog-plugin-http2/src/server.js +10 -2
  47. package/packages/datadog-plugin-jest/src/index.js +2 -2
  48. package/packages/datadog-plugin-mocha/src/index.js +1 -2
  49. package/packages/datadog-plugin-modelcontextprotocol-sdk/src/index.js +24 -0
  50. package/packages/datadog-plugin-modelcontextprotocol-sdk/src/tracing.js +55 -0
  51. package/packages/datadog-plugin-mongodb-core/src/index.js +4 -9
  52. package/packages/datadog-plugin-mysql/src/index.js +1 -1
  53. package/packages/datadog-plugin-next/src/index.js +8 -2
  54. package/packages/datadog-plugin-pg/src/index.js +1 -1
  55. package/packages/datadog-plugin-playwright/src/index.js +2 -3
  56. package/packages/datadog-plugin-tedious/src/index.js +1 -1
  57. package/packages/datadog-plugin-vitest/src/index.js +14 -6
  58. package/packages/datadog-plugin-ws/src/close.js +3 -1
  59. package/packages/datadog-plugin-ws/src/producer.js +2 -0
  60. package/packages/datadog-plugin-ws/src/receiver.js +2 -1
  61. package/packages/dd-trace/src/aiguard/channels.js +8 -0
  62. package/packages/dd-trace/src/aiguard/index.js +7 -3
  63. package/packages/dd-trace/src/aiguard/sdk.js +66 -22
  64. package/packages/dd-trace/src/aiguard/tags.js +1 -0
  65. package/packages/dd-trace/src/appsec/blocked_templates.js +4 -3
  66. package/packages/dd-trace/src/appsec/blocking.js +62 -34
  67. package/packages/dd-trace/src/appsec/graphql.js +6 -6
  68. package/packages/dd-trace/src/appsec/index.js +9 -11
  69. package/packages/dd-trace/src/appsec/rasp/command_injection.js +4 -5
  70. package/packages/dd-trace/src/appsec/rasp/lfi.js +8 -4
  71. package/packages/dd-trace/src/appsec/rasp/sql_injection.js +5 -10
  72. package/packages/dd-trace/src/appsec/rasp/ssrf.js +5 -6
  73. package/packages/dd-trace/src/appsec/recommended.json +2438 -13
  74. package/packages/dd-trace/src/appsec/reporter.js +6 -5
  75. package/packages/dd-trace/src/appsec/sdk/set_user.js +1 -1
  76. package/packages/dd-trace/src/appsec/sdk/track_event.js +5 -5
  77. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +6 -10
  78. package/packages/dd-trace/src/appsec/sdk/utils.js +4 -2
  79. package/packages/dd-trace/src/appsec/store.js +50 -0
  80. package/packages/dd-trace/src/appsec/waf/index.js +3 -5
  81. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
  82. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
  83. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -2
  84. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
  85. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -4
  86. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
  87. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -5
  88. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +3 -4
  89. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +6 -6
  90. package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +2 -2
  91. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
  92. package/packages/dd-trace/src/config/config-types.d.ts +0 -4
  93. package/packages/dd-trace/src/config/defaults.js +10 -11
  94. package/packages/dd-trace/src/config/generated-config-types.d.ts +14 -8
  95. package/packages/dd-trace/src/config/index.js +49 -32
  96. package/packages/dd-trace/src/config/parsers.js +26 -9
  97. package/packages/dd-trace/src/config/supported-configurations.json +86 -33
  98. package/packages/dd-trace/src/constants.js +1 -0
  99. package/packages/dd-trace/src/debugger/config.js +2 -0
  100. package/packages/dd-trace/src/debugger/devtools_client/send.js +25 -5
  101. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +5 -2
  102. package/packages/dd-trace/src/encode/0.4.js +11 -11
  103. package/packages/dd-trace/src/encode/span-stats.js +4 -1
  104. package/packages/dd-trace/src/exporters/agent/index.js +0 -1
  105. package/packages/dd-trace/src/exporters/agent/writer.js +1 -2
  106. package/packages/dd-trace/src/exporters/agentless/writer.js +3 -3
  107. package/packages/dd-trace/src/exporters/common/util.js +2 -2
  108. package/packages/dd-trace/src/id.js +2 -0
  109. package/packages/dd-trace/src/index.js +2 -5
  110. package/packages/dd-trace/src/lambda/handler.js +1 -3
  111. package/packages/dd-trace/src/llmobs/plugins/{anthropic.js → anthropic/index.js} +5 -63
  112. package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +106 -0
  113. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +3 -2
  114. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -2
  115. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +2 -1
  116. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +0 -49
  117. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +2 -1
  118. package/packages/dd-trace/src/llmobs/plugins/langchain/messages.js +76 -0
  119. package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -26
  120. package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/index.js +68 -0
  121. package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +57 -0
  122. package/packages/dd-trace/src/llmobs/sdk.js +2 -2
  123. package/packages/dd-trace/src/log/index.js +0 -10
  124. package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +103 -0
  125. package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -0
  126. package/packages/dd-trace/src/openfeature/remote_config.js +6 -1
  127. package/packages/dd-trace/src/opentelemetry/context_manager.js +6 -4
  128. package/packages/dd-trace/src/opentelemetry/logs/index.js +1 -1
  129. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +3 -2
  130. package/packages/dd-trace/src/opentelemetry/metrics/index.js +1 -1
  131. package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +3 -2
  132. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +19 -51
  133. package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +14 -2
  134. package/packages/dd-trace/src/opentelemetry/otlp/trace.proto +358 -0
  135. package/packages/dd-trace/src/opentelemetry/otlp/trace_service.proto +78 -0
  136. package/packages/dd-trace/src/opentelemetry/trace/index.js +70 -0
  137. package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +74 -0
  138. package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +342 -0
  139. package/packages/dd-trace/src/opentelemetry/tracer.js +9 -11
  140. package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -10
  141. package/packages/dd-trace/src/opentracing/span.js +1 -1
  142. package/packages/dd-trace/src/opentracing/tracer.js +17 -5
  143. package/packages/dd-trace/src/plugins/index.js +1 -0
  144. package/packages/dd-trace/src/plugins/log_plugin.js +3 -0
  145. package/packages/dd-trace/src/plugins/plugin.js +6 -11
  146. package/packages/dd-trace/src/plugins/storage.js +2 -2
  147. package/packages/dd-trace/src/plugins/tracing.js +22 -5
  148. package/packages/dd-trace/src/plugins/util/test.js +128 -5
  149. package/packages/dd-trace/src/plugins/util/url.js +2 -1
  150. package/packages/dd-trace/src/plugins/util/web.js +6 -88
  151. package/packages/dd-trace/src/profiling/profiler.js +34 -77
  152. package/packages/dd-trace/src/profiling/profilers/event_plugins/crypto.js +32 -0
  153. package/packages/dd-trace/src/profiling/profilers/event_plugins/zlib.js +19 -0
  154. package/packages/dd-trace/src/profiling/profilers/events.js +35 -0
  155. package/packages/dd-trace/src/proxy.js +3 -4
  156. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +17 -13
  157. package/packages/dd-trace/src/service-naming/index.js +1 -1
  158. package/packages/dd-trace/src/service-naming/schemas/definition.js +4 -1
  159. package/packages/dd-trace/src/service-naming/schemas/util.js +15 -1
  160. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +24 -1
  161. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +60 -0
  162. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +21 -1
  163. package/packages/dd-trace/src/service-naming/schemas/v0/websocket.js +5 -0
  164. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +17 -0
  165. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +15 -1
  166. package/packages/dd-trace/src/service-naming/schemas/v1/websocket.js +6 -0
  167. package/packages/dd-trace/src/span_processor.js +1 -2
  168. package/packages/dd-trace/src/span_stats.js +5 -1
  169. package/packages/dd-trace/src/tagger.js +2 -2
  170. package/packages/dd-trace/src/telemetry/send-data.js +5 -7
  171. package/vendor/dist/@apm-js-collab/code-transformer/index.js +28 -6
  172. package/vendor/dist/protobufjs/index.js +1 -1
  173. package/packages/dd-trace/src/log/utils.js +0 -16
  174. package/vendor/dist/ignore/LICENSE +0 -21
  175. package/vendor/dist/ignore/index.js +0 -1
@@ -78,7 +78,7 @@ export interface GeneratedConfig {
78
78
  DD_AZURE_RESOURCE_GROUP: string | undefined;
79
79
  DD_CIVISIBILITY_AGENTLESS_ENABLED: boolean;
80
80
  DD_CIVISIBILITY_AGENTLESS_URL: string | undefined;
81
- DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER: boolean;
81
+ DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER: string | undefined;
82
82
  DD_CIVISIBILITY_DANGEROUSLY_FORCE_COVERAGE: boolean;
83
83
  DD_CIVISIBILITY_DANGEROUSLY_FORCE_TEST_SKIPPING: boolean;
84
84
  DD_CIVISIBILITY_ENABLED: boolean;
@@ -297,6 +297,7 @@ export interface GeneratedConfig {
297
297
  DD_TRACE_MIDDIE_ENABLED: boolean;
298
298
  DD_TRACE_MOCHA_EACH_ENABLED: boolean;
299
299
  DD_TRACE_MOCHA_ENABLED: boolean;
300
+ DD_TRACE_MODELCONTEXTPROTOCOL_SDK_ENABLED: boolean;
300
301
  DD_TRACE_MOLECULER_ENABLED: boolean;
301
302
  DD_TRACE_MONGODB_CORE_ENABLED: boolean;
302
303
  DD_TRACE_MONGODB_ENABLED: boolean;
@@ -478,30 +479,34 @@ export interface GeneratedConfig {
478
479
  };
479
480
  openAiLogsEnabled: boolean;
480
481
  OTEL_EXPORTER_OTLP_ENDPOINT: string | undefined;
482
+ OTEL_EXPORTER_OTLP_HEADERS: Record<string, string> | undefined;
483
+ OTEL_EXPORTER_OTLP_LOGS_HEADERS: Record<string, string> | undefined;
484
+ OTEL_EXPORTER_OTLP_METRICS_HEADERS: Record<string, string> | undefined;
485
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: string;
486
+ OTEL_EXPORTER_OTLP_TRACES_HEADERS: Record<string, string> | undefined;
487
+ OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: "http/json";
488
+ OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: number;
481
489
  OTEL_LOGS_EXPORTER: "none" | "otlp" | undefined;
482
490
  OTEL_METRICS_EXPORTER: "none" | "otlp" | undefined;
483
491
  OTEL_RESOURCE_ATTRIBUTES: Record<string, string>;
484
492
  OTEL_SDK_DISABLED: boolean;
485
- OTEL_TRACES_EXPORTER: "none" | "otlp";
493
+ OTEL_TRACES_EXPORTER: "none" | "otlp" | undefined;
486
494
  OTEL_TRACES_SAMPLER: "always_on" | "always_off" | "traceidratio" | "parentbased_always_on" | "parentbased_always_off" | "parentbased_traceidratio";
487
495
  OTEL_TRACES_SAMPLER_ARG: number | undefined;
488
496
  otelBatchTimeout: number;
489
- otelHeaders: string | undefined;
490
497
  otelLogsEnabled: boolean;
491
- otelLogsHeaders: string | undefined;
492
498
  otelLogsProtocol: string;
493
499
  otelLogsTimeout: number;
494
- otelLogsUrl: string | undefined;
500
+ otelLogsUrl: string;
495
501
  otelMaxExportBatchSize: number;
496
502
  otelMaxQueueSize: number;
497
503
  otelMetricsEnabled: boolean;
498
504
  otelMetricsExportInterval: number;
499
505
  otelMetricsExportTimeout: number;
500
- otelMetricsHeaders: string | undefined;
501
506
  otelMetricsProtocol: string;
502
507
  otelMetricsTemporalityPreference: "DELTA" | "CUMULATIVE" | "LOWMEMORY";
503
508
  otelMetricsTimeout: number;
504
- otelMetricsUrl: string | undefined;
509
+ otelMetricsUrl: string;
505
510
  otelProtocol: string;
506
511
  otelTimeout: number;
507
512
  peerServiceMapping: Record<string, string>;
@@ -526,12 +531,13 @@ export interface GeneratedConfig {
526
531
  enabled: boolean;
527
532
  eventLoop: boolean;
528
533
  gc: boolean;
534
+ native: boolean;
529
535
  };
530
536
  runtimeMetricsRuntimeId: boolean;
531
537
  sampleRate: number | undefined;
532
538
  samplingRules: import('../../../../index').SamplingRule[];
533
539
  scope: string | undefined;
534
- service: string | undefined;
540
+ service: string;
535
541
  serviceMapping: Record<string, string>;
536
542
  site: string;
537
543
  spanAttributeSchema: "v0" | "v1";
@@ -29,7 +29,6 @@ const {
29
29
  getEnvironmentVariable,
30
30
  getEnvironmentVariables,
31
31
  getStableConfigSources,
32
- getValueFromEnvSources,
33
32
  } = require('./helper')
34
33
  const {
35
34
  defaults,
@@ -132,7 +131,13 @@ function setAndTrack (config, name, value, rawValue = value, source = 'calculate
132
131
  }
133
132
  changeTracker[source].add(name)
134
133
  } else {
135
- const copy = typeof value === 'object' && value !== null ? rfdc(value) : value
134
+ // Programmatic-only options (e.g. logger, lookup, plugins) have no row in
135
+ // `configurationsTable` and hold opaque user-supplied references that may
136
+ // carry cycles or non-plain prototypes — for example a winston Logger
137
+ // extends a Transform stream. Use a reference for these instead of cloning.
138
+ const copy = typeof value === 'object' && value !== null && name in configurationsTable
139
+ ? rfdc(value)
140
+ : value
136
141
  changeTracker.baseValuesByPath[name] = { value: copy, source }
137
142
  }
138
143
  set(config, name, value)
@@ -229,22 +234,6 @@ class Config extends ConfigBase {
229
234
  #applyEnvs (envs, source) {
230
235
  for (const [name, value] of Object.entries(envs)) {
231
236
  const entry = configurationsTable[name]
232
- // TracePropagationStyle is a special case. It is a single option that is used to set both inject and extract.
233
- // TODO: Consider what to do with this later
234
- if (name === 'DD_TRACE_PROPAGATION_STYLE') {
235
- if (
236
- getValueFromEnvSources('DD_TRACE_PROPAGATION_STYLE_INJECT') !== undefined ||
237
- getValueFromEnvSources('DD_TRACE_PROPAGATION_STYLE_EXTRACT') !== undefined
238
- ) {
239
- log.warn(
240
- // eslint-disable-next-line @stylistic/max-len
241
- 'Use either DD_TRACE_PROPAGATION_STYLE or separate DD_TRACE_PROPAGATION_STYLE_INJECT and DD_TRACE_PROPAGATION_STYLE_EXTRACT environment variables'
242
- )
243
- continue
244
- }
245
- this.#applyEnvs({ DD_TRACE_PROPAGATION_STYLE_INJECT: value, DD_TRACE_PROPAGATION_STYLE_EXTRACT: value }, source)
246
- continue
247
- }
248
237
  const parsed = entry.parser(value, name, source)
249
238
  const transformed = parsed !== undefined && entry.transformer ? entry.transformer(parsed, name, source) : parsed
250
239
  const rawValue = transformed !== null && typeof transformed === 'object' ? value : parsed
@@ -293,6 +282,7 @@ class Config extends ConfigBase {
293
282
  } else {
294
283
  if (fullName === 'tracePropagationStyle') {
295
284
  // TracePropagationStyle is special. It is a single option that is used to set both inject and extract.
285
+ // TODO: Consider what to do with this later
296
286
  // @ts-expect-error - Difficult to type this correctly.
297
287
  this.#applyOptions({ inject: value, extract: value }, source, 'tracePropagationStyle')
298
288
  } else {
@@ -374,6 +364,11 @@ class Config extends ConfigBase {
374
364
  setAndTrack(this, 'otelMetricsEnabled', false)
375
365
  }
376
366
 
367
+ if (this.OTEL_TRACES_EXPORTER === 'otlp' && this.protocolVersion && this.protocolVersion !== '0.4') {
368
+ log.warn('DD_TRACE_AGENT_PROTOCOL_VERSION is set, disabling OTLP traces export')
369
+ setAndTrack(this, 'OTEL_TRACES_EXPORTER', 'none')
370
+ }
371
+
377
372
  if (this.telemetry.heartbeatInterval) {
378
373
  setAndTrack(this, 'telemetry.heartbeatInterval', Math.floor(this.telemetry.heartbeatInterval * 1000))
379
374
  }
@@ -440,8 +435,13 @@ class Config extends ConfigBase {
440
435
  setAndTrack(this, 'runtimeMetrics.enabled', false)
441
436
  }
442
437
 
443
- if (!trackedConfigOrigins.has('sampleRate') && trackedConfigOrigins.has('OTEL_TRACES_SAMPLER')) {
444
- setAndTrack(this, 'sampleRate', getFromOtelSamplerMap(this.OTEL_TRACES_SAMPLER, this.OTEL_TRACES_SAMPLER_ARG))
438
+ // Apply the OTel sampler when the user opted into OTel traces or explicitly set the sampler.
439
+ // OTEL_TRACES_SAMPLER has `default: parentbased_always_on` (per OTel spec), so opt-in users
440
+ // that don't set the sampler still get parent-based sampling.
441
+ if (!trackedConfigOrigins.has('sampleRate') &&
442
+ (trackedConfigOrigins.has('OTEL_TRACES_SAMPLER') || this.OTEL_TRACES_EXPORTER === 'otlp')) {
443
+ setAndTrack(this, 'sampleRate',
444
+ getFromOtelSamplerMap(this.OTEL_TRACES_SAMPLER, this.OTEL_TRACES_SAMPLER_ARG))
445
445
  }
446
446
 
447
447
  if (this.DD_SPAN_SAMPLING_RULES_FILE) {
@@ -541,7 +541,10 @@ class Config extends ConfigBase {
541
541
  isServiceNameInferred = true
542
542
  }
543
543
  }
544
- setAndTrack(this, 'isServiceNameInferred', isServiceNameInferred)
544
+
545
+ // This should not be tracked.
546
+ // TODO: Consider moving this outside of the config.
547
+ set(this, 'isServiceNameInferred', isServiceNameInferred)
545
548
 
546
549
  // Add missing tags, in case they are defined otherwise.
547
550
  if (this.service) {
@@ -593,12 +596,18 @@ class Config extends ConfigBase {
593
596
  }
594
597
  }
595
598
 
596
- const DEFAULT_OTLP_PORT = '4318'
599
+ // TODO: This could likely be moved to the base class and allow easier GRPC handling
600
+ // Default OTLP endpoints follow the configured agent host so users who point DD at a custom
601
+ // agent (DD_AGENT_HOST / DD_TRACE_AGENT_URL) also reach OTLP on that host.
602
+ const defaultOtlpBase = this.OTEL_EXPORTER_OTLP_ENDPOINT?.replace(/\/$/, '') ?? `http://${agentHostname}:4318`
597
603
  if (!this.otelLogsUrl) {
598
- setAndTrack(this, 'otelLogsUrl', `http://${agentHostname}:${DEFAULT_OTLP_PORT}`)
604
+ setAndTrack(this, 'otelLogsUrl', `${defaultOtlpBase}/v1/logs`)
599
605
  }
600
606
  if (!this.otelMetricsUrl) {
601
- setAndTrack(this, 'otelMetricsUrl', `http://${agentHostname}:${DEFAULT_OTLP_PORT}/v1/metrics`)
607
+ setAndTrack(this, 'otelMetricsUrl', `${defaultOtlpBase}/v1/metrics`)
608
+ }
609
+ if (!this.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) {
610
+ setAndTrack(this, 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', `${defaultOtlpBase}/v1/traces`)
602
611
  }
603
612
 
604
613
  if (process.platform === 'win32') {
@@ -691,13 +700,25 @@ function increaseCounter (event, ddVar, otelVar) {
691
700
  }
692
701
 
693
702
  function getFromOtelSamplerMap (otelTracesSampler, otelTracesSamplerArg) {
703
+ const NON_PARENTBASED_TO_PARENTBASED = {
704
+ always_on: 'parentbased_always_on',
705
+ always_off: 'parentbased_always_off',
706
+ traceidratio: 'parentbased_traceidratio',
707
+ }
694
708
  const OTEL_TRACES_SAMPLER_MAPPING = {
695
- always_on: 1,
696
- always_off: 0,
697
709
  parentbased_always_on: 1,
698
710
  parentbased_always_off: 0,
699
711
  }
700
712
 
713
+ const parentBasedEquivalent = NON_PARENTBASED_TO_PARENTBASED[otelTracesSampler]
714
+ if (parentBasedEquivalent) {
715
+ log.info(
716
+ 'OTEL_TRACES_SAMPLER=%s does not respect upstream sampling decisions; using parent-based equivalent %s instead',
717
+ otelTracesSampler, parentBasedEquivalent
718
+ )
719
+ otelTracesSampler = parentBasedEquivalent
720
+ }
721
+
701
722
  const result = OTEL_TRACES_SAMPLER_MAPPING[otelTracesSampler] ?? otelTracesSamplerArg
702
723
  if (result === undefined) {
703
724
  increaseCounter('otel.env.invalid', 'DD_TRACE_SAMPLE_RATE', 'OTEL_TRACES_SAMPLER')
@@ -712,7 +733,7 @@ function warnWrongOtelSettings () {
712
733
  // eslint-disable-next-line eslint-rules/eslint-env-aliases
713
734
  ['OTEL_LOG_LEVEL', 'DD_TRACE_LOG_LEVEL', 'logLevel'],
714
735
  // eslint-disable-next-line eslint-rules/eslint-env-aliases
715
- ['OTEL_PROPAGATORS', 'DD_TRACE_PROPAGATION_STYLE'],
736
+ ['OTEL_PROPAGATORS', 'DD_TRACE_PROPAGATION_STYLE', 'DD_TRACE_PROPAGATION_STYLE'],
716
737
  // eslint-disable-next-line eslint-rules/eslint-env-aliases
717
738
  ['OTEL_SERVICE_NAME', 'DD_SERVICE', 'service'],
718
739
  ['OTEL_TRACES_SAMPLER', 'DD_TRACE_SAMPLE_RATE'],
@@ -733,11 +754,7 @@ function warnWrongOtelSettings () {
733
754
  increaseCounter('otel.env.hiding', ddEnvVar, otelEnvVar)
734
755
  }
735
756
 
736
- // eslint-disable-next-line eslint-rules/eslint-env-aliases
737
- const invalidOtelValue = otelEnvVar === 'OTEL_PROPAGATORS'
738
- ? trackedConfigOrigins.get(/** @type {ConfigPath} */ ('tracePropagationStyle.inject')) !== otelSource &&
739
- !envs[ddEnvVar]
740
- : !otelSource
757
+ const invalidOtelValue = !otelSource
741
758
  if (invalidOtelValue) {
742
759
  increaseCounter('otel.env.invalid', ddEnvVar, otelEnvVar)
743
760
  }
@@ -13,6 +13,15 @@ const VALID_PROPAGATION_STYLES = new Set([
13
13
  'datadog', 'tracecontext', 'b3', 'b3 single header', 'b3multi', 'baggage', 'none',
14
14
  ])
15
15
 
16
+ const RENAMED_OTEL_TAGS = new Map(
17
+ [
18
+ ['deployment.environment.name', 'env'],
19
+ ['deployment.environment', 'env'],
20
+ ['service.name', 'service'],
21
+ ['service.version', 'version'],
22
+ ]
23
+ )
24
+
16
25
  function toCase (value, methodName) {
17
26
  if (Array.isArray(value)) {
18
27
  return value.map(item => {
@@ -66,12 +75,12 @@ const transformers = {
66
75
  }
67
76
  return value
68
77
  },
69
- parseOtelTags (value, optionName) {
70
- return parsers.MAP(value
71
- ?.replace(/(^|,)deployment\.environment=/, '$1env:')
72
- .replace(/(^|,)service\.name=/, '$1service:')
73
- .replace(/(^|,)service\.version=/, '$1version:')
74
- .replaceAll('=', ':'), optionName)
78
+ parseOtelTags (object) {
79
+ const tags = {}
80
+ for (const [key, value] of Object.entries(object)) {
81
+ tags[RENAMED_OTEL_TAGS.get(key) ?? key] = value
82
+ }
83
+ return tags
75
84
  },
76
85
  normalizeProfilingEnabled (configValue) {
77
86
  if (configValue == null) {
@@ -225,11 +234,19 @@ const parsers = {
225
234
  if (!raw) {
226
235
  return entries
227
236
  }
228
- // DD_TAGS is a special case. It may be a map of key-value pairs separated by spaces.
229
- if (optionName === 'DD_TAGS' && !raw.includes(',')) {
237
+ let valueSeparator = ':'
238
+ if (optionName.startsWith('OTEL_')) {
239
+ // OTEL spec uses `key=value,key=value`
240
+ // (https://opentelemetry.io/docs/specs/otel/protocol/exporter/#specifying-headers-via-environment-variables),
241
+ // while DD uses `key:value,key:value`. Parse OTEL-prefixed options with `=` so downstream code
242
+ // receives a proper map and telemetry reports the parsed entries. The char-by-char loop
243
+ // avoids the allocations that `split(',')` + `indexOf('=')` do per pair.
244
+ valueSeparator = '='
245
+ } else if (optionName === 'DD_TAGS' && !raw.includes(',')) {
246
+ // DD_TAGS is a special case. It may be a map of key-value pairs separated by spaces.
230
247
  raw = raw.replaceAll(/\s+/g, ',')
231
248
  }
232
- tagger.add(entries, raw)
249
+ tagger.add(entries, raw, valueSeparator)
233
250
  return entries
234
251
  },
235
252
  JSON (raw) {
@@ -46,12 +46,12 @@
46
46
  ],
47
47
  "DD_AI_GUARD_BLOCK": [
48
48
  {
49
- "implementation": "B",
49
+ "implementation": "C",
50
50
  "type": "boolean",
51
51
  "configurationNames": [
52
52
  "experimental.aiguard.block"
53
53
  ],
54
- "default": "false"
54
+ "default": "true"
55
55
  }
56
56
  ],
57
57
  "DD_AI_GUARD_ENABLED": [
@@ -179,7 +179,8 @@
179
179
  {
180
180
  "implementation": "A",
181
181
  "type": "int",
182
- "default": "100"
182
+ "default": "100",
183
+ "allowed": "\\d+"
183
184
  }
184
185
  ],
185
186
  "DD_APM_TRACING_ENABLED": [
@@ -189,7 +190,10 @@
189
190
  "configurationNames": [
190
191
  "apmTracingEnabled"
191
192
  ],
192
- "default": "true"
193
+ "default": "true",
194
+ "aliases": [
195
+ "DD_TRACING_ENABLED"
196
+ ]
193
197
  }
194
198
  ],
195
199
  "DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE": [
@@ -445,9 +449,9 @@
445
449
  ],
446
450
  "DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER": [
447
451
  {
448
- "implementation": "B",
449
- "type": "boolean",
450
- "default": "false"
452
+ "implementation": "A",
453
+ "type": "string",
454
+ "default": null
451
455
  }
452
456
  ],
453
457
  "DD_CIVISIBILITY_DANGEROUSLY_FORCE_COVERAGE": [
@@ -1573,6 +1577,16 @@
1573
1577
  "default": "10000"
1574
1578
  }
1575
1579
  ],
1580
+ "DD_RUNTIME_METRICS_NATIVE": [
1581
+ {
1582
+ "implementation": "A",
1583
+ "type": "boolean",
1584
+ "configurationNames": [
1585
+ "runtimeMetrics.native"
1586
+ ],
1587
+ "default": "true"
1588
+ }
1589
+ ],
1576
1590
  "DD_RUNTIME_METRICS_GC_ENABLED": [
1577
1591
  {
1578
1592
  "implementation": "A",
@@ -2499,10 +2513,7 @@
2499
2513
  "implementation": "A",
2500
2514
  "type": "boolean",
2501
2515
  "default": "true",
2502
- "internalPropertyName": "tracing",
2503
- "aliases": [
2504
- "DD_TRACING_ENABLED"
2505
- ]
2516
+ "internalPropertyName": "tracing"
2506
2517
  }
2507
2518
  ],
2508
2519
  "DD_TRACE_ENCODING_DEBUG": [
@@ -3100,6 +3111,13 @@
3100
3111
  "default": "true"
3101
3112
  }
3102
3113
  ],
3114
+ "DD_TRACE_MODELCONTEXTPROTOCOL_SDK_ENABLED": [
3115
+ {
3116
+ "implementation": "A",
3117
+ "type": "boolean",
3118
+ "default": "true"
3119
+ }
3120
+ ],
3103
3121
  "DD_TRACE_MOLECULER_ENABLED": [
3104
3122
  {
3105
3123
  "implementation": "A",
@@ -3442,7 +3460,10 @@
3442
3460
  "tracePropagationStyle.extract"
3443
3461
  ],
3444
3462
  "default": "datadog, tracecontext, baggage",
3445
- "transform": "toLowerCase"
3463
+ "transform": "toLowerCase",
3464
+ "aliases": [
3465
+ "DD_TRACE_PROPAGATION_STYLE"
3466
+ ]
3446
3467
  }
3447
3468
  ],
3448
3469
  "DD_TRACE_PROPAGATION_STYLE_INJECT": [
@@ -3453,7 +3474,10 @@
3453
3474
  "tracePropagationStyle.inject"
3454
3475
  ],
3455
3476
  "default": "datadog, tracecontext, baggage",
3456
- "transform": "toLowerCase"
3477
+ "transform": "toLowerCase",
3478
+ "aliases": [
3479
+ "DD_TRACE_PROPAGATION_STYLE"
3480
+ ]
3457
3481
  }
3458
3482
  ],
3459
3483
  "DD_TRACE_PROTOBUFJS_ENABLED": [
@@ -3880,29 +3904,62 @@
3880
3904
  ],
3881
3905
  "OTEL_EXPORTER_OTLP_HEADERS": [
3882
3906
  {
3883
- "implementation": "C",
3884
- "type": "string",
3885
- "default": null,
3886
- "internalPropertyName": "otelHeaders"
3907
+ "implementation": "B",
3908
+ "type": "map",
3909
+ "default": null
3887
3910
  }
3888
3911
  ],
3889
- "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT": [
3912
+ "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": [
3890
3913
  {
3891
3914
  "implementation": "A",
3892
3915
  "type": "string",
3916
+ "default": null
3917
+ }
3918
+ ],
3919
+ "OTEL_EXPORTER_OTLP_TRACES_HEADERS": [
3920
+ {
3921
+ "implementation": "B",
3922
+ "type": "map",
3893
3923
  "default": null,
3894
- "internalPropertyName": "otelLogsUrl",
3895
3924
  "aliases": [
3896
- "OTEL_EXPORTER_OTLP_ENDPOINT"
3925
+ "OTEL_EXPORTER_OTLP_HEADERS"
3897
3926
  ]
3898
3927
  }
3899
3928
  ],
3900
- "OTEL_EXPORTER_OTLP_LOGS_HEADERS": [
3929
+ "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": [
3930
+ {
3931
+ "implementation": "B",
3932
+ "type": "string",
3933
+ "default": "http/json",
3934
+ "allowed": "http/json",
3935
+ "aliases": [
3936
+ "OTEL_EXPORTER_OTLP_PROTOCOL"
3937
+ ]
3938
+ }
3939
+ ],
3940
+ "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT": [
3941
+ {
3942
+ "implementation": "B",
3943
+ "type": "int",
3944
+ "default": "10000",
3945
+ "aliases": [
3946
+ "OTEL_EXPORTER_OTLP_TIMEOUT"
3947
+ ]
3948
+ }
3949
+ ],
3950
+ "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT": [
3901
3951
  {
3902
3952
  "implementation": "A",
3903
3953
  "type": "string",
3904
3954
  "default": null,
3905
- "internalPropertyName": "otelLogsHeaders",
3955
+ "internalPropertyName": "otelLogsUrl"
3956
+ }
3957
+ ],
3958
+ "OTEL_EXPORTER_OTLP_LOGS_HEADERS": [
3959
+ {
3960
+ "implementation": "B",
3961
+ "type": "map",
3962
+ "default": null,
3906
3963
  "aliases": [
3907
3964
  "OTEL_EXPORTER_OTLP_HEADERS"
3908
3965
  ]
@@ -3936,18 +3993,14 @@
3936
3993
  "implementation": "A",
3937
3994
  "type": "string",
3938
3995
  "default": null,
3939
- "internalPropertyName": "otelMetricsUrl",
3940
- "aliases": [
3941
- "OTEL_EXPORTER_OTLP_ENDPOINT"
3942
- ]
3996
+ "internalPropertyName": "otelMetricsUrl"
3943
3997
  }
3944
3998
  ],
3945
3999
  "OTEL_EXPORTER_OTLP_METRICS_HEADERS": [
3946
4000
  {
3947
- "implementation": "B",
3948
- "type": "string",
4001
+ "implementation": "C",
4002
+ "type": "map",
3949
4003
  "default": null,
3950
- "internalPropertyName": "otelMetricsHeaders",
3951
4004
  "aliases": [
3952
4005
  "OTEL_EXPORTER_OTLP_HEADERS"
3953
4006
  ]
@@ -4041,8 +4094,8 @@
4041
4094
  ],
4042
4095
  "OTEL_RESOURCE_ATTRIBUTES": [
4043
4096
  {
4044
- "implementation": "B",
4045
- "type": "string",
4097
+ "implementation": "A",
4098
+ "type": "map",
4046
4099
  "default": "",
4047
4100
  "transform": "parseOtelTags"
4048
4101
  }
@@ -4056,9 +4109,9 @@
4056
4109
  ],
4057
4110
  "OTEL_TRACES_EXPORTER": [
4058
4111
  {
4059
- "implementation": "F",
4112
+ "implementation": "H",
4060
4113
  "type": "string",
4061
- "default": "otlp",
4114
+ "default": null,
4062
4115
  "allowed": "none|otlp",
4063
4116
  "transform": "toLowerCase"
4064
4117
  }
@@ -21,6 +21,7 @@ module.exports = {
21
21
  SPAN_SAMPLING_MECHANISM: '_dd.span_sampling.mechanism',
22
22
  SPAN_SAMPLING_RULE_RATE: '_dd.span_sampling.rule_rate',
23
23
  SPAN_SAMPLING_MAX_PER_SECOND: '_dd.span_sampling.max_per_second',
24
+ SVC_SRC_KEY: '_dd.svc_src',
24
25
  DATADOG_LAMBDA_EXTENSION_PATH: '/opt/extensions/datadog-agent',
25
26
  DATADOG_MINI_AGENT_PATH: '/tmp/datadog/mini_agent_ready',
26
27
  DECISION_MAKER_KEY: '_dd.p.dm',
@@ -5,6 +5,7 @@ module.exports = function getDebuggerConfig (config, inputPath) {
5
5
  commitSHA: config.commitSHA,
6
6
  debug: config.debug,
7
7
  dynamicInstrumentation: config.dynamicInstrumentation,
8
+ env: config.env,
8
9
  hostname: config.hostname,
9
10
  logLevel: config.logLevel,
10
11
  port: config.port,
@@ -13,6 +14,7 @@ module.exports = function getDebuggerConfig (config, inputPath) {
13
14
  runtimeId: config.tags['runtime-id'],
14
15
  service: config.service,
15
16
  url: config.url?.toString(),
17
+ version: config.version,
16
18
  inputPath,
17
19
  }
18
20
  }
@@ -6,7 +6,6 @@ const { stringify } = require('querystring')
6
6
  const { version } = require('../../../../../package.json')
7
7
  const request = require('../../exporters/common/request')
8
8
  const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags')
9
- const { getValueFromEnvSources } = require('../../config/helper')
10
9
  const { DEBUGGER_DIAGNOSTICS_V1, DEBUGGER_INPUT_V2 } = require('../constants')
11
10
  const log = require('./log')
12
11
  const JSONBuffer = require('./json-buffer')
@@ -23,14 +22,14 @@ const ddsource = 'dd_debugger'
23
22
  const hostname = getHostname()
24
23
  const service = config.service
25
24
 
26
- const ddtags = [
27
- ['env', getValueFromEnvSources('DD_ENV')],
28
- ['version', getValueFromEnvSources('DD_VERSION')],
25
+ const ddtags = buildTags([
26
+ ['env', config.env],
27
+ ['version', config.version],
29
28
  ['debugger_version', version],
30
29
  ['host_name', hostname],
31
30
  [GIT_COMMIT_SHA, config.commitSHA],
32
31
  [GIT_REPOSITORY_URL, config.repositoryUrl],
33
- ].filter(([, value]) => value !== undefined).map((pair) => pair.join(':')).join(',')
32
+ ])
34
33
 
35
34
  let path
36
35
  setInputPath(config.inputPath)
@@ -136,3 +135,24 @@ function setInputPath (newPath) {
136
135
  config.inputPath = newPath
137
136
  path = `${newPath}?${stringify({ ddtags })}`
138
137
  }
138
+
139
+ /**
140
+ * @param {Array<[string, unknown]>} tags - The tags to serialize.
141
+ * @returns {string} The serialized tags.
142
+ */
143
+ function buildTags (tags) {
144
+ const serializedTags = []
145
+
146
+ for (const [key, rawValue] of tags) {
147
+ if (rawValue === undefined) continue
148
+
149
+ if (String(rawValue).includes(',')) {
150
+ log.warn('[debugger:devtools_client] Skipping invalid tag value for %s', key)
151
+ continue
152
+ }
153
+
154
+ serializedTags.push(`${key}:${rawValue}`)
155
+ }
156
+
157
+ return serializedTags.join(',')
158
+ }
@@ -105,10 +105,13 @@ function getObjectValue (obj, maxLength) {
105
105
  // case 'node': // TODO: What does this subtype represent?
106
106
  case 'regexp':
107
107
  return { type: obj.className, value: obj.description }
108
- case 'date':
108
+ case 'date': {
109
109
  // TODO: This looses millisecond resolution, as that's not retained in the `.toString()` representation contained
110
110
  // in the `description` field. Unfortunately that's all we get from the Chrome DevTools Protocol.
111
- return { type: obj.className, value: `${new Date(obj.description).toISOString().slice(0, -5)}Z` }
111
+ const date = new Date(obj.description)
112
+ const value = Number.isNaN(date.getTime()) ? obj.description : `${date.toISOString().slice(0, -5)}Z`
113
+ return { type: obj.className, value }
114
+ }
112
115
  case 'map':
113
116
  return toMap(obj.className, obj.properties, maxLength, timeBudgetReached)
114
117
  case 'set':
@@ -1,10 +1,8 @@
1
1
  'use strict'
2
2
 
3
+ const getConfig = require('../config')
3
4
  const { MsgpackChunk, MsgpackEncoder } = require('../msgpack')
4
5
  const log = require('../log')
5
- const { isTrue } = require('../util')
6
- const { memoize } = require('../log/utils')
7
- const { getValueFromEnvSources } = require('../config/helper')
8
6
  const { truncateSpan, normalizeSpan } = require('./tags-processors')
9
7
 
10
8
  const SOFT_LIMIT = 8 * 1024 * 1024 // 8MB
@@ -13,7 +11,7 @@ function formatSpan (span, config) {
13
11
  span = normalizeSpan(truncateSpan(span, false))
14
12
  if (span.span_events) {
15
13
  // ensure span events are encoded as tags if agent doesn't support native top level span events
16
- if (config?.trace?.nativeSpanEvents) {
14
+ if (config.trace.nativeSpanEvents) {
17
15
  formatSpanEvents(span)
18
16
  } else {
19
17
  span.meta.events = JSON.stringify(span.span_events)
@@ -31,8 +29,8 @@ class AgentEncoder {
31
29
  this._stringBytes = new MsgpackChunk()
32
30
  this._writer = writer
33
31
  this._reset()
34
- this._debugEncoding = isTrue(getValueFromEnvSources('DD_TRACE_ENCODING_DEBUG'))
35
- this._config = this._writer?._config
32
+ this._config = getConfig()
33
+ this._debugEncoding = this._config.DD_TRACE_ENCODING_DEBUG
36
34
  }
37
35
 
38
36
  count () {
@@ -338,11 +336,13 @@ class AgentEncoder {
338
336
  }
339
337
  }
340
338
 
341
- const memoizedLogDebug = memoize((key, message) => {
342
- log.debug(message)
343
- // return something to store in memoize cache
344
- return true
345
- })
339
+ const seenKeys = new Set()
340
+ const memoizedLogDebug = (key, message) => {
341
+ if (!seenKeys.has(key)) {
342
+ seenKeys.add(key)
343
+ log.debug(message)
344
+ }
345
+ }
346
346
 
347
347
  function formatSpanEvents (span) {
348
348
  for (const spanEvent of span.span_events) {