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
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  /**
2
4
  * @import { DogStatsD } from "../../../../index.d.ts"
3
5
  * @implements {DogStatsD}
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const pick = require('../../../../datadog-core/src/utils/src/pick')
2
4
  const log = require('../../log')
3
5
 
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const aws = require('./aws.json')
2
4
  const sdks = { aws }
3
5
 
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const rfdc = require('rfdc')({ proto: false, circles: false })
2
4
 
3
5
  const {
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { PAYLOAD_TAGGING_MAX_TAGS } = require('../constants')
2
4
 
3
5
  const redactedKeys = new Set([
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const TracingPlugin = require('./tracing')
2
4
  const { storage } = require('../../../datadog-core')
3
5
 
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { storage } = require('../../../datadog-core')
2
4
  const {
3
5
  getTestEnvironmentMetadata,
@@ -53,7 +55,8 @@ const {
53
55
  GIT_TAG,
54
56
  GIT_PULL_REQUEST_BASE_BRANCH_SHA,
55
57
  GIT_COMMIT_HEAD_SHA,
56
- GIT_PULL_REQUEST_BASE_BRANCH
58
+ GIT_PULL_REQUEST_BASE_BRANCH,
59
+ GIT_COMMIT_HEAD_MESSAGE
57
60
  } = require('./util/tags')
58
61
  const { OS_VERSION, OS_PLATFORM, OS_ARCHITECTURE, RUNTIME_NAME, RUNTIME_VERSION } = require('./util/env')
59
62
  const getDiClient = require('../ci-visibility/dynamic-instrumentation')
@@ -311,7 +314,8 @@ module.exports = class CiPlugin extends Plugin {
311
314
  [GIT_COMMIT_MESSAGE]: commitMessage,
312
315
  [GIT_TAG]: tag,
313
316
  [GIT_PULL_REQUEST_BASE_BRANCH_SHA]: pullRequestBaseSha,
314
- [GIT_COMMIT_HEAD_SHA]: commitHeadSha
317
+ [GIT_COMMIT_HEAD_SHA]: commitHeadSha,
318
+ [GIT_COMMIT_HEAD_MESSAGE]: commitHeadMessage
315
319
  } = this.testEnvironmentMetadata
316
320
 
317
321
  this.repositoryRoot = repositoryRoot || process.cwd()
@@ -333,7 +337,8 @@ module.exports = class CiPlugin extends Plugin {
333
337
  commitMessage,
334
338
  tag,
335
339
  pullRequestBaseSha,
336
- commitHeadSha
340
+ commitHeadSha,
341
+ commitHeadMessage
337
342
  }
338
343
  }
339
344
 
@@ -45,6 +45,7 @@ module.exports = {
45
45
  get graphql () { return require('../../../datadog-plugin-graphql/src') },
46
46
  get grpc () { return require('../../../datadog-plugin-grpc/src') },
47
47
  get hapi () { return require('../../../datadog-plugin-hapi/src') },
48
+ get hono () { return require('../../../datadog-plugin-hono/src') },
48
49
  get http () { return require('../../../datadog-plugin-http/src') },
49
50
  get http2 () { return require('../../../datadog-plugin-http2/src') },
50
51
  get https () { return require('../../../datadog-plugin-http/src') },
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { readFileSync } = require('fs')
2
4
  const {
3
5
  GIT_BRANCH,
@@ -25,7 +27,8 @@ const {
25
27
  GIT_COMMIT_COMMITTER_EMAIL,
26
28
  CI_NODE_LABELS,
27
29
  CI_NODE_NAME,
28
- PR_NUMBER
30
+ PR_NUMBER,
31
+ CI_JOB_ID
29
32
  } = require('./tags')
30
33
  const { filterSensitiveInfoFromRepository } = require('./url')
31
34
  const { getEnvironmentVariable, getEnvironmentVariables } = require('../../config-helper')
@@ -208,7 +211,8 @@ module.exports = {
208
211
  [CI_NODE_LABELS]: CI_RUNNER_TAGS,
209
212
  [CI_NODE_NAME]: CI_RUNNER_ID,
210
213
  [GIT_PULL_REQUEST_BASE_BRANCH]: CI_MERGE_REQUEST_TARGET_BRANCH_NAME,
211
- [PR_NUMBER]: CI_MERGE_REQUEST_IID
214
+ [PR_NUMBER]: CI_MERGE_REQUEST_IID,
215
+ [CI_JOB_ID]: GITLAB_CI_JOB_ID
212
216
  }
213
217
  }
214
218
 
@@ -245,7 +249,8 @@ module.exports = {
245
249
  CIRCLE_WORKFLOW_ID,
246
250
  CIRCLE_BUILD_NUM,
247
251
  }),
248
- [PR_NUMBER]: CIRCLE_PR_NUMBER
252
+ [PR_NUMBER]: CIRCLE_PR_NUMBER,
253
+ [CI_JOB_ID]: CIRCLE_BUILD_NUM
249
254
  }
250
255
  }
251
256
 
@@ -296,7 +301,8 @@ module.exports = {
296
301
  GITHUB_REPOSITORY,
297
302
  GITHUB_RUN_ID,
298
303
  GITHUB_RUN_ATTEMPT
299
- })
304
+ }),
305
+ [CI_JOB_ID]: GITHUB_JOB
300
306
  }
301
307
  if (GITHUB_BASE_REF) { // `pull_request` or `pull_request_target` event
302
308
  tags[GIT_PULL_REQUEST_BASE_BRANCH] = GITHUB_BASE_REF
@@ -405,7 +411,8 @@ module.exports = {
405
411
  [CI_JOB_NAME]: SYSTEM_JOBDISPLAYNAME,
406
412
  [CI_ENV_VARS]: JSON.stringify({ SYSTEM_TEAMPROJECTID, BUILD_BUILDID, SYSTEM_JOBID }),
407
413
  [PR_NUMBER]: SYSTEM_PULLREQUEST_PULLREQUESTNUMBER,
408
- [GIT_PULL_REQUEST_BASE_BRANCH]: SYSTEM_PULLREQUEST_TARGETBRANCH
414
+ [GIT_PULL_REQUEST_BASE_BRANCH]: SYSTEM_PULLREQUEST_TARGETBRANCH,
415
+ [CI_JOB_ID]: SYSTEM_JOBID
409
416
  }
410
417
 
411
418
  if (SYSTEM_TEAMFOUNDATIONSERVERURI && SYSTEM_TEAMPROJECTID && BUILD_BUILDID) {
@@ -508,7 +515,8 @@ module.exports = {
508
515
  BUILDKITE_MESSAGE,
509
516
  BUILDKITE_AGENT_ID,
510
517
  BUILDKITE_PULL_REQUEST,
511
- BUILDKITE_PULL_REQUEST_BASE_BRANCH
518
+ BUILDKITE_PULL_REQUEST_BASE_BRANCH,
519
+ BUILDKITE_CI_JOB_ID
512
520
  } = env
513
521
 
514
522
  const extraTags = Object.keys(env).filter(envVar =>
@@ -540,6 +548,7 @@ module.exports = {
540
548
  [CI_NODE_NAME]: BUILDKITE_AGENT_ID,
541
549
  [CI_NODE_LABELS]: JSON.stringify(extraTags),
542
550
  [PR_NUMBER]: BUILDKITE_PULL_REQUEST,
551
+ [CI_JOB_ID]: BUILDKITE_CI_JOB_ID
543
552
  }
544
553
 
545
554
  if (BUILDKITE_PULL_REQUEST) {
@@ -680,7 +689,8 @@ module.exports = {
680
689
  CODEBUILD_BUILD_ARN,
681
690
  DD_PIPELINE_EXECUTION_ID,
682
691
  DD_ACTION_EXECUTION_ID
683
- })
692
+ }),
693
+ [CI_JOB_ID]: DD_ACTION_EXECUTION_ID
684
694
  }
685
695
  }
686
696
 
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const os = require('os')
2
4
 
3
5
  const OS_PLATFORM = 'os.platform'
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const cp = require('child_process')
2
4
  const os = require('os')
3
5
  const path = require('path')
@@ -16,7 +18,14 @@ const {
16
18
  GIT_COMMIT_AUTHOR_DATE,
17
19
  GIT_COMMIT_AUTHOR_EMAIL,
18
20
  GIT_COMMIT_AUTHOR_NAME,
19
- CI_WORKSPACE_PATH
21
+ CI_WORKSPACE_PATH,
22
+ GIT_COMMIT_HEAD_AUTHOR_DATE,
23
+ GIT_COMMIT_HEAD_AUTHOR_EMAIL,
24
+ GIT_COMMIT_HEAD_AUTHOR_NAME,
25
+ GIT_COMMIT_HEAD_COMMITTER_DATE,
26
+ GIT_COMMIT_HEAD_COMMITTER_EMAIL,
27
+ GIT_COMMIT_HEAD_COMMITTER_NAME,
28
+ GIT_COMMIT_HEAD_MESSAGE
20
29
  } = require('./tags')
21
30
  const {
22
31
  incrementCountMetric,
@@ -117,7 +126,7 @@ function getGitVersion () {
117
126
  }
118
127
  }
119
128
 
120
- function unshallowRepository () {
129
+ function unshallowRepository (parentOnly = false) {
121
130
  const gitVersion = getGitVersion()
122
131
  if (!gitVersion) {
123
132
  log.warn('Git version could not be extracted, so git unshallow will not proceed')
@@ -132,7 +141,7 @@ function unshallowRepository () {
132
141
 
133
142
  const baseGitOptions = [
134
143
  'fetch',
135
- '--shallow-since="1 month ago"',
144
+ parentOnly ? '--deepen=1' : '--shallow-since="1 month ago"',
136
145
  '--update-shallow',
137
146
  '--filter=blob:none',
138
147
  '--recurse-submodules=no',
@@ -451,7 +460,8 @@ function getGitMetadata (ciMetadata) {
451
460
  commitMessage,
452
461
  authorName: ciAuthorName,
453
462
  authorEmail: ciAuthorEmail,
454
- ciWorkspacePath
463
+ ciWorkspacePath,
464
+ headCommitSha
455
465
  } = ciMetadata
456
466
 
457
467
  // With stdio: 'pipe', errors in this command will not be output to the parent process,
@@ -470,7 +480,32 @@ function getGitMetadata (ciMetadata) {
470
480
  commitMessage || sanitizedExec('git', ['show', '-s', '--format=%B'], null, null, null, false),
471
481
  [GIT_BRANCH]: branch || sanitizedExec('git', ['rev-parse', '--abbrev-ref', 'HEAD']),
472
482
  [GIT_COMMIT_SHA]: commitSHA || sanitizedExec('git', ['rev-parse', 'HEAD']),
473
- [CI_WORKSPACE_PATH]: ciWorkspacePath || sanitizedExec('git', ['rev-parse', '--show-toplevel'])
483
+ [CI_WORKSPACE_PATH]: ciWorkspacePath || sanitizedExec('git', ['rev-parse', '--show-toplevel']),
484
+ }
485
+
486
+ if (headCommitSha) {
487
+ if (isShallowRepository()) {
488
+ unshallowRepository(true)
489
+ }
490
+
491
+ tags[GIT_COMMIT_HEAD_MESSAGE] =
492
+ sanitizedExec('git', ['show', '-s', '--format=%B', headCommitSha], null, null, null, false)
493
+
494
+ const [
495
+ headAuthorName,
496
+ headAuthorEmail,
497
+ headAuthorDate,
498
+ headCommitterName,
499
+ headCommitterEmail,
500
+ headCommitterDate
501
+ ] = sanitizedExec('git', ['show', '-s', '--format=%an,%ae,%aI,%cn,%ce,%cI', headCommitSha]).split(',')
502
+
503
+ tags[GIT_COMMIT_HEAD_AUTHOR_DATE] = headAuthorDate
504
+ tags[GIT_COMMIT_HEAD_AUTHOR_EMAIL] = headAuthorEmail
505
+ tags[GIT_COMMIT_HEAD_AUTHOR_NAME] = headAuthorName
506
+ tags[GIT_COMMIT_HEAD_COMMITTER_DATE] = headCommitterDate
507
+ tags[GIT_COMMIT_HEAD_COMMITTER_EMAIL] = headCommitterEmail
508
+ tags[GIT_COMMIT_HEAD_COMMITTER_NAME] = headCommitterName
474
509
  }
475
510
 
476
511
  const entries = [
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const log = require('../../log')
2
4
  const tags = require('../../../../../ext/tags')
3
5
 
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const Sampler = require('../../sampler')
2
4
 
3
5
  const RE_NEWLINE = /\n/g
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const types = require('../../../../../ext/types')
2
4
  const web = require('./web')
3
5
 
@@ -1,12 +1,15 @@
1
1
  'use strict'
2
2
 
3
- const { relative, sep, isAbsolute } = require('path')
3
+ const { relative, sep } = require('path')
4
4
 
5
5
  const cwd = process.cwd()
6
6
 
7
+ const NODE_MODULES_PATTERN_MIDDLE = `${sep}node_modules${sep}`
8
+ const NODE_MODULES_PATTERN_START = `node_modules${sep}`
9
+
7
10
  module.exports = {
8
11
  getCallSites,
9
- getUserLandFrames
12
+ parseUserLandFrames
10
13
  }
11
14
 
12
15
  // From https://github.com/felixge/node-stack-trace/blob/ba06dcdb50d465cd440d84a563836e293b360427/index.js#L1
@@ -32,70 +35,195 @@ function getCallSites (constructorOpt) {
32
35
  /**
33
36
  * Get stack trace of user-land frames.
34
37
  *
35
- * @param {Function} constructorOpt - Function to pass along to Error.captureStackTrace
38
+ * @param {string} stack - The stack trace to parse
36
39
  * @param {number} [limit=Infinity] - The maximum number of frames to return
37
40
  * @returns {StackFrame[]} - A list of stack frames from user-land code
41
+ */
42
+ function parseUserLandFrames (stack, limit = Infinity) {
43
+ let index = stack.indexOf('\n at ')
44
+ const frames = []
45
+
46
+ while (index !== -1 && frames.length !== limit) {
47
+ const nextIndex = stack.indexOf('\n', index + 1)
48
+ const frame = parseLine(stack, index, nextIndex === -1 ? stack.length : nextIndex)
49
+ if (frame !== undefined) frames.push(frame)
50
+ index = nextIndex
51
+ }
52
+
53
+ return frames
54
+ }
55
+
56
+ /**
57
+ * Parses a line of the stack trace and returns the parsed frame if it is a user-land frame.
58
+ * Returns `undefined` otherwise.
59
+ *
60
+ * @param {string} stack - The stack trace in which the line is located.
61
+ * @param {number} start - The start index of the line to parse within the stack trace.
62
+ * @param {number} end - The end index of the line to parse within the stack trace.
63
+ * @returns {StackFrame|undefined} The parsed frame if it is a user frame, `undefined` otherwise.
38
64
  *
39
65
  * @typedef {Object} StackFrame
40
- * @property {string} file - The file path of the frame
41
- * @property {number} line - The line number in the file
42
- * @property {number} column - The column number in the file
43
- * @property {string} [method] - The function name, if available
44
- * @property {string} [type] - The type name, if available
66
+ * @property {string} fileName - The file name of the frame.
67
+ * @property {string} lineNumber - The line number of the frame.
68
+ * @property {string} columnNumber - The column number of the frame.
69
+ * @property {string} [functionName] - The function name of the frame.
70
+ * @property {string} [methodName] - The method name of the frame.
71
+ * @property {string} [typeName] - The type name of the frame.
45
72
  */
46
- function getUserLandFrames (constructorOpt, limit = Infinity) {
47
- const callsites = getCallSites(constructorOpt)
48
- const frames = []
73
+ function parseLine (stack, start, end) {
74
+ let index
75
+ if (stack[end - 1] === ')') {
76
+ index = end - 2 // skip the last closing parenthesis
77
+ const code = stack.charCodeAt(index)
78
+ if (code < 0x30 || code > 0x39) return // not a digit
79
+ } else {
80
+ index = end - 1
81
+ }
49
82
 
50
- for (const callsite of callsites) {
51
- if (callsite.isNative()) {
52
- continue
83
+ start += 8 // skip the `\n at ` prefix
84
+ if (stack.startsWith('new ', start)) start += 4 // skip `new `
85
+ else if (stack.startsWith('async ', start)) start += 6 // skip `async `
86
+
87
+ let fileName, lineNumber, columnNumber
88
+ const result = parseLocation(stack, start, index)
89
+ if (result === undefined) return
90
+ [fileName, lineNumber, columnNumber, index] = result
91
+
92
+ if (isNodeModulesFrame(fileName)) return
93
+
94
+ // parse method name
95
+ let methodName, functionName
96
+ if (stack[index] === ']') {
97
+ methodName = ''
98
+ index-- // skip the closing square bracket
99
+ for (; index >= start; index--) {
100
+ const char = stack[index]
101
+ if (char === ' ' && stack.slice(index - 4, index) === ' [as') {
102
+ // The space after `[as` in `[as Foo]`
103
+ index -= 4 // skip ` [as`
104
+ break
105
+ } else if (char === '[') {
106
+ // This isn't a method name after all, but probably a symbol
107
+ functionName = `${stack.slice(start, index)}[${methodName}]`
108
+ methodName = undefined
109
+ break
110
+ }
111
+ methodName = char + methodName
53
112
  }
113
+ index-- // skip the opening square bracket
114
+ }
54
115
 
55
- const filename = callsite.getFileName()
56
-
57
- // If the callsite is native, there will be no associated filename. However, there might be other instances where
58
- // this can happen, so to be sure, we add this additional check
59
- if (filename === null) {
60
- continue
116
+ // parse function and type name
117
+ functionName ??= start <= index ? stack.slice(start, index + 1) : undefined
118
+ let typeName
119
+ if (functionName !== undefined && functionName[0] !== '[') {
120
+ const periodIndex = functionName.indexOf('.')
121
+ if (periodIndex !== -1) {
122
+ typeName = functionName.slice(0, periodIndex)
123
+ functionName = functionName.slice(periodIndex + 1)
61
124
  }
125
+ }
126
+
127
+ return {
128
+ lineNumber,
129
+ columnNumber,
130
+ fileName,
131
+ methodName,
132
+ functionName,
133
+ typeName
134
+ }
135
+ }
136
+
137
+ // TODO: Technically, the algorithm below could be simplified to not use the relative path, but be simply:
138
+ //
139
+ // return filename.includes(NODE_MODULES_PATTERN_MIDDLE))
140
+ //
141
+ // However, if the user happens to be running this within a directory where `node_modules` is one of the parent
142
+ // directories, it will be flagged as a false positive.
143
+ function isNodeModulesFrame (fileName) {
144
+ // Quick check first - if it doesn't contain node_modules, it's not a node_modules frame
145
+ if (!fileName.includes(NODE_MODULES_PATTERN_MIDDLE)) {
146
+ return false
147
+ }
148
+
149
+ // More expensive relative path calculation only when necessary
150
+ const actualPath = fileName.startsWith('file:') ? fileName.slice(7) : fileName
151
+ const relativePath = relative(cwd, actualPath)
62
152
 
63
- // ESM module paths start with the "file://" protocol (because ESM supports https imports)
64
- // TODO: Node.js also supports `data:` and `node:` imports, should we do something specific for `data:`?
65
- const containsFileProtocol = filename.startsWith('file:')
153
+ return relativePath.startsWith(NODE_MODULES_PATTERN_START) || relativePath.includes(NODE_MODULES_PATTERN_MIDDLE)
154
+ }
66
155
 
67
- // TODO: I'm not sure how stable this check is. Alternatively, we could consider reversing it if we can get
68
- // a comprehensive list of all non-file-based values, eg:
69
- //
70
- // filename === '<anonymous>' || filename.startsWith('node:')
71
- if (containsFileProtocol === false && isAbsolute(filename) === false) {
156
+ /**
157
+ * A stack trace location can be in one of the following formats:
158
+ *
159
+ * 1. `myscript.js:10:3`
160
+ * 2. `(myscript.js:10:3`
161
+ * 3. `(eval at Foo.a (myscript.js:10:3)`
162
+ * 4. `(eval at Foo.a (myscript.js:10:3), <anonymous>:1:1`
163
+ * 5. `(eval at Foo.a (eval at Bar.z (myscript.js:10:3)`
164
+ * 6. `(eval at Foo.a (eval at Bar.z (myscript.js:10:3), <anonymous>:1:1`
165
+ *
166
+ * Notice how the optional closing parenthesis is not included in the location string at this point. It has been
167
+ * skipped to save time.
168
+ *
169
+ * This function extracts the `myscript.js:10:3` part, passes it, returns the file name, line number, and column
170
+ * number and sets the `index` to the start of the whole location string.
171
+ *
172
+ * @returns {[string, string, string, number]|undefined}
173
+ */
174
+ function parseLocation (stack, start, index) {
175
+ // parse column number
176
+ let columnNumber = ''
177
+ for (; index >= start; index--) {
178
+ const code = stack.charCodeAt(index)
179
+ if (code === 0x29) { // closing parenthesis
180
+ // e.g. `eval at Foo.a (eval at Bar.z (myscript.js:10:3))`
72
181
  continue
73
182
  }
183
+ if (code < 0x30 || code > 0x39) break // not a digit
184
+ columnNumber = stack[index] + columnNumber
185
+ }
74
186
 
75
- // TODO: Technically, the algorithm below could be simplified to not use the relative path, but be simply:
76
- //
77
- // if (filename.includes(sep + 'node_modules' + sep)) continue
78
- //
79
- // However, the tests in `packages/dd-trace/test/plugins/util/stacktrace.spec.js` will fail on my machine
80
- // because I have the source code in a parent folder called `node_modules`. So the code below thinks that
81
- // it's not in user-land
82
- const relativePath = relative(cwd, containsFileProtocol ? filename.slice(7) : filename)
83
- if (relativePath.startsWith('node_modules' + sep) || relativePath.includes(sep + 'node_modules' + sep)) {
84
- continue
187
+ index-- // skip colon
188
+
189
+ // parse line number
190
+ let lineNumber = ''
191
+ for (; index >= start; index--) {
192
+ const code = stack.charCodeAt(index)
193
+ if (code < 0x30 || code > 0x39) break // not a digit
194
+ lineNumber = stack[index] + lineNumber
195
+ }
196
+
197
+ index-- // skip colon
198
+
199
+ // parse file name
200
+ let nestedParenthesis = 1 // 1 instead of 0 because the trailing parenthesis wasn't seen by this function
201
+ let fileName = ''
202
+ for (; index >= start; index--) {
203
+ const char = stack[index]
204
+ if (char === ')') {
205
+ nestedParenthesis++
206
+ } else if (char === '(' && --nestedParenthesis === 0) {
207
+ index -= 2 // skip the opening parenthesis and the whitespace before it
208
+ break
209
+ } else if (nestedParenthesis === 1 && char === ':' && stack.slice(index - 4, index) === 'node') {
210
+ return // e.g. `node:vm:137:12` is not considered a user frame
85
211
  }
212
+ fileName = char + fileName
213
+ }
86
214
 
87
- const method = callsite.getFunctionName()
88
- const type = callsite.getTypeName()
89
- frames.push({
90
- file: filename,
91
- line: callsite.getLineNumber(),
92
- column: callsite.getColumnNumber(),
93
- method: method ?? undefined, // force to undefined if null so JSON.stringify will omit it
94
- type: type ?? undefined // force to undefined if null so JSON.stringify will omit it
95
- })
96
-
97
- if (frames.length === limit) break
215
+ if (fileName.startsWith('eval at ')) {
216
+ // The location we parsed was not the actual location, but the location inside the eval. Let's parse the nested
217
+ // location, which will be the location of the eval.
218
+ const result = parseLocation(fileName, 0, fileName.lastIndexOf(',') - 2)
219
+ if (result === undefined) return
220
+ [fileName, lineNumber, columnNumber] = result // ignore returned index, as we need to retain the original one
98
221
  }
99
222
 
100
- return frames
223
+ return [
224
+ fileName,
225
+ lineNumber,
226
+ columnNumber,
227
+ index // return the index, so the caller knows how far we got
228
+ ]
101
229
  }
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const GIT_COMMIT_SHA = 'git.commit.sha'
2
4
  const GIT_BRANCH = 'git.branch'
3
5
  const GIT_REPOSITORY_URL = 'git.repository_url'
@@ -9,7 +11,14 @@ const GIT_COMMIT_COMMITTER_NAME = 'git.commit.committer.name'
9
11
  const GIT_COMMIT_AUTHOR_DATE = 'git.commit.author.date'
10
12
  const GIT_COMMIT_AUTHOR_EMAIL = 'git.commit.author.email'
11
13
  const GIT_COMMIT_AUTHOR_NAME = 'git.commit.author.name'
12
- const GIT_COMMIT_HEAD_SHA = 'git.commit.head_sha'
14
+ const GIT_COMMIT_HEAD_SHA = 'git.commit.head.sha'
15
+ const GIT_COMMIT_HEAD_MESSAGE = 'git.commit.head.message'
16
+ const GIT_COMMIT_HEAD_AUTHOR_DATE = 'git.commit.head.author.date'
17
+ const GIT_COMMIT_HEAD_AUTHOR_EMAIL = 'git.commit.head.author.email'
18
+ const GIT_COMMIT_HEAD_AUTHOR_NAME = 'git.commit.head.author.name'
19
+ const GIT_COMMIT_HEAD_COMMITTER_DATE = 'git.commit.head.committer.date'
20
+ const GIT_COMMIT_HEAD_COMMITTER_EMAIL = 'git.commit.head.committer.email'
21
+ const GIT_COMMIT_HEAD_COMMITTER_NAME = 'git.commit.head.committer.name'
13
22
 
14
23
  const GIT_PULL_REQUEST_BASE_BRANCH_SHA = 'git.pull_request.base_branch_sha'
15
24
  const GIT_PULL_REQUEST_BASE_BRANCH = 'git.pull_request.base_branch'
@@ -22,6 +31,7 @@ const CI_PROVIDER_NAME = 'ci.provider.name'
22
31
  const CI_WORKSPACE_PATH = 'ci.workspace_path'
23
32
  const CI_JOB_URL = 'ci.job.url'
24
33
  const CI_JOB_NAME = 'ci.job.name'
34
+ const CI_JOB_ID = 'ci.job.id'
25
35
  const CI_STAGE_NAME = 'ci.stage.name'
26
36
  const CI_NODE_NAME = 'ci.node.name'
27
37
  const CI_NODE_LABELS = 'ci.node.labels'
@@ -43,6 +53,13 @@ module.exports = {
43
53
  GIT_COMMIT_AUTHOR_EMAIL,
44
54
  GIT_COMMIT_AUTHOR_NAME,
45
55
  GIT_COMMIT_HEAD_SHA,
56
+ GIT_COMMIT_HEAD_MESSAGE,
57
+ GIT_COMMIT_HEAD_AUTHOR_DATE,
58
+ GIT_COMMIT_HEAD_AUTHOR_EMAIL,
59
+ GIT_COMMIT_HEAD_AUTHOR_NAME,
60
+ GIT_COMMIT_HEAD_COMMITTER_DATE,
61
+ GIT_COMMIT_HEAD_COMMITTER_EMAIL,
62
+ GIT_COMMIT_HEAD_COMMITTER_NAME,
46
63
  GIT_PULL_REQUEST_BASE_BRANCH_SHA,
47
64
  GIT_PULL_REQUEST_BASE_BRANCH,
48
65
  CI_PIPELINE_ID,
@@ -53,6 +70,7 @@ module.exports = {
53
70
  CI_WORKSPACE_PATH,
54
71
  CI_JOB_URL,
55
72
  CI_JOB_NAME,
73
+ CI_JOB_ID,
56
74
  CI_STAGE_NAME,
57
75
  CI_ENV_VARS,
58
76
  CI_NODE_NAME,
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const path = require('path')
2
4
  const fs = require('fs')
3
5
  const { URL } = require('url')
@@ -32,7 +34,8 @@ const {
32
34
  GIT_COMMIT_MESSAGE,
33
35
  CI_WORKSPACE_PATH,
34
36
  CI_PIPELINE_URL,
35
- CI_JOB_NAME
37
+ CI_JOB_NAME,
38
+ GIT_COMMIT_HEAD_SHA
36
39
  } = require('./tags')
37
40
  const id = require('../../id')
38
41
  const {
@@ -446,7 +449,8 @@ function getTestEnvironmentMetadata (testFramework, config) {
446
449
  [GIT_COMMIT_AUTHOR_NAME]: authorName,
447
450
  [GIT_COMMIT_AUTHOR_EMAIL]: authorEmail,
448
451
  [GIT_COMMIT_MESSAGE]: commitMessage,
449
- [CI_WORKSPACE_PATH]: ciWorkspacePath
452
+ [CI_WORKSPACE_PATH]: ciWorkspacePath,
453
+ [GIT_COMMIT_HEAD_SHA]: headCommitSha
450
454
  } = ciMetadata
451
455
 
452
456
  const gitMetadata = getGitMetadata({
@@ -457,7 +461,8 @@ function getTestEnvironmentMetadata (testFramework, config) {
457
461
  authorName,
458
462
  authorEmail,
459
463
  commitMessage,
460
- ciWorkspacePath
464
+ ciWorkspacePath,
465
+ headCommitSha
461
466
  })
462
467
 
463
468
  const userProvidedGitMetadata = getUserProviderGitMetadata()
@@ -975,7 +980,7 @@ function getLibraryCapabilitiesTags (testFramework, isParallel, frameworkVersion
975
980
  : undefined,
976
981
  [DD_CAPABILITIES_TEST_MANAGEMENT_ATTEMPT_TO_FIX]:
977
982
  isAttemptToFixSupported(testFramework, isParallel, frameworkVersion)
978
- ? '4'
983
+ ? '5'
979
984
  : undefined,
980
985
  [DD_CAPABILITIES_FAILED_TEST_REPLAY]: isFailedTestReplaySupported(testFramework, frameworkVersion)
981
986
  ? '1'
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { URL } = require('url')
2
4
 
3
5
  function filterSensitiveInfoFromRepository (repositoryUrl) {
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const {
2
4
  GIT_COMMIT_SHA,
3
5
  GIT_BRANCH,
@@ -1,3 +1,7 @@
1
+ 'use strict'
2
+
3
+ /* eslint n/no-unsupported-features/node-builtins: ['error', { ignores: ['os.availableParallelism'] }] */
4
+
1
5
  const os = require('os')
2
6
  const perf = require('perf_hooks').performance
3
7
  const version = require('../../../../../package.json').version