dd-trace 5.54.0 → 5.55.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 (178) hide show
  1. package/ci/cypress/plugin.js +8 -0
  2. package/ci/cypress/polyfills.js +23 -0
  3. package/ci/init.js +8 -7
  4. package/initialize.mjs +2 -2
  5. package/package.json +6 -6
  6. package/packages/datadog-code-origin/index.js +22 -4
  7. package/packages/datadog-core/src/utils/src/kebabcase.js +3 -3
  8. package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -6
  9. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +2 -3
  10. package/packages/datadog-instrumentations/src/cookie-parser.js +1 -1
  11. package/packages/datadog-instrumentations/src/couchbase.js +3 -6
  12. package/packages/datadog-instrumentations/src/cucumber.js +21 -28
  13. package/packages/datadog-instrumentations/src/dns.js +4 -4
  14. package/packages/datadog-instrumentations/src/elasticsearch.js +9 -10
  15. package/packages/datadog-instrumentations/src/fastify.js +7 -9
  16. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +14 -16
  17. package/packages/datadog-instrumentations/src/hapi.js +10 -11
  18. package/packages/datadog-instrumentations/src/helpers/fetch.js +4 -5
  19. package/packages/datadog-instrumentations/src/helpers/hook.js +1 -2
  20. package/packages/datadog-instrumentations/src/helpers/register.js +6 -5
  21. package/packages/datadog-instrumentations/src/jest.js +67 -98
  22. package/packages/datadog-instrumentations/src/koa.js +2 -3
  23. package/packages/datadog-instrumentations/src/mariadb.js +11 -4
  24. package/packages/datadog-instrumentations/src/mocha/main.js +79 -75
  25. package/packages/datadog-instrumentations/src/mocha.js +3 -1
  26. package/packages/datadog-instrumentations/src/mysql.js +11 -2
  27. package/packages/datadog-instrumentations/src/nyc.js +2 -1
  28. package/packages/datadog-instrumentations/src/openai.js +2 -2
  29. package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -3
  30. package/packages/datadog-instrumentations/src/pg.js +2 -3
  31. package/packages/datadog-instrumentations/src/playwright.js +19 -22
  32. package/packages/datadog-instrumentations/src/protobufjs.js +3 -4
  33. package/packages/datadog-instrumentations/src/redis.js +1 -1
  34. package/packages/datadog-instrumentations/src/restify.js +9 -13
  35. package/packages/datadog-instrumentations/src/router.js +12 -11
  36. package/packages/datadog-instrumentations/src/tedious.js +1 -2
  37. package/packages/datadog-instrumentations/src/vitest.js +15 -29
  38. package/packages/datadog-plugin-avsc/src/schema_iterator.js +12 -12
  39. package/packages/datadog-plugin-aws-sdk/src/base.js +12 -8
  40. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +3 -5
  41. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +12 -20
  42. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -5
  43. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +3 -5
  44. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +3 -5
  45. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -5
  46. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -2
  47. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +7 -10
  48. package/packages/datadog-plugin-cucumber/src/index.js +3 -2
  49. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -1
  50. package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -1
  51. package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
  52. package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +1 -1
  53. package/packages/datadog-plugin-graphql/src/index.js +3 -2
  54. package/packages/datadog-plugin-graphql/src/resolve.js +17 -10
  55. package/packages/datadog-plugin-http/src/client.js +5 -6
  56. package/packages/datadog-plugin-http2/src/client.js +7 -8
  57. package/packages/datadog-plugin-jest/src/index.js +3 -2
  58. package/packages/datadog-plugin-mocha/src/index.js +6 -1
  59. package/packages/datadog-plugin-mongodb-core/src/index.js +2 -1
  60. package/packages/datadog-plugin-mysql/src/index.js +11 -0
  61. package/packages/datadog-plugin-next/src/index.js +1 -1
  62. package/packages/datadog-plugin-openai/src/tracing.js +2 -4
  63. package/packages/datadog-plugin-playwright/src/index.js +3 -2
  64. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +8 -9
  65. package/packages/datadog-plugin-redis/src/index.js +1 -3
  66. package/packages/datadog-plugin-vitest/src/index.js +5 -4
  67. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +0 -1
  68. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +0 -1
  69. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +0 -1
  70. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +0 -1
  71. package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +1 -2
  72. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +11 -12
  73. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
  74. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -1
  75. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +1 -1
  76. package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +1 -2
  77. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +10 -11
  78. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +0 -4
  79. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +0 -1
  80. package/packages/dd-trace/src/appsec/index.js +4 -4
  81. package/packages/dd-trace/src/appsec/reporter.js +5 -7
  82. package/packages/dd-trace/src/appsec/sdk/set_user.js +2 -2
  83. package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -3
  84. package/packages/dd-trace/src/appsec/telemetry/index.js +31 -1
  85. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +6 -2
  86. package/packages/dd-trace/src/azure_metadata.js +8 -3
  87. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +8 -7
  88. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -1
  89. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -1
  90. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -1
  91. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -1
  92. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +4 -3
  93. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +7 -6
  94. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
  95. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -3
  96. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -3
  97. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -1
  98. package/packages/dd-trace/src/config-helper.js +89 -0
  99. package/packages/dd-trace/src/config.js +77 -78
  100. package/packages/dd-trace/src/config_stable.js +7 -4
  101. package/packages/dd-trace/src/datastreams/fnv.js +1 -1
  102. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +6 -6
  103. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +1 -2
  104. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -2
  105. package/packages/dd-trace/src/debugger/devtools_client/index.js +2 -1
  106. package/packages/dd-trace/src/debugger/devtools_client/send.js +3 -2
  107. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -2
  108. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +3 -4
  109. package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +1 -1
  110. package/packages/dd-trace/src/debugger/index.js +1 -0
  111. package/packages/dd-trace/src/dogstatsd.js +2 -2
  112. package/packages/dd-trace/src/encode/0.4.js +5 -2
  113. package/packages/dd-trace/src/encode/0.5.js +3 -5
  114. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +5 -5
  115. package/packages/dd-trace/src/exporter.js +2 -1
  116. package/packages/dd-trace/src/exporters/common/docker.js +3 -2
  117. package/packages/dd-trace/src/exporters/common/request.js +4 -1
  118. package/packages/dd-trace/src/exporters/common/util.js +3 -1
  119. package/packages/dd-trace/src/id.js +3 -3
  120. package/packages/dd-trace/src/index.js +4 -3
  121. package/packages/dd-trace/src/lambda/handler.js +2 -1
  122. package/packages/dd-trace/src/lambda/index.js +2 -1
  123. package/packages/dd-trace/src/lambda/runtime/patch.js +3 -2
  124. package/packages/dd-trace/src/lambda/runtime/ritm.js +3 -2
  125. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
  126. package/packages/dd-trace/src/llmobs/index.js +21 -5
  127. package/packages/dd-trace/src/llmobs/noop.js +18 -20
  128. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +11 -13
  129. package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -2
  130. package/packages/dd-trace/src/llmobs/sdk.js +2 -1
  131. package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
  132. package/packages/dd-trace/src/llmobs/tagger.js +19 -6
  133. package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
  134. package/packages/dd-trace/src/log/index.js +5 -4
  135. package/packages/dd-trace/src/log/writer.js +1 -2
  136. package/packages/dd-trace/src/msgpack/encoder.js +3 -3
  137. package/packages/dd-trace/src/noop/span.js +1 -1
  138. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
  139. package/packages/dd-trace/src/opentracing/propagation/log.js +4 -5
  140. package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -18
  141. package/packages/dd-trace/src/opentracing/span.js +7 -6
  142. package/packages/dd-trace/src/payload-tagging/config/index.js +17 -21
  143. package/packages/dd-trace/src/plugin_manager.js +4 -3
  144. package/packages/dd-trace/src/plugins/ci_plugin.js +25 -1
  145. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  146. package/packages/dd-trace/src/plugins/util/ci.js +7 -7
  147. package/packages/dd-trace/src/plugins/util/git.js +1 -1
  148. package/packages/dd-trace/src/plugins/util/llm.js +2 -2
  149. package/packages/dd-trace/src/plugins/util/stacktrace.js +8 -1
  150. package/packages/dd-trace/src/plugins/util/test.js +4 -3
  151. package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -1
  152. package/packages/dd-trace/src/plugins/util/web.js +3 -4
  153. package/packages/dd-trace/src/priority_sampler.js +46 -35
  154. package/packages/dd-trace/src/profiling/config.js +12 -32
  155. package/packages/dd-trace/src/profiling/exporter_cli.js +20 -20
  156. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  157. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +2 -1
  158. package/packages/dd-trace/src/profiling/index.js +2 -1
  159. package/packages/dd-trace/src/profiling/profiler.js +7 -4
  160. package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +3 -1
  161. package/packages/dd-trace/src/profiling/tagger.js +22 -12
  162. package/packages/dd-trace/src/proxy.js +2 -1
  163. package/packages/dd-trace/src/ritm.js +4 -4
  164. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +3 -2
  165. package/packages/dd-trace/src/sampler.js +10 -2
  166. package/packages/dd-trace/src/serverless.js +11 -4
  167. package/packages/dd-trace/src/span_processor.js +2 -1
  168. package/packages/dd-trace/src/standalone/tracesource.js +1 -2
  169. package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +1 -2
  170. package/packages/dd-trace/src/startup-log.js +5 -17
  171. package/packages/dd-trace/src/supported-configurations.json +439 -0
  172. package/packages/dd-trace/src/telemetry/dependencies.js +62 -57
  173. package/packages/dd-trace/src/telemetry/send-data.js +7 -6
  174. package/packages/dd-trace/src/telemetry/telemetry.js +12 -25
  175. package/packages/dd-trace/src/tracer.js +3 -7
  176. package/packages/dd-trace/src/util.js +0 -5
  177. package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +0 -120
  178. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +0 -20
@@ -15,10 +15,12 @@ const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
15
15
  const { tagger } = require('./tagger')
16
16
  const { isFalse, isTrue } = require('../util')
17
17
  const { getAzureTagsFromMetadata, getAzureAppMetadata } = require('../azure_metadata')
18
+ const { getEnvironmentVariables } = require('../config-helper')
18
19
 
19
20
  class Config {
20
21
  constructor (options = {}) {
21
22
  const {
23
+ AWS_LAMBDA_FUNCTION_NAME: functionname,
22
24
  DD_AGENT_HOST,
23
25
  DD_ENV,
24
26
  DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, // used for testing
@@ -27,14 +29,10 @@ class Config {
27
29
  DD_PROFILING_DEBUG_SOURCE_MAPS,
28
30
  DD_PROFILING_DEBUG_UPLOAD_COMPRESSION,
29
31
  DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
30
- DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,
31
- DD_PROFILING_EXPERIMENTAL_CPU_ENABLED,
32
- DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED,
33
32
  DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES,
34
33
  DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
35
34
  DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
36
35
  DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED,
37
- DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED,
38
36
  DD_PROFILING_HEAP_ENABLED,
39
37
  DD_PROFILING_HEAP_SAMPLING_INTERVAL,
40
38
  DD_PROFILING_PPROF_PREFIX,
@@ -50,13 +48,12 @@ class Config {
50
48
  DD_TRACE_AGENT_PORT,
51
49
  DD_TRACE_AGENT_URL,
52
50
  DD_VERSION
53
- } = process.env
51
+ } = getEnvironmentVariables()
54
52
 
55
53
  const env = coalesce(options.env, DD_ENV)
56
54
  const service = options.service || DD_SERVICE || 'node'
57
55
  const host = os.hostname()
58
56
  const version = coalesce(options.version, DD_VERSION)
59
- const functionname = process.env.AWS_LAMBDA_FUNCTION_NAME
60
57
  // Must be longer than one minute so pad with five seconds
61
58
  const flushInterval = coalesce(options.interval, Number(DD_PROFILING_UPLOAD_PERIOD) * 1000, 65 * 1000)
62
59
  const uploadTimeout = coalesce(options.uploadTimeout,
@@ -86,16 +83,6 @@ class Config {
86
83
  }
87
84
 
88
85
  this.logger = ensureLogger(options.logger)
89
- const logger = this.logger
90
- function logExperimentalVarDeprecation (shortVarName) {
91
- const deprecatedEnvVarName = `DD_PROFILING_EXPERIMENTAL_${shortVarName}`
92
- const v = process.env[deprecatedEnvVarName]
93
- // not null, undefined, or NaN -- same logic as koalas.hasValue
94
- // eslint-disable-next-line no-self-compare
95
- if (v != null && v === v) {
96
- logger.warn(`${deprecatedEnvVarName} is deprecated. Use DD_PROFILING_${shortVarName} instead.`)
97
- }
98
- }
99
86
  // Profiler sampling contexts are not available on Windows, so features
100
87
  // depending on those (code hotspots and endpoint collection) need to default
101
88
  // to false on Windows.
@@ -119,9 +106,7 @@ class Config {
119
106
  this.sourceMap = sourceMap
120
107
  this.debugSourceMaps = isTrue(coalesce(options.debugSourceMaps, DD_PROFILING_DEBUG_SOURCE_MAPS, false))
121
108
  this.endpointCollectionEnabled = isTrue(coalesce(options.endpointCollection,
122
- DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
123
- DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
124
- logExperimentalVarDeprecation('ENDPOINT_COLLECTION_ENABLED')
109
+ DD_PROFILING_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
125
110
  checkOptionWithSamplingContextAllowed(this.endpointCollectionEnabled, 'Endpoint collection')
126
111
 
127
112
  this.pprofPrefix = pprofPrefix
@@ -172,23 +157,18 @@ class Config {
172
157
  })
173
158
 
174
159
  this.timelineEnabled = isTrue(coalesce(options.timelineEnabled,
175
- DD_PROFILING_TIMELINE_ENABLED,
176
- DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED, samplingContextsAvailable))
177
- logExperimentalVarDeprecation('TIMELINE_ENABLED')
160
+ DD_PROFILING_TIMELINE_ENABLED, samplingContextsAvailable))
178
161
  checkOptionWithSamplingContextAllowed(this.timelineEnabled, 'Timeline view')
179
162
  this.timelineSamplingEnabled = isTrue(coalesce(options.timelineSamplingEnabled,
180
163
  DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, true))
181
164
 
182
165
  this.codeHotspotsEnabled = isTrue(coalesce(options.codeHotspotsEnabled,
183
- DD_PROFILING_CODEHOTSPOTS_ENABLED,
184
- DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
185
- logExperimentalVarDeprecation('CODEHOTSPOTS_ENABLED')
166
+ DD_PROFILING_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
186
167
  checkOptionWithSamplingContextAllowed(this.codeHotspotsEnabled, 'Code hotspots')
187
168
 
188
169
  this.cpuProfilingEnabled = isTrue(coalesce(options.cpuProfilingEnabled,
189
170
  DD_PROFILING_CPU_ENABLED,
190
- DD_PROFILING_EXPERIMENTAL_CPU_ENABLED, samplingContextsAvailable))
191
- logExperimentalVarDeprecation('CPU_ENABLED')
171
+ samplingContextsAvailable))
192
172
  checkOptionWithSamplingContextAllowed(this.cpuProfilingEnabled, 'CPU profiling')
193
173
 
194
174
  this.heapSamplingInterval = coalesce(options.heapSamplingInterval,
@@ -196,25 +176,25 @@ class Config {
196
176
  const uploadCompression0 = coalesce(options.uploadCompression, DD_PROFILING_DEBUG_UPLOAD_COMPRESSION, 'on')
197
177
  let [uploadCompression, level0] = uploadCompression0.split('-')
198
178
  if (!['on', 'off', 'gzip', 'zstd'].includes(uploadCompression)) {
199
- logger.warn(`Invalid profile upload compression method "${uploadCompression0}". Will use "on".`)
179
+ this.logger.warn(`Invalid profile upload compression method "${uploadCompression0}". Will use "on".`)
200
180
  uploadCompression = 'on'
201
181
  }
202
182
  let level = level0 ? Number.parseInt(level0, 10) : undefined
203
183
  if (level !== undefined) {
204
184
  if (['on', 'off'].includes(uploadCompression)) {
205
- logger.warn(`Compression levels are not supported for "${uploadCompression}".`)
185
+ this.logger.warn(`Compression levels are not supported for "${uploadCompression}".`)
206
186
  level = undefined
207
187
  } else if (Number.isNaN(level)) {
208
- logger.warn(
188
+ this.logger.warn(
209
189
  `Invalid compression level "${level0}". Will use default level.`)
210
190
  level = undefined
211
191
  } else if (level < 1) {
212
- logger.warn(`Invalid compression level ${level}. Will use 1.`)
192
+ this.logger.warn(`Invalid compression level ${level}. Will use 1.`)
213
193
  level = 1
214
194
  } else {
215
195
  const maxLevel = { gzip: 9, zstd: 22 }[uploadCompression]
216
196
  if (level > maxLevel) {
217
- logger.warn(`Invalid compression level ${level}. Will use ${maxLevel}.`)
197
+ this.logger.warn(`Invalid compression level ${level}. Will use ${maxLevel}.`)
218
198
  level = maxLevel
219
199
  }
220
200
  }
@@ -8,6 +8,7 @@ const { ConsoleLogger } = require('./loggers/console')
8
8
  const { tagger } = require('./tagger')
9
9
  const fs = require('fs')
10
10
  const { fileURLToPath } = require('url')
11
+ const { getEnvironmentVariable } = require('../config-helper')
11
12
 
12
13
  const logger = new ConsoleLogger()
13
14
  const timeoutMs = 15 * 1000
@@ -15,25 +16,24 @@ const timeoutMs = 15 * 1000
15
16
  function exporterFromURL (url) {
16
17
  if (url.protocol === 'file:') {
17
18
  return new FileExporter({ pprofPrefix: fileURLToPath(url) })
18
- } else {
19
- const injectionEnabled = (process.env.DD_INJECTION_ENABLED || '').split(',')
20
- const libraryInjected = injectionEnabled.length > 0
21
- const profilingEnabled = (process.env.DD_PROFILING_ENABLED || '').toLowerCase()
22
- const activation = ['true', '1'].includes(profilingEnabled)
23
- ? 'manual'
24
- : profilingEnabled === 'auto'
25
- ? 'auto'
26
- : injectionEnabled.includes('profiling')
27
- ? 'injection'
28
- : 'unknown'
29
- return new AgentExporter({
30
- url,
31
- logger,
32
- uploadTimeout: timeoutMs,
33
- libraryInjected,
34
- activation
35
- })
36
19
  }
20
+ const injectionEnabled = (getEnvironmentVariable('DD_INJECTION_ENABLED') ?? '').split(',')
21
+ const libraryInjected = injectionEnabled.length > 0
22
+ const profilingEnabled = (getEnvironmentVariable('DD_PROFILING_ENABLED') ?? '').toLowerCase()
23
+ const activation = ['true', '1'].includes(profilingEnabled)
24
+ ? 'manual'
25
+ : profilingEnabled === 'auto'
26
+ ? 'auto'
27
+ : injectionEnabled.includes('profiling')
28
+ ? 'injection'
29
+ : 'unknown'
30
+ return new AgentExporter({
31
+ url,
32
+ logger,
33
+ uploadTimeout: timeoutMs,
34
+ libraryInjected,
35
+ activation
36
+ })
37
37
  }
38
38
 
39
39
  async function exportProfile (urls, tags, profileType, profile) {
@@ -46,7 +46,7 @@ async function exportProfile (urls, tags, profileType, profile) {
46
46
 
47
47
  const encodedProfile = await encode(heap.convertProfile(profile, undefined, mapper))
48
48
  const start = new Date()
49
- for (const url of urls) {
49
+ await Promise.all(urls.map(async (url) => {
50
50
  const exporter = exporterFromURL(url)
51
51
 
52
52
  await exporter.export({
@@ -57,7 +57,7 @@ async function exportProfile (urls, tags, profileType, profile) {
57
57
  end: start,
58
58
  tags
59
59
  })
60
- }
60
+ }))
61
61
  }
62
62
 
63
63
  /** Expected command line arguments are:
@@ -150,7 +150,7 @@ class AgentExporter extends EventSerializer {
150
150
  'DD-EVP-ORIGIN-VERSION': version,
151
151
  ...form.getHeaders()
152
152
  },
153
- timeout: this._backoffTime * Math.pow(2, attempt)
153
+ timeout: this._backoffTime * 2 ** attempt
154
154
  }
155
155
 
156
156
  docker.inject(options.headers)
@@ -1,9 +1,10 @@
1
1
  const os = require('os')
2
2
  const perf = require('perf_hooks').performance
3
3
  const version = require('../../../../../package.json').version
4
+ const { getEnvironmentVariable } = require('../../config-helper')
4
5
 
5
6
  const libuvThreadPoolSize = (() => {
6
- const ss = process.env.UV_THREADPOOL_SIZE
7
+ const ss = getEnvironmentVariable('UV_THREADPOOL_SIZE')
7
8
  if (ss === undefined) {
8
9
  // Backend will apply the default size based on Node version.
9
10
  return
@@ -6,8 +6,9 @@ const SpaceProfiler = require('./profilers/space')
6
6
  const { AgentExporter } = require('./exporters/agent')
7
7
  const { FileExporter } = require('./exporters/file')
8
8
  const { ConsoleLogger } = require('./loggers/console')
9
+ const { getEnvironmentVariable } = require('../config-helper')
9
10
 
10
- const profiler = process.env.AWS_LAMBDA_FUNCTION_NAME ? new ServerlessProfiler() : new Profiler()
11
+ const profiler = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') ? new ServerlessProfiler() : new Profiler()
11
12
 
12
13
  module.exports = {
13
14
  profiler,
@@ -226,7 +226,7 @@ class Profiler extends EventEmitter {
226
226
  const encodedProfiles = {}
227
227
 
228
228
  try {
229
- if (Object.keys(this._config.profilers).length === 0) {
229
+ if (this._config.profilers.length === 0) {
230
230
  throw new Error('No profile types configured.')
231
231
  }
232
232
 
@@ -246,8 +246,10 @@ class Profiler extends EventEmitter {
246
246
  this._capture(this._timeoutInterval, endDate)
247
247
  }
248
248
 
249
+ let hasEncoded = false
250
+
249
251
  // encode and export asynchronously
250
- for (const { profiler, profile } of profiles) {
252
+ await Promise.all(profiles.map(async ({ profiler, profile }) => {
251
253
  try {
252
254
  const encoded = await profiler.encode(profile)
253
255
  const compressed = encoded instanceof Buffer && this._compressionFn !== undefined
@@ -260,14 +262,15 @@ class Profiler extends EventEmitter {
260
262
  })
261
263
  return `Collected ${profiler.type} profile: ` + profileJson
262
264
  })
265
+ hasEncoded = true
263
266
  } catch (err) {
264
267
  // If encoding one of the profile types fails, we should still try to
265
268
  // encode and submit the other profile types.
266
269
  this._logError(err)
267
270
  }
268
- }
271
+ }))
269
272
 
270
- if (Object.keys(encodedProfiles).length > 0) {
273
+ if (hasEncoded) {
271
274
  await this._submit(encodedProfiles, startDate, endDate, snapshotKind)
272
275
  profileSubmittedChannel.publish()
273
276
  this._logger.debug('Submitted profiles')
@@ -3,7 +3,9 @@
3
3
  const dc = require('dc-polyfill')
4
4
  const coalesce = require('koalas')
5
5
  const profileSubmittedChannel = dc.channel('datadog:profiling:mock-profile-submitted')
6
- const { DD_PROFILING_UPLOAD_PERIOD } = process.env
6
+ const { getEnvironmentVariable } = require('../config-helper')
7
+
8
+ const DD_PROFILING_UPLOAD_PERIOD = getEnvironmentVariable('DD_PROFILING_UPLOAD_PERIOD')
7
9
 
8
10
  let timerId
9
11
 
@@ -5,20 +5,30 @@ const tagger = {
5
5
  if (!tags) return {}
6
6
 
7
7
  switch (typeof tags) {
8
- case 'object':
9
- return Array.isArray(tags)
10
- ? tags.reduce((prev, next) => {
11
- const parts = next.split(':')
12
- const key = parts.shift().trim()
13
- const value = parts.join(':').trim()
8
+ case 'object': {
9
+ if (Array.isArray(tags)) {
10
+ const tagObject = {}
11
+ for (const tag of tags) {
12
+ const colon = tag.indexOf(':')
13
+ if (colon === -1) continue
14
+ const key = tag.slice(0, colon).trim()
15
+ const value = tag.slice(colon + 1).trim()
16
+ if (key.length !== 0 && value.length !== 0) {
17
+ tagObject[key] = value
18
+ }
19
+ }
20
+ return tagObject
21
+ }
14
22
 
15
- if (!key || !value) return prev
23
+ const tagsArray = []
24
+ for (const [key, value] of Object.entries(tags)) {
25
+ if (value != null) {
26
+ tagsArray.push(`${key}:${value}`)
27
+ }
28
+ }
16
29
 
17
- return Object.assign(prev, { [key]: value })
18
- }, {})
19
- : tagger.parse(Object.keys(tags)
20
- .filter(key => tags[key] !== undefined && tags[key] !== null)
21
- .map(key => `${key}:${tags[key]}`))
30
+ return tagger.parse(tagsArray)
31
+ }
22
32
  case 'string':
23
33
  return tagger.parse(tags.split(','))
24
34
  default:
@@ -10,6 +10,7 @@ const telemetry = require('./telemetry')
10
10
  const nomenclature = require('./service-naming')
11
11
  const PluginManager = require('./plugin_manager')
12
12
  const NoopDogStatsDClient = require('./noop/dogstatsd')
13
+ const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
13
14
  const {
14
15
  setBaggageItem,
15
16
  getBaggageItem,
@@ -198,7 +199,7 @@ class Tracer extends NoopProxy {
198
199
  this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
199
200
  }
200
201
  if (config.ciVisAgentlessLogSubmissionEnabled) {
201
- if (process.env.DD_API_KEY) {
202
+ if (getEnvironmentVariable('DD_API_KEY')) {
202
203
  const LogSubmissionPlugin = require('./ci-visibility/log-submission/log-submission-plugin')
203
204
  const automaticLogPlugin = new LogSubmissionPlugin(this)
204
205
  automaticLogPlugin.configure({ ...config, enabled: true })
@@ -4,6 +4,7 @@ const path = require('path')
4
4
  const Module = require('module')
5
5
  const parse = require('module-details-from-path')
6
6
  const dc = require('dc-polyfill')
7
+ const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
7
8
 
8
9
  const origRequire = Module.prototype.require
9
10
 
@@ -82,9 +83,8 @@ function Hook (modules, options, onrequire) {
82
83
  if (patched) {
83
84
  // If it's already patched, just return it as-is.
84
85
  return origRequire.apply(this, arguments)
85
- } else {
86
- patching[filename] = true
87
86
  }
87
+ patching[filename] = true
88
88
 
89
89
  const payload = {
90
90
  filename,
@@ -110,8 +110,8 @@ function Hook (modules, options, onrequire) {
110
110
  if (!hooks) return exports // abort if module name isn't on whitelist
111
111
  name = filename
112
112
  } else {
113
- const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
114
- const hasLambdaHandler = process.env.DD_LAMBDA_HANDLER !== undefined
113
+ const inAWSLambda = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') !== undefined
114
+ const hasLambdaHandler = getEnvironmentVariable('DD_LAMBDA_HANDLER') !== undefined
115
115
  const segments = filename.split(path.sep)
116
116
  const filenameFromNodeModule = segments.includes('node_modules')
117
117
  // decide how to assign the stat
@@ -8,9 +8,10 @@ const { DogStatsDClient, MetricsAggregationClient } = require('../dogstatsd')
8
8
  const log = require('../log')
9
9
  const Histogram = require('../histogram')
10
10
  const { performance, PerformanceObserver } = require('perf_hooks')
11
+ const { getEnvironmentVariable } = require('../config-helper')
11
12
 
12
13
  const { NODE_MAJOR, NODE_MINOR } = require('../../../../version')
13
- const { DD_RUNTIME_METRICS_FLUSH_INTERVAL = '10000' } = process.env
14
+ const DD_RUNTIME_METRICS_FLUSH_INTERVAL = getEnvironmentVariable('DD_RUNTIME_METRICS_FLUSH_INTERVAL') ?? '10000'
14
15
  const INTERVAL = Number.parseInt(DD_RUNTIME_METRICS_FLUSH_INTERVAL, 10)
15
16
 
16
17
  // Node >=16 has PerformanceObserver with `gc` type, but <16.7 had a critical bug.
@@ -202,7 +203,7 @@ function captureGCMetrics () {
202
203
  const pause = {}
203
204
 
204
205
  for (const stat of profile.statistics) {
205
- const type = stat.gcType.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase()
206
+ const type = stat.gcType.replaceAll(/([a-z])([A-Z])/g, '$1_$2').toLowerCase()
206
207
 
207
208
  pause[type] = pause[type] || new Histogram()
208
209
  pause[type].record(stat.cost)
@@ -16,12 +16,16 @@ const SAMPLING_KNUTH_FACTOR = 1_111_111_111_111_111_111n
16
16
  * This class uses a deterministic sampling algorithm that is consistent across all languages.
17
17
  */
18
18
  class Sampler {
19
+ #threshold = 0n
20
+
19
21
  /**
20
22
  * @param {number} rate
21
23
  */
22
24
  constructor (rate) {
25
+ // TODO: Should this be moved up to the calling parts?
26
+ rate = Math.min(Math.max(rate, 0), 1)
23
27
  this._rate = rate
24
- this._threshold = BigInt(Math.floor(rate * MAX_TRACE_ID))
28
+ this.#threshold = BigInt(Math.floor(rate * MAX_TRACE_ID))
25
29
  }
26
30
 
27
31
  /**
@@ -31,6 +35,10 @@ class Sampler {
31
35
  return this._rate
32
36
  }
33
37
 
38
+ get threshold () {
39
+ return this.#threshold
40
+ }
41
+
34
42
  /**
35
43
  * Determines whether a trace/span should be sampled based on the configured sampling rate.
36
44
  *
@@ -48,7 +56,7 @@ class Sampler {
48
56
 
49
57
  span = typeof span.context === 'function' ? span.context() : span
50
58
 
51
- return (span._traceId.toBigInt() * SAMPLING_KNUTH_FACTOR) % UINT64_MODULO <= this._threshold
59
+ return (span._traceId.toBigInt() * SAMPLING_KNUTH_FACTOR) % UINT64_MODULO <= this.#threshold
52
60
  }
53
61
  }
54
62
 
@@ -1,21 +1,28 @@
1
1
  'use strict'
2
2
 
3
+ const { getEnvironmentVariable } = require('./config-helper')
4
+
3
5
  function getIsGCPFunction () {
4
- const isDeprecatedGCPFunction = process.env.FUNCTION_NAME !== undefined && process.env.GCP_PROJECT !== undefined
5
- const isNewerGCPFunction = process.env.K_SERVICE !== undefined && process.env.FUNCTION_TARGET !== undefined
6
+ const isDeprecatedGCPFunction =
7
+ getEnvironmentVariable('FUNCTION_NAME') !== undefined &&
8
+ getEnvironmentVariable('GCP_PROJECT') !== undefined
9
+ const isNewerGCPFunction =
10
+ getEnvironmentVariable('K_SERVICE') !== undefined &&
11
+ getEnvironmentVariable('FUNCTION_TARGET') !== undefined
6
12
 
7
13
  return isDeprecatedGCPFunction || isNewerGCPFunction
8
14
  }
9
15
 
10
16
  function getIsAzureFunction () {
11
17
  const isAzureFunction =
12
- process.env.FUNCTIONS_EXTENSION_VERSION !== undefined && process.env.FUNCTIONS_WORKER_RUNTIME !== undefined
18
+ getEnvironmentVariable('FUNCTIONS_EXTENSION_VERSION') !== undefined &&
19
+ getEnvironmentVariable('FUNCTIONS_WORKER_RUNTIME') !== undefined
13
20
 
14
21
  return isAzureFunction
15
22
  }
16
23
 
17
24
  function isInServerlessEnvironment () {
18
- const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
25
+ const inAWSLambda = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') !== undefined
19
26
  const isGCPFunction = getIsGCPFunction()
20
27
  const isAzureFunction = getIsAzureFunction()
21
28
 
@@ -4,6 +4,7 @@ const log = require('./log')
4
4
  const format = require('./format')
5
5
  const SpanSampler = require('./span_sampler')
6
6
  const GitMetadataTagger = require('./git_metadata_tagger')
7
+ const { getEnvironmentVariable } = require('./config-helper')
7
8
 
8
9
  const startedSpans = new WeakSet()
9
10
  const finishedSpans = new WeakSet()
@@ -79,7 +80,7 @@ class SpanProcessor {
79
80
  }
80
81
 
81
82
  _erase (trace, active) {
82
- if (process.env.DD_TRACE_EXPERIMENTAL_STATE_TRACKING === 'true') {
83
+ if (getEnvironmentVariable('DD_TRACE_EXPERIMENTAL_STATE_TRACKING') === 'true') {
83
84
  const started = new Set()
84
85
  const startedIds = new Set()
85
86
  const finished = new Set()
@@ -1,7 +1,6 @@
1
1
  'use strict'
2
2
 
3
3
  const { TRACE_SOURCE_PROPAGATION_KEY } = require('../constants')
4
- const { hasOwn } = require('../util')
5
4
 
6
5
  function addTraceSourceTag (tags, product) {
7
6
  if (tags && product) {
@@ -13,7 +12,7 @@ function addTraceSourceTag (tags, product) {
13
12
  }
14
13
 
15
14
  function hasTraceSourcePropagationTag (tags) {
16
- return hasOwn(tags, TRACE_SOURCE_PROPAGATION_KEY)
15
+ return Object.hasOwn(tags, TRACE_SOURCE_PROPAGATION_KEY)
17
16
  }
18
17
 
19
18
  module.exports = {
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const { hasOwn } = require('../util')
4
3
  const PrioritySampler = require('../priority_sampler')
5
4
  const { MANUAL_KEEP } = require('../../../../ext/tags')
6
5
  const { USER_KEEP, AUTO_KEEP, AUTO_REJECT } = require('../../../../ext/priority')
@@ -16,7 +15,7 @@ class TraceSourcePrioritySampler extends PrioritySampler {
16
15
  }
17
16
 
18
17
  _getPriorityFromTags (tags, context) {
19
- if (hasOwn(tags, MANUAL_KEEP) &&
18
+ if (Object.hasOwn(tags, MANUAL_KEEP) &&
20
19
  tags[MANUAL_KEEP] !== false &&
21
20
  hasTraceSourcePropagationTag(context._trace.tags)
22
21
  ) {
@@ -13,13 +13,9 @@ let samplingRules = []
13
13
  let alreadyRan = false
14
14
 
15
15
  function getIntegrationsAndAnalytics () {
16
- const integrations = new Set()
17
- const extras = {}
18
- for (const pluginName in pluginManager._pluginsByName) {
19
- integrations.add(pluginName)
16
+ return {
17
+ integrations_loaded: Object.keys(pluginManager._pluginsByName)
20
18
  }
21
- extras.integrations_loaded = [...integrations]
22
- return extras
23
19
  }
24
20
 
25
21
  function startupLog ({ agentError } = {}) {
@@ -61,7 +57,9 @@ function tracerInfo () {
61
57
  return String(this)
62
58
  },
63
59
  toString () {
64
- return JSON.stringify(this)
60
+ return JSON.stringify(this, (_key_, value) => {
61
+ return typeof value === 'bigint' || typeof value === 'symbol' ? String(value) : value
62
+ })
65
63
  }
66
64
  }
67
65
 
@@ -92,16 +90,6 @@ function tracerInfo () {
92
90
 
93
91
  out.appsec_enabled = !!config.appsec.enabled
94
92
 
95
- // // This next bunch is for features supported by other tracers, but not this
96
- // // one. They may be implemented in the future.
97
-
98
- // out.enabled_cli
99
- // out.sampling_rules_error
100
- // out.integration_XXX_analytics_enabled
101
- // out.integration_XXX_sample_rate
102
- // out.service_mapping
103
- // out.service_mapping_error
104
-
105
93
  return out
106
94
  }
107
95