dd-trace 5.14.1 → 5.15.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 (68) hide show
  1. package/LICENSE-3rdparty.csv +0 -3
  2. package/README.md +8 -18
  3. package/ci/init.js +7 -0
  4. package/ext/exporters.d.ts +1 -0
  5. package/ext/exporters.js +2 -1
  6. package/ext/tags.d.ts +1 -0
  7. package/ext/tags.js +1 -0
  8. package/index.d.ts +18 -3
  9. package/initialize.mjs +52 -0
  10. package/package.json +9 -12
  11. package/packages/datadog-instrumentations/src/amqplib.js +5 -2
  12. package/packages/datadog-instrumentations/src/apollo-server-core.js +0 -1
  13. package/packages/datadog-instrumentations/src/apollo-server.js +0 -1
  14. package/packages/datadog-instrumentations/src/body-parser.js +0 -1
  15. package/packages/datadog-instrumentations/src/check_require_cache.js +67 -5
  16. package/packages/datadog-instrumentations/src/cookie-parser.js +0 -1
  17. package/packages/datadog-instrumentations/src/express.js +0 -1
  18. package/packages/datadog-instrumentations/src/graphql.js +0 -2
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  20. package/packages/datadog-instrumentations/src/helpers/register.js +5 -2
  21. package/packages/datadog-instrumentations/src/http/server.js +0 -1
  22. package/packages/datadog-instrumentations/src/jest.js +6 -3
  23. package/packages/datadog-instrumentations/src/mocha/common.js +48 -0
  24. package/packages/datadog-instrumentations/src/mocha/main.js +487 -0
  25. package/packages/datadog-instrumentations/src/mocha/utils.js +306 -0
  26. package/packages/datadog-instrumentations/src/mocha/worker.js +51 -0
  27. package/packages/datadog-instrumentations/src/mocha.js +4 -673
  28. package/packages/datadog-instrumentations/src/openai.js +188 -17
  29. package/packages/datadog-instrumentations/src/playwright.js +4 -3
  30. package/packages/datadog-instrumentations/src/router.js +1 -1
  31. package/packages/datadog-instrumentations/src/selenium.js +13 -6
  32. package/packages/datadog-plugin-mocha/src/index.js +82 -8
  33. package/packages/datadog-plugin-next/src/index.js +1 -2
  34. package/packages/datadog-plugin-openai/src/index.js +219 -73
  35. package/packages/dd-trace/src/appsec/addresses.js +4 -2
  36. package/packages/dd-trace/src/appsec/blocking.js +19 -25
  37. package/packages/dd-trace/src/appsec/channels.js +2 -1
  38. package/packages/dd-trace/src/appsec/graphql.js +10 -3
  39. package/packages/dd-trace/src/appsec/index.js +11 -4
  40. package/packages/dd-trace/src/appsec/rasp.js +35 -0
  41. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
  42. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -0
  43. package/packages/dd-trace/src/appsec/rule_manager.js +15 -25
  44. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -5
  45. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +3 -1
  46. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -1
  47. package/packages/dd-trace/src/config.js +59 -16
  48. package/packages/dd-trace/src/encode/0.4.js +47 -8
  49. package/packages/dd-trace/src/exporter.js +1 -0
  50. package/packages/dd-trace/src/flare/file.js +44 -0
  51. package/packages/dd-trace/src/flare/index.js +98 -0
  52. package/packages/dd-trace/src/log/channels.js +54 -29
  53. package/packages/dd-trace/src/log/writer.js +7 -49
  54. package/packages/dd-trace/src/opentracing/propagation/text_map.js +57 -12
  55. package/packages/dd-trace/src/plugins/index.js +1 -0
  56. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
  57. package/packages/dd-trace/src/plugins/util/test.js +6 -0
  58. package/packages/dd-trace/src/profiler.js +2 -1
  59. package/packages/dd-trace/src/profiling/config.js +1 -0
  60. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  61. package/packages/dd-trace/src/profiling/{ssi-telemetry.js → ssi-heuristics.js} +64 -36
  62. package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +4 -9
  63. package/packages/dd-trace/src/proxy.js +49 -15
  64. package/packages/dd-trace/src/ritm.js +13 -1
  65. package/packages/dd-trace/src/startup-log.js +19 -15
  66. package/packages/dd-trace/src/telemetry/index.js +6 -2
  67. package/packages/dd-trace/src/tracer.js +3 -0
  68. package/packages/dd-trace/src/plugins/util/ip_blocklist.js +0 -51
@@ -13,7 +13,7 @@ const AppsecSdk = require('./appsec/sdk')
13
13
  const dogstatsd = require('./dogstatsd')
14
14
  const NoopDogStatsDClient = require('./noop/dogstatsd')
15
15
  const spanleak = require('./spanleak')
16
- const { SSITelemetry } = require('./profiling/ssi-telemetry')
16
+ const { SSIHeuristics } = require('./profiling/ssi-heuristics')
17
17
  const telemetryLog = require('dc-polyfill').channel('datadog:telemetry:log')
18
18
 
19
19
  class LazyModule {
@@ -40,6 +40,7 @@ class Tracer extends NoopProxy {
40
40
  this._pluginManager = new PluginManager(this)
41
41
  this.dogstatsd = new NoopDogStatsDClient()
42
42
  this._tracingInitialized = false
43
+ this._flare = new LazyModule(() => require('./flare'))
43
44
 
44
45
  // these requires must work with esm bundler
45
46
  this._modules = {
@@ -90,29 +91,46 @@ class Tracer extends NoopProxy {
90
91
  }
91
92
  this._enableOrDisableTracing(config)
92
93
  })
94
+
95
+ rc.on('AGENT_CONFIG', (action, conf) => {
96
+ if (!conf?.name?.startsWith('flare-log-level.')) return
97
+
98
+ if (action === 'unapply') {
99
+ this._flare.disable()
100
+ } else if (conf.config?.log_level) {
101
+ this._flare.enable(config)
102
+ this._flare.module.prepare(conf.config.log_level)
103
+ }
104
+ })
105
+
106
+ rc.on('AGENT_TASK', (action, conf) => {
107
+ if (action === 'unapply' || !conf) return
108
+ if (conf.task_type !== 'tracer_flare' || !conf.args) return
109
+
110
+ this._flare.enable(config)
111
+ this._flare.module.send(conf.args)
112
+ })
93
113
  }
94
114
 
95
115
  if (config.isGCPFunction || config.isAzureFunction) {
96
116
  require('./serverless').maybeStartServerlessMiniAgent(config)
97
117
  }
98
118
 
99
- const ssiTelemetry = new SSITelemetry()
100
- ssiTelemetry.start()
119
+ const ssiHeuristics = new SSIHeuristics(config.profiling)
120
+ ssiHeuristics.start()
101
121
  if (config.profiling.enabled) {
102
- // do not stop tracer initialization if the profiler fails to be imported
103
- try {
104
- const profiler = require('./profiler')
105
- this._profilerStarted = profiler.start(config)
106
- } catch (e) {
107
- log.error(e)
108
- telemetryLog.publish({
109
- message: e.message,
110
- level: 'ERROR',
111
- stack_trace: e.stack
122
+ this._profilerStarted = this._startProfiler(config)
123
+ } else if (config.profiling.ssi) {
124
+ const mockProfiler = require('./profiling/ssi-telemetry-mock-profiler')
125
+ mockProfiler.start(config)
126
+
127
+ if (config.profiling.heuristicsEnabled) {
128
+ ssiHeuristics.onTriggered(() => {
129
+ mockProfiler.stop()
130
+ this._startProfiler(config)
131
+ ssiHeuristics.onTriggered()
112
132
  })
113
133
  }
114
- } else if (ssiTelemetry.enabled()) {
115
- require('./profiling/ssi-telemetry-mock-profiler').start(config)
116
134
  }
117
135
  if (!this._profilerStarted) {
118
136
  this._profilerStarted = Promise.resolve(false)
@@ -138,6 +156,22 @@ class Tracer extends NoopProxy {
138
156
  return this
139
157
  }
140
158
 
159
+ _startProfiler (config) {
160
+ // do not stop tracer initialization if the profiler fails to be imported
161
+ try {
162
+ return require('./profiler').start(config)
163
+ } catch (e) {
164
+ log.error(e)
165
+ if (telemetryLog.hasSubscribers) {
166
+ telemetryLog.publish({
167
+ message: e.message,
168
+ level: 'ERROR',
169
+ stack_trace: e.stack
170
+ })
171
+ }
172
+ }
173
+ }
174
+
141
175
  _enableOrDisableTracing (config) {
142
176
  if (config.tracing !== false) {
143
177
  if (config.appsec.enabled) {
@@ -50,8 +50,20 @@ function Hook (modules, options, onrequire) {
50
50
 
51
51
  if (patchedRequire) return
52
52
 
53
+ const _origRequire = Module.prototype.require
53
54
  patchedRequire = Module.prototype.require = function (request) {
54
- const filename = Module._resolveFilename(request, this)
55
+ /*
56
+ If resolving the filename for a `require(...)` fails, defer to the wrapped
57
+ require implementation rather than failing right away. This allows a
58
+ possibly monkey patched `require` to work.
59
+ */
60
+ let filename
61
+ try {
62
+ filename = Module._resolveFilename(request, this)
63
+ } catch (resolveErr) {
64
+ return _origRequire.apply(this, arguments)
65
+ }
66
+
55
67
  const core = filename.indexOf(path.sep) === -1
56
68
  let name, basedir, hooks
57
69
  // return known patched modules immediately
@@ -37,6 +37,23 @@ function startupLog ({ agentError } = {}) {
37
37
  return
38
38
  }
39
39
 
40
+ const out = tracerInfo({ agentError })
41
+
42
+ if (agentError) {
43
+ out.agent_error = agentError.message
44
+ }
45
+
46
+ info('DATADOG TRACER CONFIGURATION - ' + out)
47
+ if (agentError) {
48
+ warn('DATADOG TRACER DIAGNOSTIC - Agent Error: ' + agentError.message)
49
+ errors.agentError = {
50
+ code: agentError.code ? agentError.code : '',
51
+ message: `Agent Error:${agentError.message}`
52
+ }
53
+ }
54
+ }
55
+
56
+ function tracerInfo () {
40
57
  const url = config.url || `http://${config.hostname || 'localhost'}:${config.port}`
41
58
 
42
59
  const out = {
@@ -59,9 +76,6 @@ function startupLog ({ agentError } = {}) {
59
76
  out.enabled = config.enabled
60
77
  out.service = config.service
61
78
  out.agent_url = url
62
- if (agentError) {
63
- out.agent_error = agentError.message
64
- }
65
79
  out.debug = !!config.debug
66
80
  out.sample_rate = config.sampler.sampleRate
67
81
  out.sampling_rules = samplingRules
@@ -87,18 +101,7 @@ function startupLog ({ agentError } = {}) {
87
101
  // out.service_mapping
88
102
  // out.service_mapping_error
89
103
 
90
- info('DATADOG TRACER CONFIGURATION - ' + out)
91
- if (agentError) {
92
- warn('DATADOG TRACER DIAGNOSTIC - Agent Error: ' + agentError.message)
93
- errors.agentError = {
94
- code: agentError.code ? agentError.code : '',
95
- message: `Agent Error:${agentError.message}`
96
- }
97
- }
98
-
99
- config = undefined
100
- pluginManager = undefined
101
- samplingRules = undefined
104
+ return out
102
105
  }
103
106
 
104
107
  function setStartupLogConfig (aConfig) {
@@ -118,5 +121,6 @@ module.exports = {
118
121
  setStartupLogConfig,
119
122
  setStartupLogPluginManager,
120
123
  setSamplingRules,
124
+ tracerInfo,
121
125
  errors
122
126
  }
@@ -313,7 +313,8 @@ function updateConfig (changes, config) {
313
313
  sampleRate: 'DD_TRACE_SAMPLE_RATE',
314
314
  logInjection: 'DD_LOG_INJECTION',
315
315
  headerTags: 'DD_TRACE_HEADER_TAGS',
316
- tags: 'DD_TAGS'
316
+ tags: 'DD_TAGS',
317
+ 'sampler.rules': 'DD_TRACE_SAMPLING_RULES'
317
318
  }
318
319
 
319
320
  const namesNeedFormatting = new Set(['DD_TAGS', 'peerServiceMapping'])
@@ -328,9 +329,12 @@ function updateConfig (changes, config) {
328
329
  const { origin, value } = change
329
330
  const entry = { name, value, origin }
330
331
 
331
- if (Array.isArray(value)) entry.value = value.join(',')
332
332
  if (namesNeedFormatting.has(entry.name)) entry.value = formatMapForTelemetry(entry.value)
333
333
  if (entry.name === 'url' && entry.value) entry.value = entry.value.toString()
334
+ if (entry.name === 'DD_TRACE_SAMPLING_RULES') {
335
+ entry.value = JSON.stringify(entry.value)
336
+ }
337
+ if (Array.isArray(entry.value)) entry.value = value.join(',')
334
338
 
335
339
  configuration.push(entry)
336
340
  }
@@ -11,6 +11,8 @@ const { DataStreamsProcessor } = require('./datastreams/processor')
11
11
  const { DsmPathwayCodec } = require('./datastreams/pathway')
12
12
  const { DD_MAJOR } = require('../../../version')
13
13
  const DataStreamsContext = require('./data_streams_context')
14
+ const { flushStartupLogs } = require('../../datadog-instrumentations/src/check_require_cache')
15
+ const log = require('./log/writer')
14
16
 
15
17
  const SPAN_TYPE = tags.SPAN_TYPE
16
18
  const RESOURCE_NAME = tags.RESOURCE_NAME
@@ -23,6 +25,7 @@ class DatadogTracer extends Tracer {
23
25
  this._dataStreamsProcessor = new DataStreamsProcessor(config)
24
26
  this._scope = new Scope()
25
27
  setStartupLogConfig(config)
28
+ flushStartupLogs(log)
26
29
  }
27
30
 
28
31
  configure ({ env, sampler }) {
@@ -1,51 +0,0 @@
1
- 'use strict'
2
-
3
- const semver = require('semver')
4
-
5
- if (semver.satisfies(process.version, '>=14.18.0')) {
6
- const net = require('net')
7
-
8
- module.exports = net.BlockList
9
- } else {
10
- const ipaddr = require('ipaddr.js')
11
-
12
- module.exports = class BlockList {
13
- constructor () {
14
- this.v4Ranges = []
15
- this.v6Ranges = []
16
- }
17
-
18
- addSubnet (net, prefix, type) {
19
- this[type === 'ipv4' ? 'v4Ranges' : 'v6Ranges'].push(ipaddr.parseCIDR(`${net}/${prefix}`))
20
- }
21
-
22
- check (address, type) {
23
- try {
24
- let ip = ipaddr.parse(address)
25
-
26
- type = ip.kind()
27
-
28
- if (type === 'ipv6') {
29
- for (const range of this.v6Ranges) {
30
- if (ip.match(range)) return true
31
- }
32
-
33
- if (ip.isIPv4MappedAddress()) {
34
- ip = ip.toIPv4Address()
35
- type = ip.kind()
36
- }
37
- }
38
-
39
- if (type === 'ipv4') {
40
- for (const range of this.v4Ranges) {
41
- if (ip.match(range)) return true
42
- }
43
- }
44
-
45
- return false
46
- } catch {
47
- return false
48
- }
49
- }
50
- }
51
- }