dd-trace 5.58.0 → 5.60.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 (179) hide show
  1. package/LICENSE-3rdparty.csv +1 -0
  2. package/ci/cypress/after-run.js +2 -0
  3. package/ci/cypress/after-spec.js +2 -0
  4. package/ci/cypress/plugin.js +2 -0
  5. package/ci/cypress/polyfills.js +2 -0
  6. package/ci/cypress/support.js +2 -0
  7. package/ci/init.js +2 -0
  8. package/index.d.ts +7 -0
  9. package/init.js +0 -2
  10. package/initialize.mjs +2 -0
  11. package/package.json +40 -8
  12. package/packages/datadog-code-origin/index.js +14 -9
  13. package/packages/datadog-instrumentations/src/apollo-server.js +14 -3
  14. package/packages/datadog-instrumentations/src/apollo.js +7 -10
  15. package/packages/datadog-instrumentations/src/avsc.js +2 -0
  16. package/packages/datadog-instrumentations/src/child_process.js +21 -42
  17. package/packages/datadog-instrumentations/src/cucumber.js +10 -8
  18. package/packages/datadog-instrumentations/src/cypress.js +2 -0
  19. package/packages/datadog-instrumentations/src/fastify.js +19 -1
  20. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  21. package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
  22. package/packages/datadog-instrumentations/src/hono.js +102 -0
  23. package/packages/datadog-instrumentations/src/langchain.js +21 -0
  24. package/packages/datadog-instrumentations/src/mocha/common.js +2 -0
  25. package/packages/datadog-instrumentations/src/mocha.js +2 -0
  26. package/packages/datadog-instrumentations/src/nyc.js +2 -0
  27. package/packages/datadog-instrumentations/src/openai.js +13 -114
  28. package/packages/datadog-instrumentations/src/orchestrion-config/index.js +32 -0
  29. package/packages/datadog-instrumentations/src/playwright.js +5 -1
  30. package/packages/datadog-instrumentations/src/protobufjs.js +2 -0
  31. package/packages/datadog-instrumentations/src/selenium.js +2 -0
  32. package/packages/datadog-instrumentations/src/vitest.js +2 -0
  33. package/packages/datadog-plugin-avsc/src/index.js +2 -0
  34. package/packages/datadog-plugin-avsc/src/schema_iterator.js +2 -0
  35. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +2 -0
  36. package/packages/datadog-plugin-child_process/src/index.js +30 -10
  37. package/packages/datadog-plugin-cypress/src/after-run.js +2 -0
  38. package/packages/datadog-plugin-cypress/src/after-spec.js +2 -0
  39. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +8 -3
  40. package/packages/datadog-plugin-cypress/src/index.js +2 -0
  41. package/packages/datadog-plugin-cypress/src/plugin.js +2 -0
  42. package/packages/datadog-plugin-cypress/src/support.js +4 -2
  43. package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +3 -155
  44. package/packages/datadog-plugin-google-cloud-vertexai/src/utils.js +2 -0
  45. package/packages/datadog-plugin-graphql/src/utils.js +2 -0
  46. package/packages/datadog-plugin-hono/src/index.js +28 -0
  47. package/packages/datadog-plugin-jest/src/index.js +2 -0
  48. package/packages/datadog-plugin-jest/src/util.js +2 -0
  49. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -0
  50. package/packages/datadog-plugin-langchain/src/tracing.js +36 -4
  51. package/packages/datadog-plugin-nyc/src/index.js +2 -0
  52. package/packages/datadog-plugin-openai/src/stream-helpers.js +114 -0
  53. package/packages/datadog-plugin-openai/src/tracing.js +38 -0
  54. package/packages/datadog-plugin-oracledb/src/connection-parser.js +2 -0
  55. package/packages/datadog-plugin-protobufjs/src/index.js +2 -0
  56. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +2 -0
  57. package/packages/datadog-plugin-selenium/src/index.js +2 -0
  58. package/packages/datadog-plugin-vitest/src/index.js +2 -0
  59. package/packages/dd-trace/src/appsec/iast/iast-context.js +5 -1
  60. package/packages/dd-trace/src/appsec/iast/index.js +2 -0
  61. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
  62. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +0 -2
  63. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -0
  64. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +2 -0
  65. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +2 -0
  66. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +3 -3
  67. package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +18 -11
  68. package/packages/dd-trace/src/appsec/rasp/utils.js +1 -1
  69. package/packages/dd-trace/src/appsec/recommended.json +88 -2
  70. package/packages/dd-trace/src/appsec/reporter.js +7 -19
  71. package/packages/dd-trace/src/appsec/stack_trace.js +11 -11
  72. package/packages/dd-trace/src/appsec/telemetry/common.js +1 -1
  73. package/packages/dd-trace/src/appsec/waf/index.js +20 -1
  74. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +2 -2
  75. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +5 -4
  76. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -0
  77. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -1
  78. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -0
  79. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +2 -0
  80. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -0
  81. package/packages/dd-trace/src/ci-visibility/telemetry.js +2 -0
  82. package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +2 -0
  83. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +7 -3
  84. package/packages/dd-trace/src/config.js +4 -16
  85. package/packages/dd-trace/src/config_stable.js +2 -0
  86. package/packages/dd-trace/src/datastreams/checkpointer.js +2 -0
  87. package/packages/dd-trace/src/datastreams/context.js +2 -0
  88. package/packages/dd-trace/src/datastreams/encoding.js +2 -0
  89. package/packages/dd-trace/src/datastreams/fnv.js +2 -0
  90. package/packages/dd-trace/src/datastreams/pathway.js +11 -9
  91. package/packages/dd-trace/src/datastreams/processor.js +8 -7
  92. package/packages/dd-trace/src/datastreams/schemas/schema.js +2 -0
  93. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +45 -36
  94. package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +2 -0
  95. package/packages/dd-trace/src/datastreams/writer.js +2 -0
  96. package/packages/dd-trace/src/debugger/config.js +16 -0
  97. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +1 -1
  98. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -6
  99. package/packages/dd-trace/src/debugger/devtools_client/index.js +13 -5
  100. package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
  101. package/packages/dd-trace/src/debugger/devtools_client/log.js +19 -0
  102. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +9 -6
  103. package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -1
  104. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +1 -1
  105. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +1 -1
  106. package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -1
  107. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
  108. package/packages/dd-trace/src/debugger/index.js +48 -11
  109. package/packages/dd-trace/src/encode/tags-processors.js +2 -0
  110. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +2 -0
  111. package/packages/dd-trace/src/exporters/common/util.js +2 -0
  112. package/packages/dd-trace/src/exporters/span-stats/index.js +2 -0
  113. package/packages/dd-trace/src/exporters/span-stats/writer.js +2 -0
  114. package/packages/dd-trace/src/external-logger/src/index.js +2 -0
  115. package/packages/dd-trace/src/git_metadata_tagger.js +2 -0
  116. package/packages/dd-trace/src/git_properties.js +2 -0
  117. package/packages/dd-trace/src/guardrails/index.js +3 -4
  118. package/packages/dd-trace/src/guardrails/log.js +2 -2
  119. package/packages/dd-trace/src/guardrails/telemetry.js +16 -14
  120. package/packages/dd-trace/src/guardrails/util.js +0 -2
  121. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +2 -0
  122. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +5 -0
  123. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/tool.js +15 -0
  124. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +36 -0
  125. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +47 -4
  126. package/packages/dd-trace/src/llmobs/tagger.js +10 -1
  127. package/packages/dd-trace/src/noop/dogstatsd.js +2 -0
  128. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -0
  129. package/packages/dd-trace/src/payload-tagging/config/index.js +2 -0
  130. package/packages/dd-trace/src/payload-tagging/index.js +2 -0
  131. package/packages/dd-trace/src/payload-tagging/tagging.js +2 -0
  132. package/packages/dd-trace/src/plugins/apollo.js +2 -0
  133. package/packages/dd-trace/src/plugins/ci_plugin.js +8 -3
  134. package/packages/dd-trace/src/plugins/index.js +1 -0
  135. package/packages/dd-trace/src/plugins/util/ci.js +17 -7
  136. package/packages/dd-trace/src/plugins/util/env.js +2 -0
  137. package/packages/dd-trace/src/plugins/util/git.js +40 -5
  138. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +2 -0
  139. package/packages/dd-trace/src/plugins/util/llm.js +2 -0
  140. package/packages/dd-trace/src/plugins/util/serverless.js +2 -0
  141. package/packages/dd-trace/src/plugins/util/stacktrace.js +178 -50
  142. package/packages/dd-trace/src/plugins/util/tags.js +19 -1
  143. package/packages/dd-trace/src/plugins/util/test.js +9 -4
  144. package/packages/dd-trace/src/plugins/util/url.js +2 -0
  145. package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -0
  146. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +4 -0
  147. package/packages/dd-trace/src/profiling/profiler.js +89 -70
  148. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns.js +2 -0
  149. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +2 -0
  150. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +2 -0
  151. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +2 -0
  152. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +2 -0
  153. package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +2 -0
  154. package/packages/dd-trace/src/profiling/profilers/event_plugins/fs.js +2 -0
  155. package/packages/dd-trace/src/profiling/profilers/event_plugins/net.js +2 -0
  156. package/packages/dd-trace/src/profiling/profilers/events.js +2 -0
  157. package/packages/dd-trace/src/profiling/webspan-utils.js +2 -0
  158. package/packages/dd-trace/src/remote_config/capabilities.js +4 -1
  159. package/packages/dd-trace/src/remote_config/index.js +6 -0
  160. package/packages/dd-trace/src/service-naming/index.js +2 -0
  161. package/packages/dd-trace/src/service-naming/schemas/definition.js +2 -0
  162. package/packages/dd-trace/src/service-naming/schemas/util.js +2 -0
  163. package/packages/dd-trace/src/service-naming/schemas/v0/graphql.js +2 -0
  164. package/packages/dd-trace/src/service-naming/schemas/v0/index.js +2 -0
  165. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +2 -0
  166. package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +2 -0
  167. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +2 -0
  168. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -0
  169. package/packages/dd-trace/src/service-naming/schemas/v1/graphql.js +2 -0
  170. package/packages/dd-trace/src/service-naming/schemas/v1/index.js +2 -0
  171. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +2 -0
  172. package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +2 -0
  173. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +2 -0
  174. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +2 -0
  175. package/packages/dd-trace/src/span_stats.js +2 -0
  176. package/packages/dd-trace/src/supported-configurations.json +2 -0
  177. package/packages/dd-trace/src/telemetry/send-data.js +2 -0
  178. package/register.js +4 -0
  179. package/version.js +0 -3
@@ -3,7 +3,6 @@
3
3
  const dc = require('dc-polyfill')
4
4
  const zlib = require('zlib')
5
5
 
6
- const Limiter = require('../rate_limiter')
7
6
  const { storage } = require('../../../datadog-core')
8
7
  const web = require('../plugins/util/web')
9
8
  const { ipHeaderList } = require('../plugins/util/ip_extractor')
@@ -15,7 +14,6 @@ const {
15
14
  updateWafRequestsMetricTags,
16
15
  updateRaspRequestsMetricTags,
17
16
  updateRaspRuleSkippedMetricTags,
18
- updateRateLimitedMetric,
19
17
  getRequestMetrics
20
18
  } = require('./telemetry')
21
19
  const { keepTrace } = require('../priority_sampler')
@@ -31,9 +29,6 @@ const COLLECTED_REQUEST_BODY_MAX_ELEMENTS_PER_NODE = 256
31
29
 
32
30
  const telemetryLogCh = dc.channel('datadog:telemetry:log')
33
31
 
34
- // default limiter, configurable with setRateLimit()
35
- let limiter = new Limiter(100)
36
-
37
32
  const config = {
38
33
  headersExtendedCollectionEnabled: false,
39
34
  maxHeadersCollected: 0,
@@ -91,7 +86,6 @@ const NON_EXTENDED_REQUEST_HEADERS = new Set([...requestHeadersList, ...eventHea
91
86
  const NON_EXTENDED_RESPONSE_HEADERS = new Set(contentHeaderList)
92
87
 
93
88
  function init (_config) {
94
- limiter = new Limiter(_config.rateLimit)
95
89
  config.headersExtendedCollectionEnabled = _config.extendedHeadersCollection.enabled
96
90
  config.maxHeadersCollected = _config.extendedHeadersCollection.maxHeaders
97
91
  config.headersRedaction = _config.extendedHeadersCollection.redaction
@@ -325,12 +319,6 @@ function reportAttack (attackData) {
325
319
  'appsec.event': 'true'
326
320
  }
327
321
 
328
- if (limiter.isAllowed()) {
329
- keepTrace(rootSpan, ASM)
330
- } else {
331
- updateRateLimitedMetric(req)
332
- }
333
-
334
322
  // TODO: maybe add this to format.js later (to take decision as late as possible)
335
323
  if (!currentTags['_dd.origin']) {
336
324
  newTags['_dd.origin'] = 'appsec'
@@ -430,12 +418,12 @@ function isRaspAttack (events) {
430
418
  return events.some(e => e.rule?.tags?.module === 'rasp')
431
419
  }
432
420
 
433
- function isFingerprintDerivative (derivative) {
434
- return derivative.startsWith('_dd.appsec.fp')
421
+ function isSchemaAttribute (attribute) {
422
+ return attribute.startsWith('_dd.appsec.s.')
435
423
  }
436
424
 
437
- function reportDerivatives (derivatives) {
438
- if (!derivatives) return
425
+ function reportAttributes (attributes) {
426
+ if (!attributes) return
439
427
 
440
428
  const req = storage('legacy').getStore()?.req
441
429
  const rootSpan = web.root(req)
@@ -443,8 +431,8 @@ function reportDerivatives (derivatives) {
443
431
  if (!rootSpan) return
444
432
 
445
433
  const tags = {}
446
- for (let [tag, value] of Object.entries(derivatives)) {
447
- if (!isFingerprintDerivative(tag)) {
434
+ for (let [tag, value] of Object.entries(attributes)) {
435
+ if (isSchemaAttribute(tag)) {
448
436
  const gzippedValue = zlib.gzipSync(JSON.stringify(value))
449
437
  value = gzippedValue.toString('base64')
450
438
  }
@@ -543,7 +531,7 @@ module.exports = {
543
531
  reportAttack,
544
532
  reportWafUpdate: incrementWafUpdatesMetric,
545
533
  reportRaspRuleSkipped: updateRaspRuleSkippedMetricTags,
546
- reportDerivatives,
534
+ reportAttributes,
547
535
  finishRequest,
548
536
  mapHeaderAndTags,
549
537
  truncateRequestBody
@@ -9,36 +9,36 @@ const STACK_TRACE_NAMESPACES = {
9
9
  IAST: 'vulnerability'
10
10
  }
11
11
 
12
- function getCallSiteList (maxDepth = 100) {
12
+ function prepareStackTrace (_, callsites) {
13
+ return callsites
14
+ }
15
+
16
+ function getCallSiteList (maxDepth = 100, constructorOpt) {
13
17
  const previousPrepareStackTrace = Error.prepareStackTrace
14
18
  const previousStackTraceLimit = Error.stackTraceLimit
15
- let callsiteList
16
19
  // Since some frames will be discarded because they come from tracer codebase, a buffer is added
17
20
  // to the limit in order to get as close as `maxDepth` number of frames.
18
21
  Error.stackTraceLimit = maxDepth + LIBRARY_FRAMES_BUFFER
19
22
 
20
23
  try {
21
- Error.prepareStackTrace = function (_, callsites) {
22
- callsiteList = callsites
23
- }
24
- const e = new Error('message')
25
- e.stack
24
+ Error.prepareStackTrace = prepareStackTrace
25
+ const obj = {}
26
+ Error.captureStackTrace(obj, constructorOpt)
27
+ return obj.stack
26
28
  } finally {
27
29
  Error.prepareStackTrace = previousPrepareStackTrace
28
30
  Error.stackTraceLimit = previousStackTraceLimit
29
31
  }
30
-
31
- return callsiteList
32
32
  }
33
33
 
34
34
  function filterOutFramesFromLibrary (callSiteList) {
35
35
  return callSiteList.filter(callSite => !callSite.getFileName()?.startsWith(ddBasePath))
36
36
  }
37
37
 
38
- function getCallsiteFrames (maxDepth = 32, callSiteListGetter = getCallSiteList) {
38
+ function getCallsiteFrames (maxDepth = 32, constructorOpt = getCallsiteFrames, callSiteListGetter = getCallSiteList) {
39
39
  if (maxDepth < 1) maxDepth = Infinity
40
40
 
41
- const callSiteList = callSiteListGetter(maxDepth)
41
+ const callSiteList = callSiteListGetter(maxDepth, constructorOpt)
42
42
  const filteredFrames = filterOutFramesFromLibrary(callSiteList)
43
43
 
44
44
  const half = filteredFrames.length > maxDepth ? Math.round(maxDepth / 2) : Infinity
@@ -1,4 +1,4 @@
1
- 'use strinct'
1
+ 'use strict'
2
2
 
3
3
  const DD_TELEMETRY_REQUEST_METRICS = Symbol('_dd.appsec.telemetry.request.metrics')
4
4
 
@@ -3,6 +3,11 @@
3
3
  const { storage } = require('../../../../datadog-core')
4
4
  const log = require('../../log')
5
5
  const Reporter = require('../reporter')
6
+ const Limiter = require('../../rate_limiter')
7
+ const { keepTrace } = require('../../priority_sampler')
8
+ const { ASM } = require('../../standalone/product')
9
+ const web = require('../../plugins/util/web')
10
+ const { updateRateLimitedMetric } = require('../telemetry')
6
11
 
7
12
  class WafUpdateError extends Error {
8
13
  constructor (diagnosticErrors) {
@@ -12,6 +17,8 @@ class WafUpdateError extends Error {
12
17
  }
13
18
  }
14
19
 
20
+ let limiter = new Limiter(100)
21
+
15
22
  const waf = {
16
23
  wafManager: null,
17
24
  init,
@@ -27,6 +34,8 @@ const waf = {
27
34
  function init (rules, config) {
28
35
  destroy()
29
36
 
37
+ limiter = new Limiter(config.rateLimit)
38
+
30
39
  // dirty require to make startup faster for serverless
31
40
  const WAFManager = require('./waf_manager')
32
41
 
@@ -99,8 +108,18 @@ function run (data, req, raspRule) {
99
108
  }
100
109
 
101
110
  const wafContext = waf.wafManager.getWAFContext(req)
111
+ const result = wafContext.run(data, raspRule)
112
+
113
+ if (result?.keep) {
114
+ if (limiter.isAllowed()) {
115
+ const rootSpan = web.root(req)
116
+ keepTrace(rootSpan, ASM)
117
+ } else {
118
+ updateRateLimitedMetric(req)
119
+ }
120
+ }
102
121
 
103
- return wafContext.run(data, raspRule)
122
+ return result
104
123
  }
105
124
 
106
125
  function disposeContext (req) {
@@ -135,7 +135,7 @@ class WAFContextWrapper {
135
135
  this.setUserIdCache(userId, result)
136
136
  }
137
137
 
138
- metrics.duration = result.totalRuntime / 1e3
138
+ metrics.duration = result.duration / 1e3
139
139
  metrics.blockTriggered = blockTriggered
140
140
  metrics.ruleTriggered = ruleTriggered
141
141
  metrics.wafTimeout = result.timeout
@@ -144,7 +144,7 @@ class WAFContextWrapper {
144
144
  Reporter.reportAttack(result.events)
145
145
  }
146
146
 
147
- Reporter.reportDerivatives(result.derivatives)
147
+ Reporter.reportAttributes(result.attributes)
148
148
 
149
149
  return result
150
150
  } catch (err) {
@@ -5,6 +5,7 @@ const { Worker, threadId: parentThreadId } = require('worker_threads')
5
5
  const { randomUUID } = require('crypto')
6
6
  const log = require('../../log')
7
7
  const { getEnvironmentVariables } = require('../../config-helper')
8
+ const getDebuggerConfig = require('../../debugger/config')
8
9
 
9
10
  const probeIdToResolveBreakpointSet = new Map()
10
11
  const probeIdToResolveBreakpointRemove = new Map()
@@ -62,7 +63,7 @@ class TestVisDynamicInstrumentation {
62
63
 
63
64
  log.debug('Starting Test Visibility - Dynamic Instrumentation client...')
64
65
 
65
- const rcChannel = new MessageChannel() // mock channel
66
+ const probeChannel = new MessageChannel() // mock channel
66
67
  const configChannel = new MessageChannel() // mock channel
67
68
 
68
69
  this.worker = new Worker(
@@ -82,16 +83,16 @@ class TestVisDynamicInstrumentation {
82
83
  DD_INSTRUMENTATION_TELEMETRY_ENABLED: 'false'
83
84
  },
84
85
  workerData: {
85
- config: this._config.serialize(),
86
+ config: getDebuggerConfig(this._config),
86
87
  parentThreadId,
87
- rcPort: rcChannel.port1,
88
+ probePort: probeChannel.port1,
88
89
  configPort: configChannel.port1,
89
90
  breakpointSetChannel: this.breakpointSetChannel.port1,
90
91
  breakpointHitChannel: this.breakpointHitChannel.port1,
91
92
  breakpointRemoveChannel: this.breakpointRemoveChannel.port1
92
93
  },
93
94
  transferList: [
94
- rcChannel.port1,
95
+ probeChannel.port1,
95
96
  configChannel.port1,
96
97
  this.breakpointSetChannel.port1,
97
98
  this.breakpointHitChannel.port1,
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const request = require('../../exporters/common/request')
2
4
  const id = require('../../id')
3
5
  const log = require('../../log')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const fs = require('fs')
2
4
  const path = require('path')
3
5
 
@@ -287,7 +289,7 @@ function sendGitMetadata (url, { isEvpProxy, evpProxyPrefix }, configRepositoryU
287
289
  // Otherwise we unshallow and get commits to upload again
288
290
  log.debug('It is shallow clone, unshallowing...')
289
291
  if (!isFalse(getEnvironmentVariable('DD_CIVISIBILITY_GIT_UNSHALLOW_ENABLED'))) {
290
- unshallowRepository()
292
+ unshallowRepository(false)
291
293
  }
292
294
 
293
295
  // The latest commits change after unshallowing
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const request = require('../../exporters/common/request')
2
4
  const log = require('../../log')
3
5
  const { getEnvironmentVariable } = require('../../config-helper')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const Plugin = require('../../plugins/plugin')
2
4
  const log = require('../../log')
3
5
  const { getEnvironmentVariable } = require('../../config-helper')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const request = require('../../exporters/common/request')
2
4
  const id = require('../../id')
3
5
  const log = require('../../log')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const telemetryMetrics = require('../telemetry/metrics')
2
4
 
3
5
  const ciVisibilityMetrics = telemetryMetrics.manager.namespace('civisibility')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const CiPlugin = require('../../plugins/ci_plugin')
2
4
  const {
3
5
  TEST_STATUS,
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const request = require('../../exporters/common/request')
2
4
  const id = require('../../id')
3
5
  const { getEnvironmentVariable } = require('../../config-helper')
@@ -9,7 +11,9 @@ function getTestManagementTests ({
9
11
  isGzipCompatible,
10
12
  repositoryUrl,
11
13
  commitMessage,
12
- sha
14
+ sha,
15
+ commitHeadSha,
16
+ commitHeadMessage
13
17
  }, done) {
14
18
  const options = {
15
19
  path: '/api/v2/test/libraries/test-management/tests',
@@ -43,8 +47,8 @@ function getTestManagementTests ({
43
47
  type: 'ci_app_libraries_tests_request',
44
48
  attributes: {
45
49
  repository_url: repositoryUrl,
46
- commit_message: commitMessage,
47
- sha
50
+ commit_message: commitHeadMessage || commitMessage,
51
+ sha: commitHeadSha || sha
48
52
  }
49
53
  }
50
54
  })
@@ -516,6 +516,7 @@ class Config {
516
516
  defaults['dogstatsd.port'] = '8125'
517
517
  defaults.dsmEnabled = false
518
518
  defaults['dynamicInstrumentation.enabled'] = false
519
+ defaults['dynamicInstrumentation.probeFile'] = undefined
519
520
  defaults['dynamicInstrumentation.redactedIdentifiers'] = []
520
521
  defaults['dynamicInstrumentation.redactionExcludedIdentifiers'] = []
521
522
  defaults['dynamicInstrumentation.uploadIntervalSeconds'] = 1
@@ -707,6 +708,7 @@ class Config {
707
708
  DD_DOGSTATSD_HOST,
708
709
  DD_DOGSTATSD_PORT,
709
710
  DD_DYNAMIC_INSTRUMENTATION_ENABLED,
711
+ DD_DYNAMIC_INSTRUMENTATION_PROBE_FILE,
710
712
  DD_DYNAMIC_INSTRUMENTATION_REDACTED_IDENTIFIERS,
711
713
  DD_DYNAMIC_INSTRUMENTATION_REDACTION_EXCLUDED_IDENTIFIERS,
712
714
  DD_DYNAMIC_INSTRUMENTATION_UPLOAD_INTERVAL_SECONDS,
@@ -883,6 +885,7 @@ class Config {
883
885
  this._setString(env, 'dogstatsd.port', DD_DOGSTATSD_PORT)
884
886
  this._setBoolean(env, 'dsmEnabled', DD_DATA_STREAMS_ENABLED)
885
887
  this._setBoolean(env, 'dynamicInstrumentation.enabled', DD_DYNAMIC_INSTRUMENTATION_ENABLED)
888
+ this._setString(env, 'dynamicInstrumentation.probeFile', DD_DYNAMIC_INSTRUMENTATION_PROBE_FILE)
886
889
  this._setArray(env, 'dynamicInstrumentation.redactedIdentifiers', DD_DYNAMIC_INSTRUMENTATION_REDACTED_IDENTIFIERS)
887
890
  this._setArray(
888
891
  env,
@@ -1108,6 +1111,7 @@ class Config {
1108
1111
  }
1109
1112
  this._setBoolean(opts, 'dsmEnabled', options.dsmEnabled)
1110
1113
  this._setBoolean(opts, 'dynamicInstrumentation.enabled', options.dynamicInstrumentation?.enabled)
1114
+ this._setString(opts, 'dynamicInstrumentation.probeFile', options.dynamicInstrumentation?.probeFile)
1111
1115
  this._setArray(
1112
1116
  opts,
1113
1117
  'dynamicInstrumentation.redactedIdentifiers',
@@ -1542,22 +1546,6 @@ class Config {
1542
1546
  }
1543
1547
  }
1544
1548
  }
1545
-
1546
- // TODO: Refactor the Config class so it never produces any config objects that are incompatible with MessageChannel
1547
- /**
1548
- * Serializes the config object so it can be passed over a Worker Thread MessageChannel.
1549
- * @returns {Object} The serialized config object.
1550
- */
1551
- serialize () {
1552
- // URL objects cannot be serialized over the MessageChannel, so we need to convert them to strings first
1553
- if (this.url instanceof URL) {
1554
- const config = { ...this }
1555
- config.url = this.url.toString()
1556
- return config
1557
- }
1558
-
1559
- return this
1560
- }
1561
1549
  }
1562
1550
 
1563
1551
  function handleOtel (tagString) {
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const os = require('os')
2
4
  const fs = require('fs')
3
5
  const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const DataStreamsContext = require('./context')
2
4
 
3
5
  class DataStreamsCheckpointer {
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { storage } = require('../../../datadog-core')
2
4
  const log = require('../log')
3
5
 
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  // encodes positive and negative numbers, using zig zag encoding to reduce the size of the variable length encoding.
2
4
  // uses high and low part to ensure those parts are under the limit for byte operations in javascript (32 bits)
3
5
  // maximum number possible to encode is MAX_SAFE_INTEGER/2 (using zig zag shifts the bits by 1 to the left)
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const FNV_64_PRIME = BigInt('0x100000001B3')
2
4
  const FNV1_64_INIT = BigInt('0xCBF29CE484222325')
3
5
 
@@ -1,14 +1,15 @@
1
+ 'use strict'
2
+
1
3
  // encoding used here is sha256
2
4
  // other languages use FNV1
3
5
  // this inconsistency is ok because hashes do not need to be consistent across services
4
6
  const crypto = require('crypto')
5
7
  const { encodeVarint, decodeVarint } = require('./encoding')
6
- const LRUCache = require('lru-cache')
8
+ const { LRUCache } = require('lru-cache')
7
9
  const log = require('../log')
8
10
  const pick = require('../../../datadog-core/src/utils/src/pick')
9
11
 
10
- const options = { max: 500 }
11
- const cache = new LRUCache(options)
12
+ const cache = new LRUCache({ max: 500 })
12
13
 
13
14
  const CONTEXT_PROPAGATION_KEY = 'dd-pathway-ctx'
14
15
  const CONTEXT_PROPAGATION_KEY_BASE64 = 'dd-pathway-ctx-base64'
@@ -24,15 +25,16 @@ function computeHash (service, env, edgeTags, parentHash) {
24
25
  edgeTags.sort()
25
26
  const hashableEdgeTags = edgeTags.filter(item => item !== 'manual_checkpoint:true')
26
27
 
27
- const key = `${service}${env}` + hashableEdgeTags.join('') + parentHash.toString()
28
- if (cache.get(key)) {
29
- return cache.get(key)
28
+ const key = `${service}${env}${hashableEdgeTags.join('')}${parentHash}`
29
+ let value = cache.get(key)
30
+ if (value) {
31
+ return value
30
32
  }
31
33
  const currentHash = shaHash(`${service}${env}` + hashableEdgeTags.join(''))
32
34
  const buf = Buffer.concat([currentHash, parentHash], 16)
33
- const val = shaHash(buf.toString())
34
- cache.set(key, val)
35
- return val
35
+ value = shaHash(buf.toString())
36
+ cache.set(key, value)
37
+ return value
36
38
  }
37
39
 
38
40
  function encodePathwayContext (dataStreamsContext) {
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const os = require('os')
2
4
  const pkg = require('../../../../package.json')
3
5
 
@@ -78,15 +80,14 @@ class StatsBucket {
78
80
  return this._backlogs
79
81
  }
80
82
 
81
- forCheckpoint (checkpoint) {
82
- const key = checkpoint.hash
83
- if (!this._checkpoints.has(key)) {
84
- this._checkpoints.set(
85
- key, new StatsPoint(checkpoint.hash, checkpoint.parentHash, checkpoint.edgeTags)
86
- )
83
+ forCheckpoint ({ hash, parentHash, edgeTags }) {
84
+ let checkpoint = this._checkpoints.get(hash)
85
+ if (!checkpoint) {
86
+ checkpoint = new StatsPoint(hash, parentHash, edgeTags)
87
+ this._checkpoints.set(hash, checkpoint)
87
88
  }
88
89
 
89
- return this._checkpoints.get(key)
90
+ return checkpoint
90
91
  }
91
92
 
92
93
  /**
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  class Schema {
2
4
  constructor (definition, id) {
3
5
  this.definition = definition
@@ -1,4 +1,6 @@
1
- const LRUCache = require('lru-cache')
1
+ 'use strict'
2
+
3
+ const { LRUCache } = require('lru-cache')
2
4
  const { fnv64 } = require('../fnv')
3
5
  const { Schema } = require('./schema')
4
6
 
@@ -13,22 +15,24 @@ class SchemaBuilder {
13
15
  this.properties = 0
14
16
  }
15
17
 
18
+ // TODO: This is only used in tests. Let's refactor the code and stop exposing the cache.
16
19
  static getCache () {
17
20
  return CACHE
18
21
  }
19
22
 
20
23
  static getSchemaDefinition (schema) {
21
- const noNones = convertToJsonCompatible(schema)
22
- const definition = jsonStringify(noNones)
24
+ const definition = toJSON(schema)
23
25
  const id = fnv64(Buffer.from(definition, 'utf8')).toString()
24
26
  return new Schema(definition, id)
25
27
  }
26
28
 
27
29
  static getSchema (schemaName, iterator, builder) {
28
- if (!CACHE.has(schemaName)) {
29
- CACHE.set(schemaName, (builder ?? new SchemaBuilder(iterator)).build())
30
+ let entry = CACHE.get(schemaName)
31
+ if (!entry) {
32
+ entry = (builder ?? new SchemaBuilder(iterator)).build()
33
+ CACHE.set(schemaName, entry)
30
34
  }
31
- return CACHE.get(schemaName)
35
+ return entry
32
36
  }
33
37
 
34
38
  build () {
@@ -92,42 +96,47 @@ class OpenApiComponents {
92
96
  }
93
97
  }
94
98
 
95
- function convertToJsonCompatible (obj) {
96
- if (Array.isArray(obj)) {
97
- return obj.filter(item => item !== null).map(item => convertToJsonCompatible(item))
98
- } else if (obj && typeof obj === 'object') {
99
- const jsonObj = {}
100
- for (const [key, value] of Object.entries(obj)) {
101
- if (value !== null) {
102
- jsonObj[key] = convertToJsonCompatible(value)
99
+ // This adds a single whitespace between entries without adding newlines.
100
+ // This differs from JSON.stringify and is used to align with the output
101
+ // in other platforms.
102
+ // TODO: Add tests to verify this behavior. A couple of cases are not
103
+ // covered by the existing tests.
104
+ function toJSON (value) {
105
+ // eslint-disable-next-line eslint-rules/eslint-safe-typeof-object
106
+ if (typeof value === 'object') {
107
+ if (value === null) {
108
+ return 'null'
109
+ }
110
+ if (Array.isArray(value)) {
111
+ let result = '['
112
+ for (let i = 0; i < value.length; i++) {
113
+ if (value[i] !== null) {
114
+ if (i !== 0) {
115
+ result += ', '
116
+ }
117
+ result += value[i] === undefined ? 'null' : toJSON(value[i])
118
+ }
103
119
  }
120
+ return `${result}]`
104
121
  }
105
- return jsonObj
106
- }
107
- return obj
108
- }
109
-
110
- function convertKey (key) {
111
- if (key === 'enumValues') {
112
- return 'enum'
122
+ let result = '{'
123
+ for (const [key, objectValue] of Object.entries(value)) {
124
+ if (objectValue != null && typeof key === 'string') {
125
+ const converted = toJSON(objectValue)
126
+ if (converted !== undefined) {
127
+ if (result !== '{') {
128
+ result += ', '
129
+ }
130
+ result += `"${key}": ${converted}`
131
+ }
132
+ }
133
+ }
134
+ return `${result}}`
113
135
  }
114
- return key
115
- }
116
-
117
- function jsonStringify (obj, indent = 2) {
118
- // made to stringify json exactly similar to python / java in order for hashing to be the same
119
- const jsonString = JSON.stringify(obj, (_, value) => value, indent)
120
- return jsonString.replaceAll(/^ +/gm, ' ') // Replace leading spaces with single space
121
- .replaceAll('\n', '') // Remove newlines
122
- .replaceAll('{ ', '{') // Remove space after '{'
123
- .replaceAll(' }', '}') // Remove space before '}'
124
- .replaceAll('[ ', '[') // Remove space after '['
125
- .replaceAll(' ]', ']') // Remove space before ']'
136
+ return JSON.stringify(value)
126
137
  }
127
138
 
128
139
  module.exports = {
129
140
  SchemaBuilder,
130
141
  OpenApiSchema,
131
- convertToJsonCompatible,
132
- convertKey
133
142
  }
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const SAMPLE_INTERVAL_MILLIS = 30 * 1000
2
4
 
3
5
  class SchemaSampler {
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const pkg = require('../../../../package.json')
2
4
  const log = require('../log')
3
5
  const request = require('../exporters/common/request')
@@ -0,0 +1,16 @@
1
+ 'use strict'
2
+
3
+ module.exports = function getDebuggerConfig (config) {
4
+ return {
5
+ commitSHA: config.commitSHA,
6
+ debug: config.debug,
7
+ dynamicInstrumentation: config.dynamicInstrumentation,
8
+ hostname: config.hostname,
9
+ logLevel: config.logLevel,
10
+ port: config.port,
11
+ repositoryUrl: config.repositoryUrl,
12
+ runtimeId: config.tags['runtime-id'],
13
+ service: config.service,
14
+ url: config.url?.toString(),
15
+ }
16
+ }
@@ -12,7 +12,7 @@ const {
12
12
  breakpointToProbes,
13
13
  probeToLocation
14
14
  } = require('./state')
15
- const log = require('../../log')
15
+ const log = require('./log')
16
16
 
17
17
  let sessionStarted = false
18
18
  const probes = new Map()