dd-trace 4.38.1 → 4.40.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 (73) 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-graphql/src/resolve.js +4 -0
  33. package/packages/datadog-plugin-mocha/src/index.js +82 -8
  34. package/packages/datadog-plugin-next/src/index.js +1 -2
  35. package/packages/datadog-plugin-openai/src/index.js +219 -73
  36. package/packages/dd-trace/src/appsec/addresses.js +4 -2
  37. package/packages/dd-trace/src/appsec/blocking.js +19 -25
  38. package/packages/dd-trace/src/appsec/channels.js +2 -1
  39. package/packages/dd-trace/src/appsec/graphql.js +10 -3
  40. package/packages/dd-trace/src/appsec/index.js +11 -4
  41. package/packages/dd-trace/src/appsec/rasp.js +35 -0
  42. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
  43. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -0
  44. package/packages/dd-trace/src/appsec/rule_manager.js +15 -25
  45. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -5
  46. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +3 -1
  47. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -1
  48. package/packages/dd-trace/src/config.js +97 -22
  49. package/packages/dd-trace/src/constants.js +2 -0
  50. package/packages/dd-trace/src/encode/0.4.js +47 -8
  51. package/packages/dd-trace/src/exporter.js +1 -0
  52. package/packages/dd-trace/src/flare/file.js +44 -0
  53. package/packages/dd-trace/src/flare/index.js +98 -0
  54. package/packages/dd-trace/src/log/channels.js +54 -29
  55. package/packages/dd-trace/src/log/writer.js +7 -49
  56. package/packages/dd-trace/src/opentelemetry/span.js +8 -0
  57. package/packages/dd-trace/src/opentracing/propagation/text_map.js +57 -12
  58. package/packages/dd-trace/src/plugins/index.js +1 -0
  59. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
  60. package/packages/dd-trace/src/plugins/util/test.js +6 -0
  61. package/packages/dd-trace/src/priority_sampler.js +8 -4
  62. package/packages/dd-trace/src/profiler.js +2 -1
  63. package/packages/dd-trace/src/profiling/config.js +1 -0
  64. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  65. package/packages/dd-trace/src/profiling/{ssi-telemetry.js → ssi-heuristics.js} +64 -36
  66. package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +4 -9
  67. package/packages/dd-trace/src/proxy.js +49 -15
  68. package/packages/dd-trace/src/ritm.js +13 -1
  69. package/packages/dd-trace/src/sampling_rule.js +2 -1
  70. package/packages/dd-trace/src/startup-log.js +19 -15
  71. package/packages/dd-trace/src/telemetry/index.js +6 -2
  72. package/packages/dd-trace/src/tracer.js +3 -0
  73. package/packages/dd-trace/src/plugins/util/ip_blocklist.js +0 -51
@@ -2,28 +2,25 @@
2
2
 
3
3
  const telemetryMetrics = require('../telemetry/metrics')
4
4
  const profilersNamespace = telemetryMetrics.manager.namespace('profilers')
5
- const performance = require('perf_hooks').performance
6
5
  const dc = require('dc-polyfill')
7
- const { isTrue, isFalse } = require('../util')
8
6
 
9
- // If the process lived for less than 30 seconds, it's considered short-lived
10
- const DEFAULT_SHORT_LIVED_THRESHOLD = 30000
7
+ // If the process lives for at least 30 seconds, it's considered long-lived
8
+ const DEFAULT_LONG_LIVED_THRESHOLD = 30000
11
9
 
12
10
  const EnablementChoice = {
13
11
  MANUALLY_ENABLED: Symbol('SSITelemetry.EnablementChoice.MANUALLY_ENABLED'),
14
12
  SSI_ENABLED: Symbol('SSITelemetry.EnablementChoice.SSI_ENABLED'),
15
13
  SSI_NOT_ENABLED: Symbol('SSITelemetry.EnablementChoice.SSI_NOT_ENABLED'),
16
- DISABLED: Symbol('SSITelemetry.EnablementChoice.MANUALLY_DISABLED')
14
+ DISABLED: Symbol('SSITelemetry.EnablementChoice.DISABLED')
17
15
  }
18
16
  Object.freeze(EnablementChoice)
19
17
 
20
- function getEnablementChoiceFromEnv () {
21
- const { DD_PROFILING_ENABLED, DD_INJECTION_ENABLED } = process.env
22
- if (DD_INJECTION_ENABLED === undefined || isFalse(DD_PROFILING_ENABLED)) {
18
+ function getEnablementChoiceFromConfig (config) {
19
+ if (config.ssi === false || config.enabled === false) {
23
20
  return EnablementChoice.DISABLED
24
- } else if (DD_INJECTION_ENABLED.split(',').includes('profiling')) {
21
+ } else if (config.heuristicsEnabled === true) {
25
22
  return EnablementChoice.SSI_ENABLED
26
- } else if (isTrue(DD_PROFILING_ENABLED)) {
23
+ } else if (config.enabled === true) {
27
24
  return EnablementChoice.MANUALLY_ENABLED
28
25
  } else {
29
26
  return EnablementChoice.SSI_NOT_ENABLED
@@ -38,39 +35,38 @@ function enablementChoiceToTagValue (enablementChoice) {
38
35
  return 'ssi_enabled'
39
36
  case EnablementChoice.SSI_NOT_ENABLED:
40
37
  return 'not_enabled'
41
- case EnablementChoice.MANUALLY_DISABLED:
38
+ case EnablementChoice.DISABLED:
42
39
  // Can't emit this one as a tag
43
40
  throw new Error('Invalid enablement choice')
44
41
  }
45
42
  }
46
43
 
47
44
  /**
48
- * This class emits telemetry metrics about the profiler behavior under SSI. It will only emit metrics
49
- * when the application closes, and will emit the following metrics:
45
+ * This class embodies the SSI profiler-triggering heuristics and also emits telemetry metrics about
46
+ * the profiler behavior under SSI. It emits the following metrics:
50
47
  * - `number_of_profiles`: The number of profiles that were submitted
51
- * - `number_of_runtime_id`: The number of runtime IDs in the app (always 1 for Node.js)
52
- * It will also add tags describing the state of heuristics triggers, the enablement choice, and whether
53
- * actual profiles were sent (as opposed to mock profiles). There is a mock profiler that is activated
54
- * when the profiler is not enabled, and it will emit mock profile submission events at the same cadence
55
- * the profiler would, providing insight into how many profiles would've been emitted if SSI enabled
56
- * profiling. Note that telemetry is per tracer instance, and each worker thread will have its own instance.
48
+ * - `number_of_runtime_id`: The number of runtime IDs in the app (always 1 for Node.js, emitted
49
+ * once when the tags won't change for the remaineder of of the app's lifetime.)
50
+ * It will also add tags describing the state of heuristics triggers, the enablement choice, and
51
+ * whether actual profiles were sent (as opposed to mock profiles). There is a mock profiler that is
52
+ * activated when the profiler is not enabled, and it will emit mock profile submission events at
53
+ * the same cadence the profiler would, providing insight into how many profiles would've been
54
+ * emitted if SSI enabled profiling. Note that heuristics (and thus telemetry) is per tracer
55
+ * instance, and each worker thread will have its own instance.
57
56
  */
58
- class SSITelemetry {
59
- constructor ({
60
- enablementChoice = getEnablementChoiceFromEnv(),
61
- shortLivedThreshold = DEFAULT_SHORT_LIVED_THRESHOLD
62
- } = {}) {
63
- if (!Object.values(EnablementChoice).includes(enablementChoice)) {
64
- throw new Error('Invalid enablement choice')
65
- }
66
- if (typeof shortLivedThreshold !== 'number' || shortLivedThreshold <= 0) {
67
- throw new Error('Short-lived threshold must be a positive number')
57
+ class SSIHeuristics {
58
+ constructor (config) {
59
+ this.enablementChoice = getEnablementChoiceFromConfig(config)
60
+
61
+ const longLivedThreshold = config.longLivedThreshold || DEFAULT_LONG_LIVED_THRESHOLD
62
+ if (typeof longLivedThreshold !== 'number' || longLivedThreshold <= 0) {
63
+ throw new Error('Long-lived threshold must be a positive number')
68
64
  }
69
- this.enablementChoice = enablementChoice
70
- this.shortLivedThreshold = shortLivedThreshold
65
+ this.longLivedThreshold = longLivedThreshold
71
66
 
72
67
  this.hasSentProfiles = false
73
68
  this.noSpan = true
69
+ this.shortLived = true
74
70
  }
75
71
 
76
72
  enabled () {
@@ -83,7 +79,10 @@ class SSITelemetry {
83
79
  // reference point, but the tracer initialization point is more relevant, as we couldn't be
84
80
  // collecting profiles earlier anyway. The difference is not particularly significant if the
85
81
  // tracer is initialized early in the process lifetime.
86
- this.startTime = performance.now()
82
+ setTimeout(() => {
83
+ this.shortLived = false
84
+ this._maybeTriggered()
85
+ }, this.longLivedThreshold).unref()
87
86
 
88
87
  this._onSpanCreated = this._onSpanCreated.bind(this)
89
88
  this._onProfileSubmitted = this._onProfileSubmitted.bind(this)
@@ -97,8 +96,31 @@ class SSITelemetry {
97
96
  }
98
97
  }
99
98
 
99
+ onTriggered (callback) {
100
+ switch (typeof callback) {
101
+ case 'undefined':
102
+ case 'function':
103
+ this.triggeredCallback = callback
104
+ process.nextTick(() => {
105
+ this._maybeTriggered()
106
+ })
107
+ break
108
+ default:
109
+ throw new TypeError('callback must be a function or undefined')
110
+ }
111
+ }
112
+
113
+ _maybeTriggered () {
114
+ if (!this.shortLived && !this.noSpan) {
115
+ if (typeof this.triggeredCallback === 'function') {
116
+ this.triggeredCallback.call(null)
117
+ }
118
+ }
119
+ }
120
+
100
121
  _onSpanCreated () {
101
122
  this.noSpan = false
123
+ this._maybeTriggered()
102
124
  dc.unsubscribe('dd-trace:span:start', this._onSpanCreated)
103
125
  }
104
126
 
@@ -121,7 +143,7 @@ class SSITelemetry {
121
143
  if (this.noSpan) {
122
144
  decision.push('no_span')
123
145
  }
124
- if (performance.now() - this.startTime < this.shortLivedThreshold) {
146
+ if (this.shortLived) {
125
147
  decision.push('short_lived')
126
148
  }
127
149
  if (decision.length === 0) {
@@ -138,8 +160,14 @@ class SSITelemetry {
138
160
  this._profileCount = profilersNamespace.count('ssi_heuristic.number_of_profiles', tags)
139
161
  this._runtimeIdCount = profilersNamespace.count('ssi_heuristic.number_of_runtime_id', tags)
140
162
 
141
- if (!this._emittedRuntimeId && decision[0] === 'triggered') {
142
- // Tags won't change anymore, so we can emit the runtime ID metric now
163
+ if (
164
+ !this._emittedRuntimeId &&
165
+ decision[0] === 'triggered' &&
166
+ // When enablement choice is SSI_ENABLED, hasSentProfiles can transition from false to true when the
167
+ // profiler gets started and the first profile is submitted, so we have to wait for it.
168
+ (this.enablementChoice !== EnablementChoice.SSI_ENABLED || this.hasSentProfiles)
169
+ ) {
170
+ // Tags won't change anymore, so we can emit the runtime ID metric now.
143
171
  this._emittedRuntimeId = true
144
172
  this._runtimeIdCount.inc()
145
173
  }
@@ -164,4 +192,4 @@ class SSITelemetry {
164
192
  }
165
193
  }
166
194
 
167
- module.exports = { SSITelemetry, EnablementChoice }
195
+ module.exports = { SSIHeuristics, EnablementChoice }
@@ -12,16 +12,11 @@ module.exports = {
12
12
  // Copied from packages/dd-trace/src/profiler.js
13
13
  const flushInterval = coalesce(config.interval, Number(DD_PROFILING_UPLOAD_PERIOD) * 1000, 65 * 1000)
14
14
 
15
- function scheduleProfileSubmit () {
16
- timerId = setTimeout(emitProfileSubmit, flushInterval)
17
- }
18
-
19
- function emitProfileSubmit () {
15
+ timerId = setTimeout(() => {
20
16
  profileSubmittedChannel.publish()
21
- scheduleProfileSubmit()
22
- }
23
-
24
- scheduleProfileSubmit()
17
+ timerId.refresh()
18
+ }, flushInterval)
19
+ timerId.unref()
25
20
  },
26
21
 
27
22
  stop: () => {
@@ -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
@@ -64,7 +64,7 @@ function serviceLocator (span) {
64
64
  }
65
65
 
66
66
  class SamplingRule {
67
- constructor ({ name, service, resource, tags, sampleRate = 1.0, maxPerSecond } = {}) {
67
+ constructor ({ name, service, resource, tags, sampleRate = 1.0, provenance = undefined, maxPerSecond } = {}) {
68
68
  this.matchers = []
69
69
 
70
70
  if (name) {
@@ -82,6 +82,7 @@ class SamplingRule {
82
82
 
83
83
  this._sampler = new Sampler(sampleRate)
84
84
  this._limiter = undefined
85
+ this.provenance = provenance
85
86
 
86
87
  if (Number.isFinite(maxPerSecond)) {
87
88
  this._limiter = new RateLimiter(maxPerSecond)
@@ -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
- }