dd-trace 4.47.1 → 4.49.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 (156) hide show
  1. package/LICENSE-3rdparty.csv +1 -1
  2. package/ext/types.d.ts +1 -0
  3. package/ext/types.js +1 -0
  4. package/index.d.ts +361 -0
  5. package/package.json +18 -13
  6. package/packages/datadog-code-origin/index.js +38 -0
  7. package/packages/datadog-core/index.js +2 -2
  8. package/packages/datadog-core/src/utils/src/parse-tags.js +33 -0
  9. package/packages/datadog-esbuild/index.js +4 -2
  10. package/packages/datadog-instrumentations/src/amqplib.js +65 -5
  11. package/packages/datadog-instrumentations/src/avsc.js +37 -0
  12. package/packages/datadog-instrumentations/src/azure-functions.js +48 -0
  13. package/packages/datadog-instrumentations/src/child_process.js +144 -27
  14. package/packages/datadog-instrumentations/src/express.js +37 -4
  15. package/packages/datadog-instrumentations/src/fastify.js +12 -1
  16. package/packages/datadog-instrumentations/src/fs.js +27 -7
  17. package/packages/datadog-instrumentations/src/helpers/hooks.js +6 -0
  18. package/packages/datadog-instrumentations/src/helpers/register.js +9 -0
  19. package/packages/datadog-instrumentations/src/jest.js +2 -1
  20. package/packages/datadog-instrumentations/src/kafkajs.js +123 -63
  21. package/packages/datadog-instrumentations/src/mocha/common.js +1 -1
  22. package/packages/datadog-instrumentations/src/mocha/utils.js +2 -2
  23. package/packages/datadog-instrumentations/src/multer.js +37 -0
  24. package/packages/datadog-instrumentations/src/mysql2.js +220 -1
  25. package/packages/datadog-instrumentations/src/openai.js +2 -2
  26. package/packages/datadog-instrumentations/src/protobufjs.js +127 -0
  27. package/packages/datadog-instrumentations/src/url.js +84 -0
  28. package/packages/datadog-instrumentations/src/utils/src/extract-package-and-module-path.js +7 -4
  29. package/packages/datadog-instrumentations/src/winston.js +22 -0
  30. package/packages/datadog-plugin-amqplib/src/consumer.js +4 -4
  31. package/packages/datadog-plugin-avsc/src/index.js +9 -0
  32. package/packages/datadog-plugin-avsc/src/schema_iterator.js +169 -0
  33. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
  34. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
  35. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -0
  36. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
  37. package/packages/datadog-plugin-azure-functions/src/index.js +77 -0
  38. package/packages/datadog-plugin-fastify/src/code_origin.js +31 -0
  39. package/packages/datadog-plugin-fastify/src/index.js +10 -12
  40. package/packages/datadog-plugin-fastify/src/tracing.js +19 -0
  41. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +8 -1
  42. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +8 -0
  43. package/packages/datadog-plugin-grpc/src/client.js +3 -0
  44. package/packages/datadog-plugin-grpc/src/server.js +3 -0
  45. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +6 -3
  46. package/packages/datadog-plugin-kafkajs/src/consumer.js +8 -4
  47. package/packages/datadog-plugin-kafkajs/src/producer.js +10 -4
  48. package/packages/datadog-plugin-mocha/src/index.js +4 -1
  49. package/packages/datadog-plugin-openai/src/index.js +9 -1015
  50. package/packages/datadog-plugin-openai/src/tracing.js +1023 -0
  51. package/packages/datadog-plugin-protobufjs/src/index.js +14 -0
  52. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +180 -0
  53. package/packages/dd-trace/src/appsec/addresses.js +8 -1
  54. package/packages/dd-trace/src/appsec/channels.js +7 -1
  55. package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +13 -1
  56. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +8 -1
  57. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +1 -1
  58. package/packages/dd-trace/src/appsec/iast/index.js +3 -0
  59. package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +1 -0
  60. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +55 -7
  61. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +15 -0
  62. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -2
  63. package/packages/dd-trace/src/appsec/index.js +61 -43
  64. package/packages/dd-trace/src/appsec/rasp/command_injection.js +49 -0
  65. package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +99 -0
  66. package/packages/dd-trace/src/appsec/rasp/index.js +27 -10
  67. package/packages/dd-trace/src/appsec/rasp/lfi.js +112 -0
  68. package/packages/dd-trace/src/appsec/rasp/sql_injection.js +24 -4
  69. package/packages/dd-trace/src/appsec/rasp/ssrf.js +4 -3
  70. package/packages/dd-trace/src/appsec/rasp/utils.js +4 -2
  71. package/packages/dd-trace/src/appsec/recommended.json +3 -7
  72. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +6 -1
  73. package/packages/dd-trace/src/appsec/remote_config/index.js +10 -0
  74. package/packages/dd-trace/src/appsec/reporter.js +17 -9
  75. package/packages/dd-trace/src/appsec/sdk/track_event.js +10 -3
  76. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +1 -1
  77. package/packages/dd-trace/src/appsec/waf/waf_manager.js +4 -0
  78. package/packages/dd-trace/src/azure_metadata.js +120 -0
  79. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +97 -0
  80. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +90 -0
  81. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -14
  82. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +19 -1
  83. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +53 -0
  84. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +8 -1
  85. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +43 -0
  86. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +53 -0
  87. package/packages/dd-trace/src/config.js +86 -6
  88. package/packages/dd-trace/src/constants.js +3 -1
  89. package/packages/dd-trace/src/datastreams/pathway.js +1 -0
  90. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +25 -17
  91. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  92. package/packages/dd-trace/src/debugger/devtools_client/index.js +52 -5
  93. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +4 -4
  94. package/packages/dd-trace/src/debugger/devtools_client/send.js +29 -2
  95. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +187 -0
  96. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +40 -0
  97. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +252 -0
  98. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +6 -0
  99. package/packages/dd-trace/src/debugger/devtools_client/state.js +19 -4
  100. package/packages/dd-trace/src/debugger/index.js +10 -3
  101. package/packages/dd-trace/src/exporters/common/request.js +8 -34
  102. package/packages/dd-trace/src/exporters/common/url-to-http-options-polyfill.js +31 -0
  103. package/packages/dd-trace/src/llmobs/constants/tags.js +34 -0
  104. package/packages/dd-trace/src/llmobs/constants/text.js +6 -0
  105. package/packages/dd-trace/src/llmobs/constants/writers.js +13 -0
  106. package/packages/dd-trace/src/llmobs/index.js +103 -0
  107. package/packages/dd-trace/src/llmobs/noop.js +82 -0
  108. package/packages/dd-trace/src/llmobs/plugins/base.js +65 -0
  109. package/packages/dd-trace/src/llmobs/plugins/openai.js +205 -0
  110. package/packages/dd-trace/src/llmobs/sdk.js +377 -0
  111. package/packages/dd-trace/src/llmobs/span_processor.js +195 -0
  112. package/packages/dd-trace/src/llmobs/storage.js +7 -0
  113. package/packages/dd-trace/src/llmobs/tagger.js +322 -0
  114. package/packages/dd-trace/src/llmobs/util.js +176 -0
  115. package/packages/dd-trace/src/llmobs/writers/base.js +111 -0
  116. package/packages/dd-trace/src/llmobs/writers/evaluations.js +29 -0
  117. package/packages/dd-trace/src/llmobs/writers/spans/agentProxy.js +23 -0
  118. package/packages/dd-trace/src/llmobs/writers/spans/agentless.js +17 -0
  119. package/packages/dd-trace/src/llmobs/writers/spans/base.js +49 -0
  120. package/packages/dd-trace/src/noop/proxy.js +3 -0
  121. package/packages/dd-trace/src/noop/span.js +3 -0
  122. package/packages/dd-trace/src/opentelemetry/span.js +1 -1
  123. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -0
  124. package/packages/dd-trace/src/opentracing/propagation/text_map.js +73 -12
  125. package/packages/dd-trace/src/opentracing/span.js +12 -0
  126. package/packages/dd-trace/src/opentracing/tracer.js +8 -1
  127. package/packages/dd-trace/src/payload-tagging/config/aws.json +71 -3
  128. package/packages/dd-trace/src/payload-tagging/index.js +1 -1
  129. package/packages/dd-trace/src/payload-tagging/jsonpath-plus.js +2094 -0
  130. package/packages/dd-trace/src/plugin_manager.js +4 -2
  131. package/packages/dd-trace/src/plugins/ci_plugin.js +2 -0
  132. package/packages/dd-trace/src/plugins/index.js +3 -0
  133. package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
  134. package/packages/dd-trace/src/plugins/outbound.js +9 -0
  135. package/packages/dd-trace/src/plugins/schema.js +35 -0
  136. package/packages/dd-trace/src/plugins/util/ci.js +23 -1
  137. package/packages/dd-trace/src/plugins/util/serverless.js +7 -0
  138. package/packages/dd-trace/src/plugins/util/stacktrace.js +94 -0
  139. package/packages/dd-trace/src/plugins/util/tags.js +7 -0
  140. package/packages/dd-trace/src/plugins/util/test.js +20 -22
  141. package/packages/dd-trace/src/plugins/util/web.js +6 -4
  142. package/packages/dd-trace/src/priority_sampler.js +16 -0
  143. package/packages/dd-trace/src/profiling/config.js +3 -1
  144. package/packages/dd-trace/src/profiling/exporters/agent.js +7 -5
  145. package/packages/dd-trace/src/profiling/profiler.js +24 -14
  146. package/packages/dd-trace/src/profiling/profilers/events.js +3 -3
  147. package/packages/dd-trace/src/profiling/profilers/wall.js +95 -66
  148. package/packages/dd-trace/src/proxy.js +20 -1
  149. package/packages/dd-trace/src/service-naming/schemas/v0/index.js +2 -1
  150. package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +12 -0
  151. package/packages/dd-trace/src/service-naming/schemas/v1/index.js +2 -1
  152. package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +12 -0
  153. package/packages/dd-trace/src/span_processor.js +5 -0
  154. package/packages/dd-trace/src/telemetry/index.js +11 -1
  155. package/packages/datadog-core/src/storage/async_resource.js +0 -108
  156. package/packages/datadog-core/src/storage/index.js +0 -5
@@ -20,7 +20,7 @@ const enterCh = dc.channel('dd-trace:storage:enter')
20
20
  const spanFinishCh = dc.channel('dd-trace:span:finish')
21
21
  const profilerTelemetryMetrics = telemetryMetrics.manager.namespace('profilers')
22
22
 
23
- const MemoizedWebTags = Symbol('NativeWallProfiler.MemoizedWebTags')
23
+ const ProfilingContext = Symbol('NativeWallProfiler.ProfilingContext')
24
24
 
25
25
  let kSampleCount
26
26
 
@@ -44,36 +44,42 @@ function endpointNameFromTags (tags) {
44
44
  ].filter(v => v).join(' ')
45
45
  }
46
46
 
47
- function getWebTags (startedSpans, i, span) {
48
- // Are web tags for this span already memoized?
49
- const memoizedWebTags = span[MemoizedWebTags]
50
- if (memoizedWebTags !== undefined) {
51
- return memoizedWebTags
52
- }
53
- // No, we'll have to memoize a new value
54
- function memoize (tags) {
55
- span[MemoizedWebTags] = tags
56
- return tags
57
- }
58
- // Is this span itself a web span?
59
- const context = span.context()
60
- const tags = context._tags
61
- if (isWebServerSpan(tags)) {
62
- return memoize(tags)
63
- }
64
- // It isn't. Get parent's web tags (memoize them too recursively.)
65
- // There might be several webspans, for example with next.js, http plugin creates the first span
66
- // and then next.js plugin creates a child span, and this child span has the correct endpoint
67
- // information. That's why we always use the tags of the closest ancestor web span.
68
- const parentId = context._parentId
69
- while (--i >= 0) {
70
- const ispan = startedSpans[i]
71
- if (ispan.context()._spanId === parentId) {
72
- return memoize(getWebTags(startedSpans, i, ispan))
47
+ let channelsActivated = false
48
+ function ensureChannelsActivated () {
49
+ if (channelsActivated) return
50
+
51
+ const { AsyncLocalStorage, createHook } = require('async_hooks')
52
+ const shimmer = require('../../../../datadog-shimmer')
53
+
54
+ createHook({ before: () => beforeCh.publish() }).enable()
55
+
56
+ let inRun = false
57
+ shimmer.wrap(AsyncLocalStorage.prototype, 'enterWith', function (original) {
58
+ return function (...args) {
59
+ const retVal = original.apply(this, args)
60
+ if (!inRun) enterCh.publish()
61
+ return retVal
73
62
  }
74
- }
75
- // Local root span with no web span
76
- return memoize(null)
63
+ })
64
+
65
+ shimmer.wrap(AsyncLocalStorage.prototype, 'run', function (original) {
66
+ return function (store, callback, ...args) {
67
+ const wrappedCb = shimmer.wrapFunction(callback, cb => function (...args) {
68
+ inRun = false
69
+ enterCh.publish()
70
+ const retVal = cb.apply(this, args)
71
+ inRun = true
72
+ return retVal
73
+ })
74
+ inRun = true
75
+ const retVal = original.call(this, store, wrappedCb, ...args)
76
+ enterCh.publish()
77
+ inRun = false
78
+ return retVal
79
+ }
80
+ })
81
+
82
+ channelsActivated = true
77
83
  }
78
84
 
79
85
  class NativeWallProfiler {
@@ -121,6 +127,8 @@ class NativeWallProfiler {
121
127
  start ({ mapper } = {}) {
122
128
  if (this._started) return
123
129
 
130
+ ensureChannelsActivated()
131
+
124
132
  this._mapper = mapper
125
133
  this._pprof = require('@datadog/pprof')
126
134
  kSampleCount = this._pprof.time.constants.kSampleCount
@@ -144,14 +152,10 @@ class NativeWallProfiler {
144
152
  })
145
153
 
146
154
  if (this._withContexts) {
147
- this._currentContext = {}
148
- this._pprof.time.setContext(this._currentContext)
155
+ this._setNewContext()
149
156
 
150
157
  if (this._captureSpanData) {
151
158
  this._profilerState = this._pprof.time.getState()
152
- this._lastSpan = undefined
153
- this._lastStartedSpans = undefined
154
- this._lastWebTags = undefined
155
159
  this._lastSampleCount = 0
156
160
 
157
161
  beforeCh.subscribe(this._enter)
@@ -169,51 +173,78 @@ class NativeWallProfiler {
169
173
  const sampleCount = this._profilerState[kSampleCount]
170
174
  if (sampleCount !== this._lastSampleCount) {
171
175
  this._lastSampleCount = sampleCount
172
- const context = this._currentContext
173
- this._currentContext = {}
174
- this._pprof.time.setContext(this._currentContext)
176
+ const context = this._currentContext.ref
177
+ this._setNewContext()
175
178
 
176
179
  this._updateContext(context)
177
180
  }
178
181
 
179
182
  const span = getActiveSpan()
180
- if (span) {
183
+ this._currentContext.ref = span ? this._getProfilingContext(span) : {}
184
+ }
185
+
186
+ _getProfilingContext (span) {
187
+ let profilingContext = span[ProfilingContext]
188
+ if (profilingContext === undefined) {
181
189
  const context = span.context()
182
- this._lastSpan = span
183
190
  const startedSpans = getStartedSpans(context)
184
- this._lastStartedSpans = startedSpans
191
+
192
+ let spanId
193
+ let rootSpanId
194
+ if (this._codeHotspotsEnabled) {
195
+ spanId = context._spanId
196
+ rootSpanId = startedSpans.length ? startedSpans[0].context()._spanId : context._spanId
197
+ }
198
+
199
+ let webTags
185
200
  if (this._endpointCollectionEnabled) {
186
- this._lastWebTags = getWebTags(startedSpans, startedSpans.length, span)
201
+ const tags = context._tags
202
+ if (isWebServerSpan(tags)) {
203
+ webTags = tags
204
+ } else {
205
+ // Get parent's context's web tags
206
+ const parentId = context._parentId
207
+ for (let i = startedSpans.length; --i >= 0;) {
208
+ const ispan = startedSpans[i]
209
+ if (ispan.context()._spanId === parentId) {
210
+ webTags = this._getProfilingContext(ispan).webTags
211
+ break
212
+ }
213
+ }
214
+ }
187
215
  }
188
- } else {
189
- this._lastStartedSpans = undefined
190
- this._lastSpan = undefined
191
- this._lastWebTags = undefined
216
+
217
+ profilingContext = { spanId, rootSpanId, webTags }
218
+ span[ProfilingContext] = profilingContext
192
219
  }
220
+ return profilingContext
221
+ }
222
+
223
+ _setNewContext () {
224
+ this._pprof.time.setContext(
225
+ this._currentContext = {
226
+ ref: {}
227
+ }
228
+ )
193
229
  }
194
230
 
195
231
  _updateContext (context) {
196
- if (!this._lastSpan) {
197
- return
232
+ if (typeof context.spanId === 'object') {
233
+ context.spanId = context.spanId.toString(10)
198
234
  }
199
- if (this._codeHotspotsEnabled) {
200
- context.spanId = this._lastSpan.context().toSpanId()
201
- const rootSpan = this._lastStartedSpans[0]
202
- if (rootSpan) {
203
- context.rootSpanId = rootSpan.context().toSpanId()
204
- }
235
+ if (typeof context.rootSpanId === 'object') {
236
+ context.rootSpanId = context.rootSpanId.toString(10)
205
237
  }
206
- if (this._lastWebTags) {
207
- context.webTags = this._lastWebTags
238
+ if (context.webTags !== undefined && context.endpoint === undefined) {
208
239
  // endpoint may not be determined yet, but keep it as fallback
209
240
  // if tags are not available anymore during serialization
210
- context.endpoint = endpointNameFromTags(this._lastWebTags)
241
+ context.endpoint = endpointNameFromTags(context.webTags)
211
242
  }
212
243
  }
213
244
 
214
245
  _spanFinished (span) {
215
- if (span[MemoizedWebTags]) {
216
- span[MemoizedWebTags] = undefined
246
+ if (span[ProfilingContext] !== undefined) {
247
+ span[ProfilingContext] = undefined
217
248
  }
218
249
  }
219
250
 
@@ -248,9 +279,6 @@ class NativeWallProfiler {
248
279
  enterCh.unsubscribe(this._enter)
249
280
  spanFinishCh.unsubscribe(this._spanFinished)
250
281
  this._profilerState = undefined
251
- this._lastSpan = undefined
252
- this._lastStartedSpans = undefined
253
- this._lastWebTags = undefined
254
282
  }
255
283
  this._started = false
256
284
  }
@@ -273,20 +301,21 @@ class NativeWallProfiler {
273
301
 
274
302
  const labels = { ...getThreadLabels() }
275
303
 
276
- const { context: { spanId, rootSpanId, webTags, endpoint }, timestamp } = context
304
+ const { context: { ref }, timestamp } = context
305
+ const { spanId, rootSpanId, webTags, endpoint } = ref ?? {}
277
306
 
278
307
  if (this._timelineEnabled) {
279
308
  // Incoming timestamps are in microseconds, we emit nanos.
280
309
  labels[END_TIMESTAMP_LABEL] = timestamp * 1000n
281
310
  }
282
311
 
283
- if (spanId) {
312
+ if (spanId !== undefined) {
284
313
  labels[SPAN_ID_LABEL] = spanId
285
314
  }
286
- if (rootSpanId) {
315
+ if (rootSpanId !== undefined) {
287
316
  labels[LOCAL_ROOT_SPAN_ID_LABEL] = rootSpanId
288
317
  }
289
- if (webTags && Object.keys(webTags).length !== 0) {
318
+ if (webTags !== undefined && Object.keys(webTags).length !== 0) {
290
319
  labels['trace endpoint'] = endpointNameFromTags(webTags)
291
320
  } else if (endpoint) {
292
321
  // fallback to endpoint computed when sample was taken
@@ -16,6 +16,7 @@ const NoopDogStatsDClient = require('./noop/dogstatsd')
16
16
  const spanleak = require('./spanleak')
17
17
  const { SSIHeuristics } = require('./profiling/ssi-heuristics')
18
18
  const appsecStandalone = require('./appsec/standalone')
19
+ const LLMObsSDK = require('./llmobs/sdk')
19
20
 
20
21
  class LazyModule {
21
22
  constructor (provider) {
@@ -46,7 +47,8 @@ class Tracer extends NoopProxy {
46
47
  // these requires must work with esm bundler
47
48
  this._modules = {
48
49
  appsec: new LazyModule(() => require('./appsec')),
49
- iast: new LazyModule(() => require('./appsec/iast'))
50
+ iast: new LazyModule(() => require('./appsec/iast')),
51
+ llmobs: new LazyModule(() => require('./llmobs'))
50
52
  }
51
53
  }
52
54
 
@@ -162,6 +164,18 @@ class Tracer extends NoopProxy {
162
164
  this._testApiManualPlugin.configure({ ...config, enabled: true })
163
165
  }
164
166
  }
167
+ if (config.ciVisAgentlessLogSubmissionEnabled) {
168
+ if (process.env.DD_API_KEY) {
169
+ const LogSubmissionPlugin = require('./ci-visibility/log-submission/log-submission-plugin')
170
+ const automaticLogPlugin = new LogSubmissionPlugin(this)
171
+ automaticLogPlugin.configure({ ...config, enabled: true })
172
+ } else {
173
+ log.warn(
174
+ 'DD_AGENTLESS_LOG_SUBMISSION_ENABLED is set, ' +
175
+ 'but DD_API_KEY is undefined, so no automatic log submission will be performed.'
176
+ )
177
+ }
178
+ }
165
179
  } catch (e) {
166
180
  log.error(e)
167
181
  }
@@ -183,11 +197,15 @@ class Tracer extends NoopProxy {
183
197
  if (config.appsec.enabled) {
184
198
  this._modules.appsec.enable(config)
185
199
  }
200
+ if (config.llmobs.enabled) {
201
+ this._modules.llmobs.enable(config)
202
+ }
186
203
  if (!this._tracingInitialized) {
187
204
  const prioritySampler = appsecStandalone.configure(config)
188
205
  this._tracer = new DatadogTracer(config, prioritySampler)
189
206
  this.dataStreamsCheckpointer = this._tracer.dataStreamsCheckpointer
190
207
  this.appsec = new AppsecSdk(this._tracer, config)
208
+ this.llmobs = new LLMObsSDK(this._tracer, this._modules.llmobs, config)
191
209
  this._tracingInitialized = true
192
210
  }
193
211
  if (config.iast.enabled) {
@@ -196,6 +214,7 @@ class Tracer extends NoopProxy {
196
214
  } else if (this._tracingInitialized) {
197
215
  this._modules.appsec.disable()
198
216
  this._modules.iast.disable()
217
+ this._modules.llmobs.disable()
199
218
  }
200
219
 
201
220
  if (this._tracingInitialized) {
@@ -3,5 +3,6 @@ const messaging = require('./messaging')
3
3
  const storage = require('./storage')
4
4
  const graphql = require('./graphql')
5
5
  const web = require('./web')
6
+ const serverless = require('./serverless')
6
7
 
7
- module.exports = new SchemaDefinition({ messaging, storage, web, graphql })
8
+ module.exports = new SchemaDefinition({ messaging, storage, web, graphql, serverless })
@@ -0,0 +1,12 @@
1
+ const { identityService } = require('../util')
2
+
3
+ const serverless = {
4
+ server: {
5
+ 'azure-functions': {
6
+ opName: () => 'azure-functions.invoke',
7
+ serviceName: identityService
8
+ }
9
+ }
10
+ }
11
+
12
+ module.exports = serverless
@@ -3,5 +3,6 @@ const messaging = require('./messaging')
3
3
  const storage = require('./storage')
4
4
  const graphql = require('./graphql')
5
5
  const web = require('./web')
6
+ const serverless = require('./serverless')
6
7
 
7
- module.exports = new SchemaDefinition({ messaging, storage, web, graphql })
8
+ module.exports = new SchemaDefinition({ messaging, storage, web, graphql, serverless })
@@ -0,0 +1,12 @@
1
+ const { identityService } = require('../util')
2
+
3
+ const serverless = {
4
+ server: {
5
+ 'azure-functions': {
6
+ opName: () => 'azure-functions.invoke',
7
+ serviceName: identityService
8
+ }
9
+ }
10
+ }
11
+
12
+ module.exports = serverless
@@ -10,6 +10,9 @@ const { SpanStatsProcessor } = require('./span_stats')
10
10
  const startedSpans = new WeakSet()
11
11
  const finishedSpans = new WeakSet()
12
12
 
13
+ const { channel } = require('dc-polyfill')
14
+ const spanProcessCh = channel('dd-trace:span:process')
15
+
13
16
  class SpanProcessor {
14
17
  constructor (exporter, prioritySampler, config) {
15
18
  this._exporter = exporter
@@ -45,6 +48,8 @@ class SpanProcessor {
45
48
  const formattedSpan = format(span)
46
49
  this._stats.onSpanFinished(formattedSpan)
47
50
  formatted.push(formattedSpan)
51
+
52
+ spanProcessCh.publish({ span })
48
53
  } else {
49
54
  active.push(span)
50
55
  }
@@ -314,7 +314,17 @@ function updateConfig (changes, config) {
314
314
  logInjection: 'DD_LOG_INJECTION',
315
315
  headerTags: 'DD_TRACE_HEADER_TAGS',
316
316
  tags: 'DD_TAGS',
317
- 'sampler.rules': 'DD_TRACE_SAMPLING_RULES'
317
+ 'sampler.rules': 'DD_TRACE_SAMPLING_RULES',
318
+ traceEnabled: 'DD_TRACE_ENABLED',
319
+ url: 'DD_TRACE_AGENT_URL',
320
+ 'sampler.rateLimit': 'DD_TRACE_RATE_LIMIT',
321
+ queryStringObfuscation: 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP',
322
+ version: 'DD_VERSION',
323
+ env: 'DD_ENV',
324
+ service: 'DD_SERVICE',
325
+ clientIpHeader: 'DD_TRACE_CLIENT_IP_HEADER',
326
+ 'grpc.client.error.statuses': 'DD_GRPC_CLIENT_ERROR_STATUSES',
327
+ 'grpc.server.error.statuses': 'DD_GRPC_SERVER_ERROR_STATUSES'
318
328
  }
319
329
 
320
330
  const namesNeedFormatting = new Set(['DD_TAGS', 'peerServiceMapping', 'serviceMapping'])
@@ -1,108 +0,0 @@
1
- 'use strict'
2
-
3
- const { createHook, executionAsyncResource } = require('async_hooks')
4
- const { channel } = require('dc-polyfill')
5
-
6
- const beforeCh = channel('dd-trace:storage:before')
7
- const afterCh = channel('dd-trace:storage:after')
8
- const enterCh = channel('dd-trace:storage:enter')
9
-
10
- let PrivateSymbol = Symbol
11
- function makePrivateSymbol () {
12
- // eslint-disable-next-line no-new-func
13
- PrivateSymbol = new Function('name', 'return %CreatePrivateSymbol(name)')
14
- }
15
-
16
- try {
17
- makePrivateSymbol()
18
- } catch (e) {
19
- try {
20
- const v8 = require('v8')
21
- v8.setFlagsFromString('--allow-natives-syntax')
22
- makePrivateSymbol()
23
- v8.setFlagsFromString('--no-allow-natives-syntax')
24
- // eslint-disable-next-line no-empty
25
- } catch (e) {}
26
- }
27
-
28
- class AsyncResourceStorage {
29
- constructor () {
30
- this._ddResourceStore = PrivateSymbol('ddResourceStore')
31
- this._enabled = false
32
- this._hook = createHook(this._createHook())
33
- }
34
-
35
- disable () {
36
- if (!this._enabled) return
37
-
38
- this._hook.disable()
39
- this._enabled = false
40
- }
41
-
42
- getStore () {
43
- if (!this._enabled) return
44
-
45
- const resource = this._executionAsyncResource()
46
-
47
- return resource[this._ddResourceStore]
48
- }
49
-
50
- enterWith (store) {
51
- this._enable()
52
-
53
- const resource = this._executionAsyncResource()
54
-
55
- resource[this._ddResourceStore] = store
56
- enterCh.publish()
57
- }
58
-
59
- run (store, callback, ...args) {
60
- this._enable()
61
-
62
- const resource = this._executionAsyncResource()
63
- const oldStore = resource[this._ddResourceStore]
64
-
65
- resource[this._ddResourceStore] = store
66
- enterCh.publish()
67
-
68
- try {
69
- return callback(...args)
70
- } finally {
71
- resource[this._ddResourceStore] = oldStore
72
- enterCh.publish()
73
- }
74
- }
75
-
76
- _createHook () {
77
- return {
78
- init: this._init.bind(this),
79
- before () {
80
- beforeCh.publish()
81
- },
82
- after () {
83
- afterCh.publish()
84
- }
85
- }
86
- }
87
-
88
- _enable () {
89
- if (this._enabled) return
90
-
91
- this._enabled = true
92
- this._hook.enable()
93
- }
94
-
95
- _init (asyncId, type, triggerAsyncId, resource) {
96
- const currentResource = this._executionAsyncResource()
97
-
98
- if (Object.prototype.hasOwnProperty.call(currentResource, this._ddResourceStore)) {
99
- resource[this._ddResourceStore] = currentResource[this._ddResourceStore]
100
- }
101
- }
102
-
103
- _executionAsyncResource () {
104
- return executionAsyncResource() || {}
105
- }
106
- }
107
-
108
- module.exports = AsyncResourceStorage
@@ -1,5 +0,0 @@
1
- 'use strict'
2
-
3
- // TODO: default to AsyncLocalStorage when it supports triggerAsyncResource
4
-
5
- module.exports = require('./async_resource')