dd-trace 5.41.1 → 5.42.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 (59) hide show
  1. package/LICENSE-3rdparty.csv +1 -0
  2. package/index.d.ts +8 -1
  3. package/package.json +6 -3
  4. package/packages/datadog-esbuild/index.js +3 -1
  5. package/packages/datadog-instrumentations/src/cucumber.js +37 -29
  6. package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +102 -0
  7. package/packages/datadog-instrumentations/src/{check_require_cache.js → helpers/check-require-cache.js} +2 -2
  8. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -2
  9. package/packages/datadog-instrumentations/src/helpers/register.js +4 -1
  10. package/packages/datadog-instrumentations/src/jest.js +72 -49
  11. package/packages/datadog-instrumentations/src/langchain.js +29 -10
  12. package/packages/datadog-instrumentations/src/mocha/main.js +53 -34
  13. package/packages/datadog-instrumentations/src/mocha/utils.js +34 -24
  14. package/packages/datadog-instrumentations/src/mocha/worker.js +7 -8
  15. package/packages/datadog-instrumentations/src/openai.js +1 -1
  16. package/packages/datadog-instrumentations/src/playwright.js +37 -30
  17. package/packages/datadog-instrumentations/src/vitest.js +64 -29
  18. package/packages/datadog-plugin-cucumber/src/index.js +13 -4
  19. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +41 -35
  20. package/packages/datadog-plugin-cypress/src/plugin.js +10 -0
  21. package/packages/datadog-plugin-google-cloud-vertexai/src/index.js +195 -0
  22. package/packages/datadog-plugin-jest/src/index.js +18 -6
  23. package/packages/datadog-plugin-langchain/src/handlers/embedding.js +4 -1
  24. package/packages/datadog-plugin-mocha/src/index.js +13 -4
  25. package/packages/datadog-plugin-playwright/src/index.js +19 -5
  26. package/packages/datadog-plugin-vitest/src/index.js +41 -17
  27. package/packages/dd-trace/src/appsec/api_security_sampler.js +7 -3
  28. package/packages/dd-trace/src/appsec/blocking.js +23 -16
  29. package/packages/dd-trace/src/appsec/graphql.js +13 -6
  30. package/packages/dd-trace/src/appsec/rasp/utils.js +0 -1
  31. package/packages/dd-trace/src/appsec/reporter.js +35 -0
  32. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -3
  33. package/packages/dd-trace/src/appsec/telemetry/index.js +5 -1
  34. package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -1
  35. package/packages/dd-trace/src/appsec/telemetry/waf.js +16 -1
  36. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +43 -13
  37. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
  38. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +15 -14
  39. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +1 -2
  40. package/packages/dd-trace/src/ci-visibility/telemetry.js +2 -1
  41. package/packages/dd-trace/src/ci-visibility/{quarantined-tests/get-quarantined-tests.js → test-management/get-test-management-tests.js} +5 -5
  42. package/packages/dd-trace/src/config.js +11 -1
  43. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -2
  44. package/packages/dd-trace/src/lambda/runtime/patch.js +5 -3
  45. package/packages/dd-trace/src/lambda/runtime/ritm.js +13 -18
  46. package/packages/dd-trace/src/llmobs/plugins/openai.js +27 -2
  47. package/packages/dd-trace/src/opentracing/span.js +3 -0
  48. package/packages/dd-trace/src/plugins/ci_plugin.js +38 -10
  49. package/packages/dd-trace/src/plugins/index.js +1 -0
  50. package/packages/dd-trace/src/plugins/util/git.js +7 -3
  51. package/packages/dd-trace/src/plugins/util/test.js +10 -0
  52. package/packages/dd-trace/src/plugins/util/web.js +5 -2
  53. package/packages/dd-trace/src/priority_sampler.js +116 -15
  54. package/packages/dd-trace/src/sampler.js +9 -0
  55. package/packages/dd-trace/src/standalone/product.js +6 -2
  56. package/packages/dd-trace/src/startup-log.js +2 -1
  57. package/packages/dd-trace/src/telemetry/metrics.js +0 -8
  58. package/packages/dd-trace/src/tracer.js +1 -1
  59. /package/packages/datadog-instrumentations/src/{utils/src → helpers}/extract-package-and-module-path.js +0 -0
@@ -27,7 +27,10 @@ const {
27
27
  DI_DEBUG_ERROR_PREFIX,
28
28
  DI_DEBUG_ERROR_SNAPSHOT_ID_SUFFIX,
29
29
  DI_DEBUG_ERROR_FILE_SUFFIX,
30
- DI_DEBUG_ERROR_LINE_SUFFIX
30
+ DI_DEBUG_ERROR_LINE_SUFFIX,
31
+ DD_CAPABILITIES_EARLY_FLAKE_DETECTION,
32
+ DD_CAPABILITIES_AUTO_TEST_RETRIES,
33
+ DD_CAPABILITIES_TEST_IMPACT_ANALYSIS
31
34
  } = require('./util/test')
32
35
  const Plugin = require('./plugin')
33
36
  const { COMPONENT } = require('../constants')
@@ -42,6 +45,19 @@ const { CI_PROVIDER_NAME, GIT_REPOSITORY_URL, GIT_COMMIT_SHA, GIT_BRANCH, CI_WOR
42
45
  const { OS_VERSION, OS_PLATFORM, OS_ARCHITECTURE, RUNTIME_NAME, RUNTIME_VERSION } = require('./util/env')
43
46
  const getDiClient = require('../ci-visibility/dynamic-instrumentation')
44
47
 
48
+ const UNSUPPORTED_TIA_FRAMEWORKS = ['playwright', 'vitest']
49
+ const UNSUPPORTED_TIA_FRAMEWORKS_PARALLEL_MODE = ['cucumber', 'mocha']
50
+
51
+ function isTiaSupported (testFramework, isParallel) {
52
+ if (UNSUPPORTED_TIA_FRAMEWORKS.includes(testFramework)) {
53
+ return false
54
+ }
55
+ if (isParallel && UNSUPPORTED_TIA_FRAMEWORKS_PARALLEL_MODE.includes(testFramework)) {
56
+ return false
57
+ }
58
+ return true
59
+ }
60
+
45
61
  module.exports = class CiPlugin extends Plugin {
46
62
  constructor (...args) {
47
63
  super(...args)
@@ -49,7 +65,7 @@ module.exports = class CiPlugin extends Plugin {
49
65
  this.fileLineToProbeId = new Map()
50
66
  this.rootDir = process.cwd() // fallback in case :session:start events are not emitted
51
67
 
52
- this.addSub(`ci:${this.constructor.id}:library-configuration`, ({ onDone }) => {
68
+ this.addSub(`ci:${this.constructor.id}:library-configuration`, ({ onDone, isParallel }) => {
53
69
  if (!this.tracer._exporter || !this.tracer._exporter.getLibraryConfiguration) {
54
70
  return onDone({ err: new Error('Test optimization was not initialized correctly') })
55
71
  }
@@ -59,6 +75,18 @@ module.exports = class CiPlugin extends Plugin {
59
75
  } else {
60
76
  this.libraryConfig = libraryConfig
61
77
  }
78
+ const { isItrEnabled, isEarlyFlakeDetectionEnabled, isFlakyTestRetriesEnabled } = this.libraryConfig || {}
79
+ const metadataTags = {
80
+ test: {
81
+ [DD_CAPABILITIES_TEST_IMPACT_ANALYSIS]: isItrEnabled ? 'true' : 'false',
82
+ [DD_CAPABILITIES_EARLY_FLAKE_DETECTION]: isEarlyFlakeDetectionEnabled ? 'true' : 'false',
83
+ [DD_CAPABILITIES_AUTO_TEST_RETRIES]: isFlakyTestRetriesEnabled ? 'true' : 'false'
84
+ }
85
+ }
86
+ if (!isTiaSupported(this.constructor.id, isParallel)) {
87
+ metadataTags.test[DD_CAPABILITIES_TEST_IMPACT_ANALYSIS] = undefined
88
+ }
89
+ this.tracer._exporter.addMetadataTags(metadataTags)
62
90
  onDone({ err, libraryConfig })
63
91
  })
64
92
  })
@@ -96,8 +124,8 @@ module.exports = class CiPlugin extends Plugin {
96
124
  }
97
125
  }
98
126
  // tracer might not be initialized correctly
99
- if (this.tracer._exporter.setMetadataTags) {
100
- this.tracer._exporter.setMetadataTags(metadataTags)
127
+ if (this.tracer._exporter.addMetadataTags) {
128
+ this.tracer._exporter.addMetadataTags(metadataTags)
101
129
  }
102
130
 
103
131
  this.testSessionSpan = this.tracer.startSpan(`${this.constructor.id}.test_session`, {
@@ -166,16 +194,16 @@ module.exports = class CiPlugin extends Plugin {
166
194
  })
167
195
  })
168
196
 
169
- this.addSub(`ci:${this.constructor.id}:quarantined-tests`, ({ onDone }) => {
170
- if (!this.tracer._exporter?.getQuarantinedTests) {
197
+ this.addSub(`ci:${this.constructor.id}:test-management-tests`, ({ onDone }) => {
198
+ if (!this.tracer._exporter?.getTestManagementTests) {
171
199
  return onDone({ err: new Error('Test optimization was not initialized correctly') })
172
200
  }
173
- this.tracer._exporter.getQuarantinedTests(this.testConfiguration, (err, quarantinedTests) => {
201
+ this.tracer._exporter.getTestManagementTests(this.testConfiguration, (err, testManagementTests) => {
174
202
  if (err) {
175
- log.error('Quarantined tests could not be fetched. %s', err.message)
176
- this.libraryConfig.isQuarantinedTestsEnabled = false
203
+ log.error('Test management tests could not be fetched. %s', err.message)
204
+ this.libraryConfig.isTestManagementEnabled = false
177
205
  }
178
- onDone({ err, quarantinedTests })
206
+ onDone({ err, testManagementTests })
179
207
  })
180
208
  })
181
209
  }
@@ -9,6 +9,7 @@ module.exports = {
9
9
  get '@elastic/elasticsearch' () { return require('../../../datadog-plugin-elasticsearch/src') },
10
10
  get '@elastic/transport' () { return require('../../../datadog-plugin-elasticsearch/src') },
11
11
  get '@google-cloud/pubsub' () { return require('../../../datadog-plugin-google-cloud-pubsub/src') },
12
+ get '@google-cloud/vertexai' () { return require('../../../datadog-plugin-google-cloud-vertexai/src') },
12
13
  get '@grpc/grpc-js' () { return require('../../../datadog-plugin-grpc/src') },
13
14
  get '@hapi/hapi' () { return require('../../../datadog-plugin-hapi/src') },
14
15
  get '@jest/core' () { return require('../../../datadog-plugin-jest/src') },
@@ -35,7 +35,8 @@ function sanitizedExec (
35
35
  flags,
36
36
  operationMetric,
37
37
  durationMetric,
38
- errorMetric
38
+ errorMetric,
39
+ shouldTrim = true
39
40
  ) {
40
41
  const store = storage('legacy').getStore()
41
42
  storage('legacy').enterWith({ noop: true })
@@ -48,7 +49,10 @@ function sanitizedExec (
48
49
  startTime = Date.now()
49
50
  }
50
51
  try {
51
- const result = cp.execFileSync(cmd, flags, { stdio: 'pipe' }).toString().replace(/(\r\n|\n|\r)/gm, '')
52
+ let result = cp.execFileSync(cmd, flags, { stdio: 'pipe' }).toString()
53
+ if (shouldTrim) {
54
+ result = result.replace(/(\r\n|\n|\r)/gm, '')
55
+ }
52
56
  if (durationMetric) {
53
57
  distributionMetric(durationMetric.name, durationMetric.tags, Date.now() - startTime)
54
58
  }
@@ -330,7 +334,7 @@ function getGitMetadata (ciMetadata) {
330
334
 
331
335
  const tags = {
332
336
  [GIT_COMMIT_MESSAGE]:
333
- commitMessage || sanitizedExec('git', ['show', '-s', '--format=%s']),
337
+ commitMessage || sanitizedExec('git', ['show', '-s', '--format=%B'], null, null, null, false),
334
338
  [GIT_BRANCH]: branch || sanitizedExec('git', ['rev-parse', '--abbrev-ref', 'HEAD']),
335
339
  [GIT_COMMIT_SHA]: commitSHA || sanitizedExec('git', ['rev-parse', 'HEAD']),
336
340
  [CI_WORKSPACE_PATH]: ciWorkspacePath || sanitizedExec('git', ['rev-parse', '--show-toplevel'])
@@ -99,6 +99,11 @@ const MOCHA_WORKER_TRACE_PAYLOAD_CODE = 80
99
99
  const EFD_STRING = "Retried by Datadog's Early Flake Detection"
100
100
  const EFD_TEST_NAME_REGEX = new RegExp(EFD_STRING + ' \\(#\\d+\\): ', 'g')
101
101
 
102
+ // Library Capabilities Tagging
103
+ const DD_CAPABILITIES_TEST_IMPACT_ANALYSIS = '_dd.library_capabilities.test_impact_analysis'
104
+ const DD_CAPABILITIES_EARLY_FLAKE_DETECTION = '_dd.library_capabilities.early_flake_detection'
105
+ const DD_CAPABILITIES_AUTO_TEST_RETRIES = '_dd.library_capabilities.auto_test_retries'
106
+
102
107
  const TEST_LEVEL_EVENT_TYPES = [
103
108
  'test',
104
109
  'test_suite_end',
@@ -115,6 +120,7 @@ const DI_DEBUG_ERROR_SNAPSHOT_ID_SUFFIX = 'snapshot_id'
115
120
  const DI_DEBUG_ERROR_FILE_SUFFIX = 'file'
116
121
  const DI_DEBUG_ERROR_LINE_SUFFIX = 'line'
117
122
 
123
+ const TEST_MANAGEMENT_IS_DISABLED = 'test.test_management.is_test_disabled'
118
124
  const TEST_MANAGEMENT_IS_QUARANTINED = 'test.test_management.is_quarantined'
119
125
  const TEST_MANAGEMENT_ENABLED = 'test.test_management.enabled'
120
126
 
@@ -193,6 +199,9 @@ module.exports = {
193
199
  TEST_BROWSER_NAME,
194
200
  TEST_BROWSER_VERSION,
195
201
  getTestSessionName,
202
+ DD_CAPABILITIES_TEST_IMPACT_ANALYSIS,
203
+ DD_CAPABILITIES_EARLY_FLAKE_DETECTION,
204
+ DD_CAPABILITIES_AUTO_TEST_RETRIES,
196
205
  TEST_LEVEL_EVENT_TYPES,
197
206
  getNumFromKnownTests,
198
207
  getFileAndLineNumberFromError,
@@ -203,6 +212,7 @@ module.exports = {
203
212
  DI_DEBUG_ERROR_LINE_SUFFIX,
204
213
  getFormattedError,
205
214
  DD_TEST_IS_USER_PROVIDED_SERVICE,
215
+ TEST_MANAGEMENT_IS_DISABLED,
206
216
  TEST_MANAGEMENT_IS_QUARANTINED,
207
217
  TEST_MANAGEMENT_ENABLED
208
218
  }
@@ -8,10 +8,11 @@ const tags = require('../../../../../ext/tags')
8
8
  const types = require('../../../../../ext/types')
9
9
  const kinds = require('../../../../../ext/kinds')
10
10
  const urlFilter = require('./urlfilter')
11
- const { extractIp } = require('./ip_extractor')
12
11
  const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../constants')
13
12
  const { createInferredProxySpan, finishInferredProxySpan } = require('./inferred_proxy')
14
13
 
14
+ let extractIp
15
+
15
16
  const WEB = types.WEB
16
17
  const SERVER = kinds.SERVER
17
18
  const RESOURCE_NAME = tags.RESOURCE_NAME
@@ -48,6 +49,8 @@ const web = {
48
49
  const middleware = getMiddlewareSetting(config)
49
50
  const queryStringObfuscation = getQsObfuscator(config)
50
51
 
52
+ extractIp = config.clientIpEnabled && require('./ip_extractor').extractIp
53
+
51
54
  return {
52
55
  ...config,
53
56
  headers,
@@ -460,7 +463,7 @@ function addRequestTags (context, spanType) {
460
463
  })
461
464
 
462
465
  // if client ip has already been set by appsec, no need to run it again
463
- if (config.clientIpEnabled && !span.context()._tags.hasOwnProperty(HTTP_CLIENT_IP)) {
466
+ if (extractIp && !span.context()._tags.hasOwnProperty(HTTP_CLIENT_IP)) {
464
467
  const clientIp = extractIp(config, req)
465
468
 
466
469
  if (clientIp) {
@@ -39,28 +39,54 @@ const DEFAULT_KEY = 'service:,env:'
39
39
 
40
40
  const defaultSampler = new Sampler(AUTO_KEEP)
41
41
 
42
+ /**
43
+ * from config.js
44
+ * @typedef { sampleRate: number, provenance: string, rateLimit: number, rules: SamplingRule[] } SamplingConfig
45
+ *
46
+ * empirically defined
47
+ * @typedef {2|-1|1|0} SamplingPriority
48
+ */
42
49
  class PrioritySampler {
50
+ /**
51
+ * @param env {string}
52
+ * @param config {SamplingConfig}
53
+ */
43
54
  constructor (env, config) {
44
55
  this.configure(env, config)
45
56
  this.update({})
46
57
  }
47
58
 
59
+ /**
60
+ *
61
+ * @param env {string}
62
+ * @param opts {SamplingConfig}
63
+ */
48
64
  configure (env, opts = {}) {
49
65
  const { sampleRate, provenance = undefined, rateLimit = 100, rules = [] } = opts
50
66
  this._env = env
51
- this._rules = this._normalizeRules(rules, sampleRate, rateLimit, provenance)
67
+ this._rules = this.#_normalizeRules(rules, sampleRate, rateLimit, provenance)
52
68
  this._limiter = new RateLimiter(rateLimit)
53
69
 
54
70
  log.trace(env, opts)
55
71
  setSamplingRules(this._rules)
56
72
  }
57
73
 
74
+ /**
75
+ * @param span {DatadogSpan}
76
+ * @returns {boolean}
77
+ */
58
78
  isSampled (span) {
59
79
  const priority = this._getPriorityFromAuto(span)
60
80
  log.trace(span)
61
81
  return priority === USER_KEEP || priority === AUTO_KEEP
62
82
  }
63
83
 
84
+ /**
85
+ *
86
+ * @param span {DatadogSpan}
87
+ * @param auto {boolean}
88
+ * @returns {void}
89
+ */
64
90
  sample (span, auto = true) {
65
91
  if (!span) return
66
92
 
@@ -84,17 +110,20 @@ class PrioritySampler {
84
110
  return
85
111
  }
86
112
 
87
- this._addDecisionMaker(root)
113
+ this.#_addDecisionMaker(root)
88
114
  }
89
115
 
116
+ /**
117
+ *
118
+ * @param rates {Record<string, number>}
119
+ * @returns {void}
120
+ */
90
121
  update (rates) {
91
122
  const samplers = {}
92
123
 
93
124
  for (const key in rates) {
94
125
  const rate = rates[key]
95
- const sampler = new Sampler(rate)
96
-
97
- samplers[key] = sampler
126
+ samplers[key] = new Sampler(rate)
98
127
  }
99
128
 
100
129
  samplers[DEFAULT_KEY] = samplers[DEFAULT_KEY] || defaultSampler
@@ -104,6 +133,11 @@ class PrioritySampler {
104
133
  log.trace(rates)
105
134
  }
106
135
 
136
+ /**
137
+ *
138
+ * @param samplingPriority {SamplingPriority}
139
+ * @returns {boolean}
140
+ */
107
141
  validate (samplingPriority) {
108
142
  switch (samplingPriority) {
109
143
  case USER_REJECT:
@@ -116,6 +150,12 @@ class PrioritySampler {
116
150
  }
117
151
  }
118
152
 
153
+ /**
154
+ *
155
+ * @param span {DatadogSpan}
156
+ * @param samplingPriority {SamplingPriority}
157
+ * @param product {import('./standalone/product').PRODUCTS}
158
+ */
119
159
  setPriority (span, samplingPriority, product) {
120
160
  if (!span || !this.validate(samplingPriority)) return
121
161
 
@@ -134,23 +174,40 @@ class PrioritySampler {
134
174
 
135
175
  log.trace(span, samplingPriority, mechanism)
136
176
 
137
- this._addDecisionMaker(root)
177
+ this.#_addDecisionMaker(root)
138
178
  }
139
179
 
180
+ /**
181
+ *
182
+ * @param span {DatadogSpan}
183
+ * @returns {DatadogSpanContext}
184
+ */
140
185
  _getContext (span) {
141
186
  return typeof span.context === 'function' ? span.context() : span
142
187
  }
143
188
 
189
+ /**
190
+ *
191
+ * @param span {DatadogSpan}
192
+ * @returns {SamplingPriority}
193
+ */
144
194
  _getPriorityFromAuto (span) {
145
195
  const context = this._getContext(span)
146
- const rule = this._findRule(span)
196
+ const rule = this.#_findRule(span)
147
197
 
148
198
  return rule
149
- ? this._getPriorityByRule(context, rule)
150
- : this._getPriorityByAgent(context)
199
+ ? this.#_getPriorityByRule(context, rule)
200
+ : this.#_getPriorityByAgent(context)
151
201
  }
152
202
 
153
- _getPriorityFromTags (tags) {
203
+ /**
204
+ *
205
+ * @param tags {Record<string, symbol | unknown>}
206
+ * Included for compatibility with {@link import('./standalone/tracesource_priority_sampler')._getPriorityFromTags}
207
+ * @param _context {DatadogSpanContext}
208
+ * @returns {SamplingPriority}
209
+ */
210
+ _getPriorityFromTags (tags, _context) {
154
211
  if (hasOwn(tags, MANUAL_KEEP) && tags[MANUAL_KEEP] !== false) {
155
212
  return USER_KEEP
156
213
  } else if (hasOwn(tags, MANUAL_DROP) && tags[MANUAL_DROP] !== false) {
@@ -166,7 +223,13 @@ class PrioritySampler {
166
223
  }
167
224
  }
168
225
 
169
- _getPriorityByRule (context, rule) {
226
+ /**
227
+ *
228
+ * @param context {DatadogSpanContext}
229
+ * @param rule {SamplingRule}
230
+ * @returns {SamplingPriority}
231
+ */
232
+ #_getPriorityByRule (context, rule) {
170
233
  context._trace[SAMPLING_RULE_DECISION] = rule.sampleRate
171
234
  context._sampling.mechanism = SAMPLING_MECHANISM_RULE
172
235
  if (rule.provenance === 'customer') context._sampling.mechanism = SAMPLING_MECHANISM_REMOTE_USER
@@ -177,6 +240,12 @@ class PrioritySampler {
177
240
  : USER_REJECT
178
241
  }
179
242
 
243
+ /**
244
+ *
245
+ * @param context {DatadogSpanContext}
246
+ * @returns {boolean}
247
+ * @private
248
+ */
180
249
  _isSampledByRateLimit (context) {
181
250
  const allowed = this._limiter.isAllowed()
182
251
 
@@ -185,7 +254,13 @@ class PrioritySampler {
185
254
  return allowed
186
255
  }
187
256
 
188
- _getPriorityByAgent (context) {
257
+ /**
258
+ *
259
+ * @param context {DatadogSpanContext}
260
+ * @returns {SamplingPriority}
261
+ * @private
262
+ */
263
+ #_getPriorityByAgent (context) {
189
264
  const key = `service:${context._tags[SERVICE_NAME]},env:${this._env}`
190
265
  const sampler = this._samplers[key] || this._samplers[DEFAULT_KEY]
191
266
 
@@ -200,7 +275,13 @@ class PrioritySampler {
200
275
  return sampler.isSampled(context) ? AUTO_KEEP : AUTO_REJECT
201
276
  }
202
277
 
203
- _addDecisionMaker (span) {
278
+ /**
279
+ *
280
+ * @param span {DatadogSpan}
281
+ * @private
282
+ * @returns {void}
283
+ */
284
+ #_addDecisionMaker (span) {
204
285
  const context = span.context()
205
286
  const trace = context._trace
206
287
  const priority = context._sampling.priority
@@ -215,7 +296,16 @@ class PrioritySampler {
215
296
  }
216
297
  }
217
298
 
218
- _normalizeRules (rules, sampleRate, rateLimit, provenance) {
299
+ /**
300
+ *
301
+ * @param rules {SamplingRule[]}
302
+ * @param sampleRate {number}
303
+ * @param rateLimit {number}
304
+ * @param provenance {string}
305
+ * @returns {SamplingRule[]}
306
+ * @private
307
+ */
308
+ #_normalizeRules (rules, sampleRate, rateLimit, provenance) {
219
309
  rules = [].concat(rules || [])
220
310
 
221
311
  return rules
@@ -225,12 +315,23 @@ class PrioritySampler {
225
315
  .map(SamplingRule.from)
226
316
  }
227
317
 
228
- _findRule (span) {
318
+ /**
319
+ *
320
+ * @param span {DatadogSpan}
321
+ * @returns {SamplingRule}
322
+ * @private
323
+ */
324
+ #_findRule (span) {
229
325
  for (const rule of this._rules) {
230
326
  if (rule.match(span)) return rule
231
327
  }
232
328
  }
233
329
 
330
+ /**
331
+ *
332
+ * @param span {DatadogSpan}
333
+ * @param product {import('./standalone/product').PRODUCTS}
334
+ */
234
335
  static keepTrace (span, product) {
235
336
  span?._prioritySampler?.setPriority(span, USER_KEEP, product)
236
337
  }
@@ -1,14 +1,23 @@
1
1
  'use strict'
2
2
 
3
3
  class Sampler {
4
+ /**
5
+ * @param rate {number}
6
+ */
4
7
  constructor (rate) {
5
8
  this._rate = rate
6
9
  }
7
10
 
11
+ /**
12
+ * @returns {number}
13
+ */
8
14
  rate () {
9
15
  return this._rate
10
16
  }
11
17
 
18
+ /**
19
+ * @returns {boolean}
20
+ */
12
21
  isSampled () {
13
22
  return this._rate === 1 || Math.random() < this._rate
14
23
  }
@@ -13,12 +13,16 @@ function getProductRateLimiter (config) {
13
13
  return dropAll
14
14
  }
15
15
 
16
- module.exports = {
16
+ const PRODUCTS = {
17
17
  APM: { id: 1 << 0 },
18
18
  ASM: { id: 1 << 1, mechanism: SAMPLING_MECHANISM_APPSEC },
19
19
  DSM: { id: 1 << 2 },
20
20
  DJM: { id: 1 << 3 },
21
- DBM: { id: 1 << 4 },
21
+ DBM: { id: 1 << 4 }
22
+ }
23
+
24
+ module.exports = {
25
+ ...PRODUCTS,
22
26
 
23
27
  getProductRateLimiter
24
28
  }
@@ -86,7 +86,8 @@ function tracerInfo () {
86
86
 
87
87
  out.log_injection_enabled = !!config.logInjection
88
88
  out.runtime_metrics_enabled = !!config.runtimeMetrics
89
- out.profiling_enabled = !!(config.profiling || {}).enabled
89
+ const profilingEnabled = config.profiling?.enabled
90
+ out.profiling_enabled = profilingEnabled === 'true' || profilingEnabled === 'auto'
90
91
  Object.assign(out, getIntegrationsAndAnalytics())
91
92
 
92
93
  out.appsec_enabled = !!config.appsec.enabled
@@ -27,19 +27,11 @@ function hasPoints (metric) {
27
27
  return metric.points.length > 0
28
28
  }
29
29
 
30
- let versionTag
31
-
32
30
  class Metric {
33
31
  constructor (namespace, metric, common, tags) {
34
32
  this.namespace = namespace.toString()
35
33
  this.metric = common ? metric : `nodejs.${metric}`
36
34
  this.tags = tagArray(tags)
37
- if (common) {
38
- if (versionTag === undefined) {
39
- versionTag = `version:${process.version}`
40
- }
41
- this.tags.push(versionTag)
42
- }
43
35
  this.common = common
44
36
 
45
37
  this.points = []
@@ -7,7 +7,7 @@ const { isError } = require('./util')
7
7
  const { setStartupLogConfig } = require('./startup-log')
8
8
  const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../dd-trace/src/constants')
9
9
  const { DataStreamsCheckpointer, DataStreamsManager, DataStreamsProcessor } = require('./datastreams')
10
- const { flushStartupLogs } = require('../../datadog-instrumentations/src/check_require_cache')
10
+ const { flushStartupLogs } = require('../../datadog-instrumentations/src/helpers/check-require-cache')
11
11
  const log = require('./log/writer')
12
12
 
13
13
  const SPAN_TYPE = tags.SPAN_TYPE