dd-trace 5.58.0 → 5.59.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 (165) 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 +36 -7
  12. package/packages/datadog-code-origin/index.js +14 -9
  13. package/packages/datadog-instrumentations/src/apollo.js +7 -10
  14. package/packages/datadog-instrumentations/src/avsc.js +2 -0
  15. package/packages/datadog-instrumentations/src/child_process.js +21 -42
  16. package/packages/datadog-instrumentations/src/cucumber.js +10 -8
  17. package/packages/datadog-instrumentations/src/cypress.js +2 -0
  18. package/packages/datadog-instrumentations/src/fastify.js +19 -1
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  20. package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
  21. package/packages/datadog-instrumentations/src/hono.js +102 -0
  22. package/packages/datadog-instrumentations/src/langchain.js +21 -0
  23. package/packages/datadog-instrumentations/src/mocha/common.js +2 -0
  24. package/packages/datadog-instrumentations/src/mocha.js +2 -0
  25. package/packages/datadog-instrumentations/src/nyc.js +2 -0
  26. package/packages/datadog-instrumentations/src/orchestrion-config/index.js +32 -0
  27. package/packages/datadog-instrumentations/src/playwright.js +5 -1
  28. package/packages/datadog-instrumentations/src/protobufjs.js +2 -0
  29. package/packages/datadog-instrumentations/src/selenium.js +2 -0
  30. package/packages/datadog-instrumentations/src/vitest.js +2 -0
  31. package/packages/datadog-plugin-avsc/src/index.js +2 -0
  32. package/packages/datadog-plugin-avsc/src/schema_iterator.js +2 -0
  33. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +2 -0
  34. package/packages/datadog-plugin-child_process/src/index.js +30 -10
  35. package/packages/datadog-plugin-cypress/src/after-run.js +2 -0
  36. package/packages/datadog-plugin-cypress/src/after-spec.js +2 -0
  37. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +8 -3
  38. package/packages/datadog-plugin-cypress/src/index.js +2 -0
  39. package/packages/datadog-plugin-cypress/src/plugin.js +2 -0
  40. package/packages/datadog-plugin-cypress/src/support.js +4 -2
  41. package/packages/datadog-plugin-google-cloud-vertexai/src/utils.js +2 -0
  42. package/packages/datadog-plugin-graphql/src/utils.js +2 -0
  43. package/packages/datadog-plugin-hono/src/index.js +28 -0
  44. package/packages/datadog-plugin-jest/src/index.js +2 -0
  45. package/packages/datadog-plugin-jest/src/util.js +2 -0
  46. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -0
  47. package/packages/datadog-plugin-langchain/src/tracing.js +36 -4
  48. package/packages/datadog-plugin-nyc/src/index.js +2 -0
  49. package/packages/datadog-plugin-oracledb/src/connection-parser.js +2 -0
  50. package/packages/datadog-plugin-protobufjs/src/index.js +2 -0
  51. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +2 -0
  52. package/packages/datadog-plugin-selenium/src/index.js +2 -0
  53. package/packages/datadog-plugin-vitest/src/index.js +2 -0
  54. package/packages/dd-trace/src/appsec/iast/iast-context.js +5 -1
  55. package/packages/dd-trace/src/appsec/iast/index.js +2 -0
  56. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
  57. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +0 -2
  58. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -0
  59. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +2 -0
  60. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +2 -0
  61. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +3 -3
  62. package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +18 -11
  63. package/packages/dd-trace/src/appsec/rasp/utils.js +1 -1
  64. package/packages/dd-trace/src/appsec/recommended.json +88 -2
  65. package/packages/dd-trace/src/appsec/reporter.js +7 -7
  66. package/packages/dd-trace/src/appsec/stack_trace.js +11 -11
  67. package/packages/dd-trace/src/appsec/telemetry/common.js +1 -1
  68. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +2 -2
  69. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +3 -3
  70. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -0
  71. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -1
  72. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -0
  73. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +2 -0
  74. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -0
  75. package/packages/dd-trace/src/ci-visibility/telemetry.js +2 -0
  76. package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +2 -0
  77. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +7 -3
  78. package/packages/dd-trace/src/config.js +4 -0
  79. package/packages/dd-trace/src/config_stable.js +2 -0
  80. package/packages/dd-trace/src/datastreams/checkpointer.js +2 -0
  81. package/packages/dd-trace/src/datastreams/context.js +2 -0
  82. package/packages/dd-trace/src/datastreams/encoding.js +2 -0
  83. package/packages/dd-trace/src/datastreams/fnv.js +2 -0
  84. package/packages/dd-trace/src/datastreams/pathway.js +11 -9
  85. package/packages/dd-trace/src/datastreams/processor.js +8 -7
  86. package/packages/dd-trace/src/datastreams/schemas/schema.js +2 -0
  87. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +45 -36
  88. package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +2 -0
  89. package/packages/dd-trace/src/datastreams/writer.js +2 -0
  90. package/packages/dd-trace/src/debugger/devtools_client/index.js +12 -4
  91. package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
  92. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +8 -5
  93. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +1 -1
  94. package/packages/dd-trace/src/debugger/index.js +36 -9
  95. package/packages/dd-trace/src/encode/tags-processors.js +2 -0
  96. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +2 -0
  97. package/packages/dd-trace/src/exporters/common/util.js +2 -0
  98. package/packages/dd-trace/src/exporters/span-stats/index.js +2 -0
  99. package/packages/dd-trace/src/exporters/span-stats/writer.js +2 -0
  100. package/packages/dd-trace/src/external-logger/src/index.js +2 -0
  101. package/packages/dd-trace/src/git_metadata_tagger.js +2 -0
  102. package/packages/dd-trace/src/git_properties.js +2 -0
  103. package/packages/dd-trace/src/guardrails/index.js +3 -4
  104. package/packages/dd-trace/src/guardrails/log.js +2 -2
  105. package/packages/dd-trace/src/guardrails/telemetry.js +16 -14
  106. package/packages/dd-trace/src/guardrails/util.js +0 -2
  107. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +2 -0
  108. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +5 -0
  109. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/tool.js +15 -0
  110. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +36 -0
  111. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +47 -4
  112. package/packages/dd-trace/src/llmobs/tagger.js +10 -1
  113. package/packages/dd-trace/src/noop/dogstatsd.js +2 -0
  114. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -0
  115. package/packages/dd-trace/src/payload-tagging/config/index.js +2 -0
  116. package/packages/dd-trace/src/payload-tagging/index.js +2 -0
  117. package/packages/dd-trace/src/payload-tagging/tagging.js +2 -0
  118. package/packages/dd-trace/src/plugins/apollo.js +2 -0
  119. package/packages/dd-trace/src/plugins/ci_plugin.js +8 -3
  120. package/packages/dd-trace/src/plugins/index.js +1 -0
  121. package/packages/dd-trace/src/plugins/util/ci.js +2 -0
  122. package/packages/dd-trace/src/plugins/util/env.js +2 -0
  123. package/packages/dd-trace/src/plugins/util/git.js +40 -5
  124. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +2 -0
  125. package/packages/dd-trace/src/plugins/util/llm.js +2 -0
  126. package/packages/dd-trace/src/plugins/util/serverless.js +2 -0
  127. package/packages/dd-trace/src/plugins/util/stacktrace.js +178 -50
  128. package/packages/dd-trace/src/plugins/util/tags.js +17 -1
  129. package/packages/dd-trace/src/plugins/util/test.js +9 -4
  130. package/packages/dd-trace/src/plugins/util/url.js +2 -0
  131. package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -0
  132. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +4 -0
  133. package/packages/dd-trace/src/profiling/profiler.js +89 -70
  134. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns.js +2 -0
  135. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +2 -0
  136. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +2 -0
  137. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +2 -0
  138. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +2 -0
  139. package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +2 -0
  140. package/packages/dd-trace/src/profiling/profilers/event_plugins/fs.js +2 -0
  141. package/packages/dd-trace/src/profiling/profilers/event_plugins/net.js +2 -0
  142. package/packages/dd-trace/src/profiling/profilers/events.js +2 -0
  143. package/packages/dd-trace/src/profiling/webspan-utils.js +2 -0
  144. package/packages/dd-trace/src/remote_config/capabilities.js +3 -1
  145. package/packages/dd-trace/src/remote_config/index.js +4 -0
  146. package/packages/dd-trace/src/service-naming/index.js +2 -0
  147. package/packages/dd-trace/src/service-naming/schemas/definition.js +2 -0
  148. package/packages/dd-trace/src/service-naming/schemas/util.js +2 -0
  149. package/packages/dd-trace/src/service-naming/schemas/v0/graphql.js +2 -0
  150. package/packages/dd-trace/src/service-naming/schemas/v0/index.js +2 -0
  151. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +2 -0
  152. package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +2 -0
  153. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +2 -0
  154. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -0
  155. package/packages/dd-trace/src/service-naming/schemas/v1/graphql.js +2 -0
  156. package/packages/dd-trace/src/service-naming/schemas/v1/index.js +2 -0
  157. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +2 -0
  158. package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +2 -0
  159. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +2 -0
  160. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +2 -0
  161. package/packages/dd-trace/src/span_stats.js +2 -0
  162. package/packages/dd-trace/src/supported-configurations.json +2 -0
  163. package/packages/dd-trace/src/telemetry/send-data.js +2 -0
  164. package/register.js +4 -0
  165. package/version.js +0 -3
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { workerData: { rcPort } } = require('node:worker_threads')
3
+ const { workerData: { probePort } } = require('node:worker_threads')
4
4
  const { addBreakpoint, removeBreakpoint, modifyBreakpoint } = require('./breakpoints')
5
5
  const { ackReceived, ackInstalled, ackError } = require('./status')
6
6
  const log = require('../../log')
@@ -32,16 +32,19 @@ const log = require('../../log')
32
32
  // sampling: { snapshotsPerSecond: 5000 },
33
33
  // evaluateAt: 'EXIT' // only used for method probes
34
34
  // }
35
- rcPort.on('message', async ({ action, conf: probe, ackId }) => {
35
+ probePort.on('message', async ({ action, probe, ackId }) => {
36
36
  try {
37
37
  await processMsg(action, probe)
38
- rcPort.postMessage({ ackId })
38
+ probePort.postMessage({ ackId })
39
39
  } catch (err) {
40
- rcPort.postMessage({ ackId, error: err })
40
+ probePort.postMessage({ ackId, error: err })
41
41
  ackError(err, probe)
42
42
  }
43
43
  })
44
- rcPort.on('messageerror', (err) => log.error('[debugger:devtools_client] received "messageerror" on RC port', err))
44
+ probePort.on(
45
+ 'messageerror',
46
+ (err) => log.error('[debugger:devtools_client] received "messageerror" on probe port', err)
47
+ )
45
48
 
46
49
  async function processMsg (action, probe) {
47
50
  log.debug(
@@ -1,4 +1,4 @@
1
- 'use stict'
1
+ 'use strict'
2
2
 
3
3
  module.exports = {
4
4
  collectionSizeSym: Symbol('datadog.collectionSize'),
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ const { readFile } = require('fs')
3
4
  const { types } = require('util')
4
5
  const { join } = require('path')
5
6
  const { Worker, MessageChannel, threadId: parentThreadId } = require('worker_threads')
@@ -23,17 +24,24 @@ function start (config, rc) {
23
24
  log.debug('[debugger] Starting Dynamic Instrumentation client...')
24
25
 
25
26
  const rcAckCallbacks = new Map()
26
- const rcChannel = new MessageChannel()
27
+ const probeChannel = new MessageChannel()
27
28
  configChannel = new MessageChannel()
28
29
 
29
30
  process[Symbol.for('datadog:node:util:types')] = types
30
31
 
31
- rc.setProductHandler('LIVE_DEBUGGING', (action, conf, id, ack) => {
32
+ readProbeFile(config.dynamicInstrumentation.probeFile, (probes) => {
33
+ const action = 'apply'
34
+ for (const probe of probes) {
35
+ probeChannel.port2.postMessage({ action, probe })
36
+ }
37
+ })
38
+
39
+ rc.setProductHandler('LIVE_DEBUGGING', (action, probe, id, ack) => {
32
40
  rcAckCallbacks.set(++ackId, ack)
33
- rcChannel.port2.postMessage({ action, conf, ackId })
41
+ probeChannel.port2.postMessage({ action, probe, ackId })
34
42
  })
35
43
 
36
- rcChannel.port2.on('message', ({ ackId, error }) => {
44
+ probeChannel.port2.on('message', ({ ackId, error }) => {
37
45
  const ack = rcAckCallbacks.get(ackId)
38
46
  if (ack === undefined) {
39
47
  // This should never happen, but just in case something changes in the future, we should guard against it
@@ -44,7 +52,7 @@ function start (config, rc) {
44
52
  ack(error)
45
53
  rcAckCallbacks.delete(ackId)
46
54
  })
47
- rcChannel.port2.on('messageerror', (err) => log.error('[debugger] received "messageerror" on RC port', err))
55
+ probeChannel.port2.on('messageerror', (err) => log.error('[debugger] received "messageerror" on probe port', err))
48
56
 
49
57
  worker = new Worker(
50
58
  join(__dirname, 'devtools_client', 'index.js'),
@@ -54,10 +62,10 @@ function start (config, rc) {
54
62
  workerData: {
55
63
  config: config.serialize(),
56
64
  parentThreadId,
57
- rcPort: rcChannel.port1,
65
+ probePort: probeChannel.port1,
58
66
  configPort: configChannel.port1
59
67
  },
60
- transferList: [rcChannel.port1, configChannel.port1]
68
+ transferList: [probeChannel.port1, configChannel.port1]
61
69
  }
62
70
  )
63
71
 
@@ -84,8 +92,8 @@ function start (config, rc) {
84
92
  })
85
93
 
86
94
  worker.unref()
87
- rcChannel.port1.unref()
88
- rcChannel.port2.unref()
95
+ probeChannel.port1.unref()
96
+ probeChannel.port2.unref()
89
97
  configChannel.port1.unref()
90
98
  configChannel.port2.unref()
91
99
  }
@@ -94,3 +102,22 @@ function configure (config) {
94
102
  if (configChannel === null) return
95
103
  configChannel.port2.postMessage(config.serialize())
96
104
  }
105
+
106
+ function readProbeFile (path, cb) {
107
+ if (!path) return
108
+
109
+ log.debug('[debugger] Reading probe file: %s', path)
110
+ readFile(path, 'utf8', (err, data) => {
111
+ if (err) {
112
+ log.error('[debugger] Failed to read probe file: %s', path, err)
113
+ return
114
+ }
115
+ try {
116
+ const parsedData = JSON.parse(data)
117
+ log.debug('[debugger] Successfully parsed probe file: %s', path)
118
+ cb(parsedData)
119
+ } catch (err) {
120
+ log.error('[debugger] Probe file (%s) is not valid JSON', path, err)
121
+ }
122
+ })
123
+ }
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  // From agent truncators: https://github.com/DataDog/datadog-agent/blob/main/pkg/trace/agent/truncator.go
2
4
 
3
5
  // Values from: https://github.com/DataDog/datadog-agent/blob/main/pkg/trace/traceutil/truncate.go#L22-L27
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { URL, format } = require('url')
2
4
 
3
5
  const request = require('./request')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { getEnvironmentVariable } = require('../../config-helper')
2
4
 
3
5
  function safeJSONStringify (value) {
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { URL, format } = require('url')
2
4
 
3
5
  const { Writer } = require('./writer')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { SpanStatsEncoder } = require('../../encode/span-stats')
2
4
 
3
5
  const pkg = require('../../../../../package.json')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const tracerLogger = require('../../log')// path to require tracer logger
2
4
 
3
5
  const https = require('https')
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const { SCI_COMMIT_SHA, SCI_REPOSITORY_URL } = require('./constants')
2
4
 
3
5
  class GitMetadataTagger {
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const commitSHARegex = /git\.commit\.sha=([a-f\d]{40})/
2
4
  const repositoryUrlRegex = /git\.repository_url=([\w\d:@/.-]+)/
3
5
 
@@ -1,7 +1,5 @@
1
1
  'use strict'
2
2
 
3
- /* eslint-disable no-var */
4
-
5
3
  var path = require('path')
6
4
  var Module = require('module')
7
5
  var isTrue = require('./util').isTrue
@@ -26,9 +24,11 @@ function guard (fn) {
26
24
  var resolvedInApp
27
25
  var entrypoint = process.argv[1]
28
26
  try {
27
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
29
28
  resolvedInApp = Module.createRequire(entrypoint).resolve('dd-trace')
30
29
  } catch (e) {
31
30
  // Ignore. If we can't resolve the module, we assume it's not in the app.
31
+ // TODO: There's also the possibility that this version of Node.js doesn't have Module.createRequire (pre v12.2.0)
32
32
  }
33
33
  if (resolvedInApp) {
34
34
  var ourselves = path.normalize(path.join(__dirname, '..', '..', '..', '..', 'index.js'))
@@ -54,8 +54,7 @@ function guard (fn) {
54
54
  }
55
55
 
56
56
  if (!clobberBailout && (!initBailout || forced)) {
57
- // Ensure the instrumentation source is set for the current process and potential
58
- // child processes.
57
+ // Ensure the instrumentation source is set for the current process and potential child processes.
59
58
  var result = fn()
60
59
  telemetry('complete', ['injection_forced:' + (forced && initBailout ? 'true' : 'false')])
61
60
  log.info('Application instrumentation bootstrapping complete')
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- /* eslint-disable no-var */
4
3
  /* eslint-disable no-console */
5
4
 
6
5
  var isTrue = require('./util').isTrue
@@ -23,7 +22,8 @@ var logLevel = isTrue(DD_TRACE_DEBUG)
23
22
  : logLevels.off
24
23
 
25
24
  var log = {
26
- debug: logLevel <= 20 ? console.debug.bind(console) : function () {},
25
+ /* eslint n/no-unsupported-features/node-builtins: ['error', { ignores: ['console.debug'] }] */
26
+ debug: logLevel <= 20 ? (console.debug || console.log).bind(console) : function () {},
27
27
  info: logLevel <= 30 ? console.info.bind(console) : function () {},
28
28
  warn: logLevel <= 40 ? console.warn.bind(console) : function () {},
29
29
  error: logLevel <= 50 ? console.error.bind(console) : function () {}
@@ -1,8 +1,5 @@
1
1
  'use strict'
2
2
 
3
- /* eslint-disable no-var */
4
- /* eslint-disable object-shorthand */
5
-
6
3
  var fs = require('fs')
7
4
  var spawn = require('child_process').spawn
8
5
  var tracerVersion = require('../../../../package.json').version
@@ -11,12 +8,12 @@ var log = require('./log')
11
8
  module.exports = sendTelemetry
12
9
 
13
10
  if (!process.env.DD_INJECTION_ENABLED) {
14
- module.exports = function () {}
11
+ module.exports = function noop () {}
15
12
  }
16
13
 
17
14
  var telemetryForwarderPath = process.env.DD_TELEMETRY_FORWARDER_PATH
18
15
  if (typeof telemetryForwarderPath !== 'string' || !fs.existsSync(telemetryForwarderPath)) {
19
- module.exports = function () {}
16
+ module.exports = function noop () {}
20
17
  }
21
18
 
22
19
  var metadata = {
@@ -28,18 +25,23 @@ var metadata = {
28
25
  pid: process.pid
29
26
  }
30
27
 
31
- var seen = []
32
- function hasSeen (point) {
28
+ var seen = {}
29
+ function shouldSend (point) {
33
30
  if (point.name === 'abort') {
34
31
  // This one can only be sent once, regardless of tags
35
- return seen.includes('abort')
36
- }
37
- if (point.name === 'abort.integration') {
32
+ if (seen.abort) {
33
+ return false
34
+ }
35
+ seen.abort = true
36
+ } else if (point.name === 'abort.integration') {
38
37
  // For now, this is the only other one we want to dedupe
39
38
  var compiledPoint = point.name + point.tags.join('')
40
- return seen.includes(compiledPoint)
39
+ if (seen[compiledPoint]) {
40
+ return false
41
+ }
42
+ seen[compiledPoint] = true
41
43
  }
42
- return false
44
+ return true
43
45
  }
44
46
 
45
47
  function sendTelemetry (name, tags) {
@@ -48,9 +50,9 @@ function sendTelemetry (name, tags) {
48
50
  points = [{ name: name, tags: tags || [] }]
49
51
  }
50
52
  if (['1', 'true', 'True'].indexOf(process.env.DD_INJECT_FORCE) !== -1) {
51
- points = points.filter(function (p) { return ['error', 'complete'].includes(p.name) })
53
+ points = points.filter(function (p) { return ['error', 'complete'].indexOf(p.name) !== -1 })
52
54
  }
53
- points = points.filter(function (p) { return !hasSeen(p) })
55
+ points = points.filter(function (p) { return shouldSend(p) })
54
56
  for (var i = 0; i < points.length; i++) {
55
57
  points[i].name = 'library_entrypoint.' + points[i].name
56
58
  }
@@ -1,7 +1,5 @@
1
1
  'use strict'
2
2
 
3
- /* eslint-disable object-shorthand */
4
-
5
3
  function isTrue (str) {
6
4
  str = String(str).toLowerCase()
7
5
  return str === 'true' || str === '1'
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const BaseLLMObsPlugin = require('./base')
2
4
  const { storage } = require('../../../../datadog-core')
3
5
  const llmobsStore = storage('llmobs')
@@ -8,9 +8,14 @@ const ROLE_MAPPINGS = {
8
8
 
9
9
  class LangChainLLMObsHandler {
10
10
  constructor (tagger) {
11
+ /** @type {import('../../../tagger')} */
11
12
  this._tagger = tagger
12
13
  }
13
14
 
15
+ getName ({ span }) {
16
+ return span?.context()._tags?.['resource.name']
17
+ }
18
+
14
19
  setMetaTags () {}
15
20
 
16
21
  formatIO (messages) {
@@ -0,0 +1,15 @@
1
+ 'use strict'
2
+
3
+ const LangChainLLMObsHandler = require('.')
4
+
5
+ class LangChainLLMObsToolHandler extends LangChainLLMObsHandler {
6
+ getName ({ instance }) {
7
+ return instance.name
8
+ }
9
+
10
+ setMetaTags ({ span, inputs, results }) {
11
+ this._tagger.tagTextIO(span, inputs, results)
12
+ }
13
+ }
14
+
15
+ module.exports = LangChainLLMObsToolHandler
@@ -0,0 +1,36 @@
1
+ 'use strict'
2
+
3
+ const LangChainLLMObsHandler = require('.')
4
+ const { spanHasError } = require('../../../util')
5
+
6
+ class LangChainLLMObsVectorStoreHandler extends LangChainLLMObsHandler {
7
+ setMetaTags ({ span, inputs, results }) {
8
+ const input = this.formatIO(inputs)
9
+ if (spanHasError(span)) {
10
+ this._tagger.tagRetrievalIO(span, input)
11
+ return
12
+ }
13
+
14
+ const documents = []
15
+ for (const documentResult of results) {
16
+ let document, score
17
+ if (Array.isArray(documentResult)) {
18
+ document = documentResult[0]
19
+ score = documentResult[1]
20
+ } else {
21
+ document = documentResult
22
+ }
23
+
24
+ documents.push({
25
+ text: document.pageContent,
26
+ id: document.id,
27
+ name: document.metadata?.source,
28
+ score
29
+ })
30
+ }
31
+
32
+ this._tagger.tagRetrievalIO(span, input, documents)
33
+ }
34
+ }
35
+
36
+ module.exports = LangChainLLMObsVectorStoreHandler
@@ -14,11 +14,15 @@ const LLM_SPAN_TYPES = new Set(['llm', 'chat_model', 'embedding'])
14
14
  const LLM = 'llm'
15
15
  const WORKFLOW = 'workflow'
16
16
  const EMBEDDING = 'embedding'
17
+ const TOOL = 'tool'
18
+ const RETRIEVAL = 'retrieval'
17
19
 
18
20
  const ChainHandler = require('./handlers/chain')
19
21
  const ChatModelHandler = require('./handlers/chat_model')
20
22
  const LlmHandler = require('./handlers/llm')
21
23
  const EmbeddingHandler = require('./handlers/embedding')
24
+ const ToolHandler = require('./handlers/tool')
25
+ const VectorStoreHandler = require('./handlers/vectorstore')
22
26
 
23
27
  class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
24
28
  static get integration () { return 'langchain' }
@@ -34,7 +38,9 @@ class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
34
38
  chain: new ChainHandler(this._tagger),
35
39
  chat_model: new ChatModelHandler(this._tagger),
36
40
  llm: new LlmHandler(this._tagger),
37
- embedding: new EmbeddingHandler(this._tagger)
41
+ embedding: new EmbeddingHandler(this._tagger),
42
+ tool: new ToolHandler(this._tagger),
43
+ similarity_search: new VectorStoreHandler(this._tagger)
38
44
  }
39
45
  }
40
46
 
@@ -45,7 +51,10 @@ class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
45
51
  const modelProvider = tags['langchain.request.provider'] // could be undefined
46
52
  const modelName = tags['langchain.request.model'] // could be undefined
47
53
  const kind = this.getKind(ctx.type, modelProvider)
48
- const name = tags['resource.name']
54
+
55
+ const instance = ctx.instance || ctx.self
56
+ const handler = this._handlers[ctx.type]
57
+ const name = handler?.getName({ span, instance })
49
58
 
50
59
  return {
51
60
  modelProvider,
@@ -113,7 +122,14 @@ class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
113
122
  }
114
123
  }
115
124
 
116
- return WORKFLOW
125
+ switch (type) {
126
+ case 'tool':
127
+ return TOOL
128
+ case 'similarity_search':
129
+ return RETRIEVAL
130
+ default:
131
+ return WORKFLOW
132
+ }
117
133
  }
118
134
 
119
135
  getIntegrationName (type, provider = 'custom') {
@@ -181,11 +197,38 @@ class EmbeddingsEmbedDocumentsPlugin extends BaseLangChainLLMObsPlugin {
181
197
  }
182
198
  }
183
199
 
200
+ class ToolInvokePlugin extends BaseLangChainLLMObsPlugin {
201
+ static get id () { return 'llmobs_langchain_tool_invoke' }
202
+ static get lcType () { return 'tool' }
203
+ static get prefix () {
204
+ return 'tracing:orchestrion:@langchain/core:Tool_invoke'
205
+ }
206
+ }
207
+
208
+ class VectorStoreSimilaritySearchPlugin extends BaseLangChainLLMObsPlugin {
209
+ static get id () { return 'llmobs_langchain_vectorstore_similarity_search' }
210
+ static get lcType () { return 'similarity_search' }
211
+ static get prefix () {
212
+ return 'tracing:orchestrion:@langchain/core:VectorStore_similaritySearch'
213
+ }
214
+ }
215
+
216
+ class VectorStoreSimilaritySearchWithScorePlugin extends BaseLangChainLLMObsPlugin {
217
+ static get id () { return 'llmobs_langchain_vectorstore_similarity_search_with_score' }
218
+ static get lcType () { return 'similarity_search' }
219
+ static get prefix () {
220
+ return 'tracing:orchestrion:@langchain/core:VectorStore_similaritySearchWithScore'
221
+ }
222
+ }
223
+
184
224
  module.exports = [
185
225
  RunnableSequenceInvokePlugin,
186
226
  RunnableSequenceBatchPlugin,
187
227
  BaseChatModelGeneratePlugin,
188
228
  BaseLLMGeneratePlugin,
189
229
  EmbeddingsEmbedQueryPlugin,
190
- EmbeddingsEmbedDocumentsPlugin
230
+ EmbeddingsEmbedDocumentsPlugin,
231
+ ToolInvokePlugin,
232
+ VectorStoreSimilaritySearchPlugin,
233
+ VectorStoreSimilaritySearchWithScorePlugin
191
234
  ]
@@ -281,6 +281,7 @@ class LLMObsTagger {
281
281
 
282
282
  const { content = '', role } = message
283
283
  const toolCalls = message.toolCalls
284
+ const toolId = message.toolId
284
285
  const messageObj = { content }
285
286
 
286
287
  const valid = typeof content === 'string'
@@ -288,7 +289,7 @@ class LLMObsTagger {
288
289
  this.#handleFailure('Message content must be a string.', 'invalid_io_messages')
289
290
  }
290
291
 
291
- const condition = this.#tagConditionalString(role, 'Message role', messageObj, 'role')
292
+ let condition = this.#tagConditionalString(role, 'Message role', messageObj, 'role')
292
293
 
293
294
  if (toolCalls) {
294
295
  const filteredToolCalls = this.#filterToolCalls(toolCalls)
@@ -298,6 +299,14 @@ class LLMObsTagger {
298
299
  }
299
300
  }
300
301
 
302
+ if (toolId) {
303
+ if (role === 'tool') {
304
+ condition = this.#tagConditionalString(toolId, 'Tool ID', messageObj, 'tool_id')
305
+ } else {
306
+ log.warn(`Tool ID for tool message not associated with a "tool" role, instead got "${role}"`)
307
+ }
308
+ }
309
+
301
310
  if (valid && condition) {
302
311
  messages.push(messageObj)
303
312
  }
@@ -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,
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const os = require('os')
2
4
 
3
5
  const OS_PLATFORM = 'os.platform'