dd-trace 3.38.1 → 3.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 (82) hide show
  1. package/LICENSE-3rdparty.csv +2 -2
  2. package/README.md +3 -3
  3. package/ext/kinds.d.ts +1 -0
  4. package/ext/kinds.js +2 -1
  5. package/ext/tags.d.ts +2 -1
  6. package/ext/tags.js +6 -1
  7. package/index.d.ts +9 -1
  8. package/package.json +8 -8
  9. package/packages/datadog-core/src/storage/async_resource.js +1 -1
  10. package/packages/datadog-esbuild/index.js +1 -20
  11. package/packages/datadog-instrumentations/src/cucumber.js +5 -0
  12. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +1 -2
  13. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
  14. package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
  15. package/packages/datadog-instrumentations/src/jest.js +39 -10
  16. package/packages/datadog-instrumentations/src/knex.js +24 -17
  17. package/packages/datadog-instrumentations/src/mocha.js +16 -1
  18. package/packages/datadog-instrumentations/src/next.js +58 -23
  19. package/packages/datadog-instrumentations/src/playwright.js +11 -6
  20. package/packages/datadog-instrumentations/src/restify.js +14 -1
  21. package/packages/datadog-plugin-http/src/client.js +2 -0
  22. package/packages/datadog-plugin-jest/src/index.js +11 -3
  23. package/packages/datadog-plugin-kafkajs/src/consumer.js +8 -6
  24. package/packages/datadog-plugin-kafkajs/src/producer.js +9 -6
  25. package/packages/datadog-plugin-mocha/src/index.js +7 -1
  26. package/packages/datadog-plugin-next/src/index.js +4 -3
  27. package/packages/datadog-plugin-playwright/src/index.js +4 -1
  28. package/packages/dd-trace/src/appsec/channels.js +1 -1
  29. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
  30. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-analyzer.js +60 -0
  31. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +269 -0
  32. package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +5 -2
  33. package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +22 -4
  34. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +9 -2
  35. package/packages/dd-trace/src/appsec/iast/analyzers/xcontenttype-header-missing-analyzer.js +2 -2
  36. package/packages/dd-trace/src/appsec/iast/iast-log.js +9 -4
  37. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +1 -1
  38. package/packages/dd-trace/src/appsec/iast/index.js +1 -1
  39. package/packages/dd-trace/src/appsec/iast/path-line.js +7 -2
  40. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +13 -2
  41. package/packages/dd-trace/src/appsec/iast/telemetry/index.js +1 -14
  42. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +19 -0
  43. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +2 -1
  44. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
  45. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +5 -1
  46. package/packages/dd-trace/src/appsec/recommended.json +272 -48
  47. package/packages/dd-trace/src/appsec/reporter.js +31 -34
  48. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +16 -4
  49. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -0
  50. package/packages/dd-trace/src/config.js +35 -17
  51. package/packages/dd-trace/src/datastreams/processor.js +60 -15
  52. package/packages/dd-trace/src/format.js +6 -1
  53. package/packages/dd-trace/src/git_properties.js +16 -15
  54. package/packages/dd-trace/src/iitm.js +1 -1
  55. package/packages/dd-trace/src/log/channels.js +1 -1
  56. package/packages/dd-trace/src/opentelemetry/span.js +95 -2
  57. package/packages/dd-trace/src/opentelemetry/tracer.js +9 -10
  58. package/packages/dd-trace/src/opentracing/span.js +4 -0
  59. package/packages/dd-trace/src/opentracing/span_context.js +5 -2
  60. package/packages/dd-trace/src/plugin_manager.js +1 -1
  61. package/packages/dd-trace/src/plugins/database.js +1 -1
  62. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  63. package/packages/dd-trace/src/plugins/util/ci.js +6 -19
  64. package/packages/dd-trace/src/plugins/util/git.js +2 -1
  65. package/packages/dd-trace/src/plugins/util/ip_extractor.js +7 -6
  66. package/packages/dd-trace/src/plugins/util/test.js +29 -1
  67. package/packages/dd-trace/src/plugins/util/url.js +26 -0
  68. package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -14
  69. package/packages/dd-trace/src/profiling/config.js +23 -20
  70. package/packages/dd-trace/src/profiling/profilers/events.js +161 -0
  71. package/packages/dd-trace/src/profiling/profilers/shared.js +9 -0
  72. package/packages/dd-trace/src/profiling/profilers/wall.js +84 -47
  73. package/packages/dd-trace/src/ritm.js +1 -1
  74. package/packages/dd-trace/src/span_processor.js +4 -0
  75. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  76. package/packages/dd-trace/src/telemetry/index.js +5 -1
  77. package/packages/dd-trace/src/telemetry/logs/index.js +65 -0
  78. package/packages/dd-trace/src/{appsec/iast/telemetry/log → telemetry/logs}/log-collector.js +9 -22
  79. package/packages/dd-trace/src/tracer.js +4 -2
  80. package/packages/dd-trace/src/appsec/iast/telemetry/log/index.js +0 -87
  81. package/packages/diagnostics_channel/index.js +0 -3
  82. package/packages/diagnostics_channel/src/index.js +0 -121
@@ -2,15 +2,20 @@
2
2
 
3
3
  const { storage } = require('../../../../datadog-core')
4
4
 
5
- const dc = require('../../../../diagnostics_channel')
5
+ const dc = require('dc-polyfill')
6
6
  const { HTTP_METHOD, HTTP_ROUTE, RESOURCE_NAME, SPAN_TYPE } = require('../../../../../ext/tags')
7
7
  const { WEB } = require('../../../../../ext/types')
8
8
  const runtimeMetrics = require('../../runtime_metrics')
9
9
  const telemetryMetrics = require('../../telemetry/metrics')
10
+ const { END_TIMESTAMP, THREAD_NAME, threadNamePrefix } = require('./shared')
10
11
 
11
12
  const beforeCh = dc.channel('dd-trace:storage:before')
12
13
  const enterCh = dc.channel('dd-trace:storage:enter')
14
+ const spanFinishCh = dc.channel('dd-trace:span:finish')
13
15
  const profilerTelemetryMetrics = telemetryMetrics.manager.namespace('profilers')
16
+ const threadName = `${threadNamePrefix} Event Loop`
17
+
18
+ const CachedWebTags = Symbol('NativeWallProfiler.CachedWebTags')
14
19
 
15
20
  let kSampleCount
16
21
 
@@ -24,7 +29,11 @@ function getStartedSpans (context) {
24
29
  }
25
30
 
26
31
  function generateLabels ({ context: { spanId, rootSpanId, webTags, endpoint }, timestamp }) {
27
- const labels = {}
32
+ const labels = {
33
+ [THREAD_NAME]: threadName,
34
+ // Incoming timestamps are in microseconds, we emit nanos.
35
+ [END_TIMESTAMP]: timestamp * 1000n
36
+ }
28
37
  if (spanId) {
29
38
  labels['span id'] = spanId
30
39
  }
@@ -37,16 +46,10 @@ function generateLabels ({ context: { spanId, rootSpanId, webTags, endpoint }, t
37
46
  // fallback to endpoint computed when sample was taken
38
47
  labels['trace endpoint'] = endpoint
39
48
  }
40
- // Incoming timestamps are in microseconds, we emit nanos.
41
- labels['end_timestamp_ns'] = timestamp * 1000n
42
49
 
43
50
  return labels
44
51
  }
45
52
 
46
- function getSpanContextTags (span) {
47
- return span.context()._tags
48
- }
49
-
50
53
  function isWebServerSpan (tags) {
51
54
  return tags[SPAN_TYPE] === WEB
52
55
  }
@@ -58,29 +61,6 @@ function endpointNameFromTags (tags) {
58
61
  ].filter(v => v).join(' ')
59
62
  }
60
63
 
61
- function updateContext (context, span, startedSpans, endpointCollectionEnabled) {
62
- context.spanId = span.context().toSpanId()
63
- const rootSpan = startedSpans[0]
64
- if (rootSpan) {
65
- context.rootSpanId = rootSpan.context().toSpanId()
66
- if (endpointCollectionEnabled) {
67
- // Find the first webspan starting from the end:
68
- // There might be several webspans, for example with next.js, http plugin creates a first span
69
- // and then next.js plugin creates a child span, and this child span haves the correct endpoint information.
70
- for (let i = startedSpans.length - 1; i >= 0; i--) {
71
- const tags = getSpanContextTags(startedSpans[i])
72
- if (isWebServerSpan(tags)) {
73
- context.webTags = tags
74
- // endpoint may not be determined yet, but keep it as fallback
75
- // if tags are not available anymore during serialization
76
- context.endpoint = endpointNameFromTags(tags)
77
- break
78
- }
79
- }
80
- }
81
- }
82
- }
83
-
84
64
  class NativeWallProfiler {
85
65
  constructor (options = {}) {
86
66
  this.type = 'wall'
@@ -88,12 +68,14 @@ class NativeWallProfiler {
88
68
  this._flushIntervalMillis = options.flushInterval || 60 * 1e3 // 60 seconds
89
69
  this._codeHotspotsEnabled = !!options.codeHotspotsEnabled
90
70
  this._endpointCollectionEnabled = !!options.endpointCollectionEnabled
71
+ this._withContexts = this._codeHotspotsEnabled || this._endpointCollectionEnabled
91
72
  this._v8ProfilerBugWorkaroundEnabled = !!options.v8ProfilerBugWorkaroundEnabled
92
73
  this._mapper = undefined
93
74
  this._pprof = undefined
94
75
 
95
76
  // Bind to this so the same value can be used to unsubscribe later
96
77
  this._enter = this._enter.bind(this)
78
+ this._spanFinished = this._spanFinished.bind(this)
97
79
  this._logger = options.logger
98
80
  this._started = false
99
81
  }
@@ -109,12 +91,6 @@ class NativeWallProfiler {
109
91
  start ({ mapper } = {}) {
110
92
  if (this._started) return
111
93
 
112
- if (this._codeHotspotsEnabled && !this._emittedFFMessage && this._logger) {
113
- this._logger.debug(
114
- `Wall profiler: Enable trace_show_breakdown_profiling_for_node feature flag to see code hotspots.`)
115
- this._emittedFFMessage = true
116
- }
117
-
118
94
  this._mapper = mapper
119
95
  this._pprof = require('@datadog/pprof')
120
96
  kSampleCount = this._pprof.time.constants.kSampleCount
@@ -131,21 +107,23 @@ class NativeWallProfiler {
131
107
  intervalMicros: this._samplingIntervalMicros,
132
108
  durationMillis: this._flushIntervalMillis,
133
109
  sourceMapper: this._mapper,
134
- withContexts: this._codeHotspotsEnabled,
110
+ withContexts: this._withContexts,
135
111
  lineNumbers: false,
136
112
  workaroundV8Bug: this._v8ProfilerBugWorkaroundEnabled
137
113
  })
138
114
 
139
- if (this._codeHotspotsEnabled) {
115
+ if (this._withContexts) {
140
116
  this._profilerState = this._pprof.time.getState()
141
117
  this._currentContext = {}
142
118
  this._pprof.time.setContext(this._currentContext)
143
119
  this._lastSpan = undefined
144
120
  this._lastStartedSpans = undefined
121
+ this._lastWebTags = undefined
145
122
  this._lastSampleCount = 0
146
123
 
147
124
  beforeCh.subscribe(this._enter)
148
125
  enterCh.subscribe(this._enter)
126
+ spanFinishCh.subscribe(this._spanFinished)
149
127
  }
150
128
 
151
129
  this._started = true
@@ -161,18 +139,73 @@ class NativeWallProfiler {
161
139
  this._currentContext = {}
162
140
  this._pprof.time.setContext(this._currentContext)
163
141
 
164
- if (this._lastSpan) {
165
- updateContext(context, this._lastSpan, this._lastStartedSpans, this._endpointCollectionEnabled)
166
- }
142
+ this._updateContext(context)
167
143
  }
168
144
 
169
145
  const span = getActiveSpan()
170
146
  if (span) {
147
+ const context = span.context()
171
148
  this._lastSpan = span
172
- this._lastStartedSpans = getStartedSpans(span.context())
149
+ const startedSpans = getStartedSpans(context)
150
+ this._lastStartedSpans = startedSpans
151
+ if (this._endpointCollectionEnabled) {
152
+ const cachedWebTags = span[CachedWebTags]
153
+ if (cachedWebTags === undefined) {
154
+ let found = false
155
+ // Find the first webspan starting from the end:
156
+ // There might be several webspans, for example with next.js, http plugin creates a first span
157
+ // and then next.js plugin creates a child span, and this child span has the correct endpoint information.
158
+ let nextSpanId = context._spanId
159
+ for (let i = startedSpans.length - 1; i >= 0; i--) {
160
+ const nextContext = startedSpans[i].context()
161
+ if (nextContext._spanId === nextSpanId) {
162
+ const tags = nextContext._tags
163
+ if (isWebServerSpan(tags)) {
164
+ this._lastWebTags = tags
165
+ span[CachedWebTags] = tags
166
+ found = true
167
+ break
168
+ }
169
+ nextSpanId = nextContext._parentId
170
+ }
171
+ }
172
+ if (!found) {
173
+ this._lastWebTags = undefined
174
+ span[CachedWebTags] = null // cache negative lookup result
175
+ }
176
+ } else {
177
+ this._lastWebTags = cachedWebTags
178
+ }
179
+ }
173
180
  } else {
174
181
  this._lastStartedSpans = undefined
175
182
  this._lastSpan = undefined
183
+ this._lastWebTags = undefined
184
+ }
185
+ }
186
+
187
+ _updateContext (context) {
188
+ if (!this._lastSpan) {
189
+ return
190
+ }
191
+ if (this._codeHotspotsEnabled) {
192
+ context.spanId = this._lastSpan.context().toSpanId()
193
+ const rootSpan = this._lastStartedSpans[0]
194
+ if (rootSpan) {
195
+ context.rootSpanId = rootSpan.context().toSpanId()
196
+ }
197
+ }
198
+ if (this._lastWebTags) {
199
+ context.webTags = this._lastWebTags
200
+ // endpoint may not be determined yet, but keep it as fallback
201
+ // if tags are not available anymore during serialization
202
+ context.endpoint = endpointNameFromTags(this._lastWebTags)
203
+ }
204
+ }
205
+
206
+ _spanFinished (span) {
207
+ if (span[CachedWebTags]) {
208
+ span[CachedWebTags] = undefined
176
209
  }
177
210
  }
178
211
 
@@ -188,12 +221,12 @@ class NativeWallProfiler {
188
221
 
189
222
  _stop (restart) {
190
223
  if (!this._started) return
191
- if (this._codeHotspotsEnabled) {
224
+ if (this._withContexts) {
192
225
  // update last sample context if needed
193
226
  this._enter()
194
227
  this._lastSampleCount = 0
195
228
  }
196
- const profile = this._pprof.time.stop(restart, this._codeHotspotsEnabled ? generateLabels : undefined)
229
+ const profile = this._pprof.time.stop(restart, this._withContexts ? generateLabels : undefined)
197
230
  if (restart) {
198
231
  const v8BugDetected = this._pprof.time.v8ProfilerStuckEventLoopDetected()
199
232
  if (v8BugDetected !== 0) {
@@ -215,10 +248,14 @@ class NativeWallProfiler {
215
248
  if (!this._started) return
216
249
 
217
250
  const profile = this._stop(false)
218
- if (this._codeHotspotsEnabled) {
251
+ if (this._withContexts) {
219
252
  beforeCh.unsubscribe(this._enter)
220
- enterCh.subscribe(this._enter)
253
+ enterCh.unsubscribe(this._enter)
254
+ spanFinishCh.unsubscribe(this._spanFinished)
221
255
  this._profilerState = undefined
256
+ this._lastSpan = undefined
257
+ this._lastStartedSpans = undefined
258
+ this._lastWebTags = undefined
222
259
  }
223
260
 
224
261
  this._started = false
@@ -3,7 +3,7 @@
3
3
  const path = require('path')
4
4
  const Module = require('module')
5
5
  const parse = require('module-details-from-path')
6
- const dc = require('../../diagnostics_channel')
6
+ const dc = require('dc-polyfill')
7
7
 
8
8
  const origRequire = Module.prototype.require
9
9
 
@@ -138,6 +138,10 @@ class SpanProcessor {
138
138
  }
139
139
  }
140
140
 
141
+ for (const span of trace.finished) {
142
+ span.context()._tags = {}
143
+ }
144
+
141
145
  trace.started = active
142
146
  trace.finished = []
143
147
  }
@@ -4,7 +4,7 @@ const path = require('path')
4
4
  const parse = require('module-details-from-path')
5
5
  const requirePackageJson = require('../require-package-json')
6
6
  const { sendData } = require('./send-data')
7
- const dc = require('../../../diagnostics_channel')
7
+ const dc = require('dc-polyfill')
8
8
  const { fileURLToPath } = require('url')
9
9
 
10
10
  const savedDependenciesToSend = new Set()
@@ -1,12 +1,13 @@
1
1
  'use strict'
2
2
 
3
3
  const tracerVersion = require('../../../../package.json').version
4
- const dc = require('../../../diagnostics_channel')
4
+ const dc = require('dc-polyfill')
5
5
  const os = require('os')
6
6
  const dependencies = require('./dependencies')
7
7
  const { sendData } = require('./send-data')
8
8
 
9
9
  const { manager: metricsManager } = require('./metrics')
10
+ const logs = require('./logs')
10
11
 
11
12
  const telemetryStartChannel = dc.channel('datadog:telemetry:start')
12
13
  const telemetryStopChannel = dc.channel('datadog:telemetry:stop')
@@ -139,10 +140,13 @@ function start (aConfig, thePluginManager) {
139
140
  heartbeatInterval = config.telemetry.heartbeatInterval
140
141
 
141
142
  dependencies.start(config, application, host)
143
+ logs.start(config)
144
+
142
145
  sendData(config, application, host, 'app-started', appStarted())
143
146
  heartbeat(config, application, host)
144
147
  interval = setInterval(() => {
145
148
  metricsManager.send(config, application, host)
149
+ logs.send(config, application, host)
146
150
  }, heartbeatInterval)
147
151
  interval.unref()
148
152
  process.on('beforeExit', onBeforeExit)
@@ -0,0 +1,65 @@
1
+ 'use strict'
2
+
3
+ const dc = require('dc-polyfill')
4
+ const logCollector = require('./log-collector')
5
+ const { sendData } = require('../send-data')
6
+
7
+ const telemetryLog = dc.channel('datadog:telemetry:log')
8
+
9
+ let enabled = false
10
+
11
+ /**
12
+ * Telemetry logs api defines only ERROR, WARN and DEBUG levels:
13
+ * - WARN level is enabled by default
14
+ * - DEBUG level will be possible to activate with an env var or telemetry config property
15
+ */
16
+ function isLevelEnabled (level) {
17
+ return isValidLevel(level)
18
+ }
19
+
20
+ function isValidLevel (level) {
21
+ switch (level) {
22
+ case 'ERROR':
23
+ case 'WARN':
24
+ return true
25
+ default:
26
+ return false
27
+ }
28
+ }
29
+
30
+ function onLog (log) {
31
+ if (isLevelEnabled(log?.level?.toUpperCase())) {
32
+ logCollector.add(log)
33
+ }
34
+ }
35
+
36
+ function start (config) {
37
+ if (!config.telemetry.logCollection || enabled) return
38
+
39
+ enabled = true
40
+
41
+ telemetryLog.subscribe(onLog)
42
+ }
43
+
44
+ function stop () {
45
+ enabled = false
46
+
47
+ if (telemetryLog.hasSubscribers) {
48
+ telemetryLog.unsubscribe(onLog)
49
+ }
50
+ }
51
+
52
+ function send (config, application, host) {
53
+ if (!enabled) return
54
+
55
+ const logs = logCollector.drain()
56
+ if (logs) {
57
+ sendData(config, application, host, 'logs', logs)
58
+ }
59
+ }
60
+
61
+ module.exports = {
62
+ start,
63
+ stop,
64
+ send
65
+ }
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const log = require('../../../../log')
3
+ const log = require('../../log')
4
4
 
5
5
  const logs = new Map()
6
6
 
@@ -18,37 +18,21 @@ function hashCode (hashSource) {
18
18
  }
19
19
 
20
20
  function createHash (logEntry) {
21
- if (!logEntry) return 0
22
-
23
21
  const prime = 31
24
22
  let result = ((!logEntry.level) ? 0 : hashCode(logEntry.level))
25
23
  result = (((prime * result) | 0) + ((!logEntry.message) ? 0 : hashCode(logEntry.message))) | 0
26
-
27
- // NOTE: tags are not used at the moment
28
- // result = (((prime * result) | 0) + ((!logEntry.tags) ? 0 : hashCode(logEntry.tags))) | 0
29
24
  result = (((prime * result) | 0) + ((!logEntry.stack_trace) ? 0 : hashCode(logEntry.stack_trace))) | 0
30
25
  return result
31
26
  }
32
27
 
33
- function newLogEntry (message, level, tags) {
34
- return {
35
- message,
36
- level,
37
- tags
38
- }
39
- }
40
-
41
28
  function isValid (logEntry) {
42
- return logEntry && logEntry.level && logEntry.message
29
+ return logEntry?.level && logEntry.message
43
30
  }
44
31
 
45
32
  const logCollector = {
46
33
  add (logEntry) {
47
34
  try {
48
- if (!isValid(logEntry)) {
49
- log.info('IAST log collector discarding invalid log')
50
- return
51
- }
35
+ if (!isValid(logEntry)) return false
52
36
 
53
37
  // NOTE: should errors have higher priority? and discard log entries with lower priority?
54
38
  if (logs.size >= maxEntries) {
@@ -70,11 +54,13 @@ const logCollector = {
70
54
  drain () {
71
55
  if (logs.size === 0) return
72
56
 
73
- const drained = []
74
- drained.push(...logs.values())
57
+ const drained = [...logs.values()]
75
58
 
76
59
  if (overflowedCount > 0) {
77
- drained.push(newLogEntry(`Omitted ${overflowedCount} entries due to overflowing`, 'ERROR'))
60
+ drained.push({
61
+ message: `Omitted ${overflowedCount} entries due to overflowing`,
62
+ level: 'ERROR'
63
+ })
78
64
  }
79
65
 
80
66
  this.reset()
@@ -85,6 +71,7 @@ const logCollector = {
85
71
  reset (max) {
86
72
  logs.clear()
87
73
  overflowedCount = 0
74
+
88
75
  if (max) {
89
76
  maxEntries = max
90
77
  }
@@ -31,8 +31,10 @@ class DatadogTracer extends Tracer {
31
31
 
32
32
  // todo[piochelepiotr] These two methods are not related to the tracer, but to data streams monitoring.
33
33
  // They should be moved outside of the tracer in the future.
34
- setCheckpoint (edgeTags) {
35
- const ctx = this._dataStreamsProcessor.setCheckpoint(edgeTags, DataStreamsContext.getDataStreamsContext())
34
+ setCheckpoint (edgeTags, span, payloadSize = 0) {
35
+ const ctx = this._dataStreamsProcessor.setCheckpoint(
36
+ edgeTags, span, DataStreamsContext.getDataStreamsContext(), payloadSize
37
+ )
36
38
  DataStreamsContext.setDataStreamsContext(ctx)
37
39
  return ctx
38
40
  }
@@ -1,87 +0,0 @@
1
- 'use strict'
2
-
3
- const dc = require('../../../../../../diagnostics_channel')
4
- const logCollector = require('./log-collector')
5
- const { sendData } = require('../../../../telemetry/send-data')
6
- const log = require('../../../../log')
7
-
8
- const telemetryStartChannel = dc.channel('datadog:telemetry:start')
9
- const telemetryStopChannel = dc.channel('datadog:telemetry:stop')
10
-
11
- let config, application, host, interval
12
-
13
- function publish (log) {
14
- if (log && isLevelEnabled(log.level)) {
15
- logCollector.add(log)
16
- }
17
- }
18
-
19
- function sendLogs () {
20
- try {
21
- const logs = logCollector.drain()
22
- if (logs) {
23
- sendData(config, application, host, 'logs', logs)
24
- }
25
- } catch (e) {
26
- log.error(e)
27
- }
28
- }
29
-
30
- function isLevelEnabled (level) {
31
- return isLogCollectionEnabled(config) && level !== 'DEBUG'
32
- }
33
-
34
- function isLogCollectionEnabled (config) {
35
- return config && config.telemetry && config.telemetry.logCollection
36
- }
37
-
38
- function onTelemetryStart (msg) {
39
- if (!msg || !isLogCollectionEnabled(msg.config)) {
40
- log.info('IAST telemetry logs start event received but log collection is not enabled or configuration is incorrect')
41
- return false
42
- }
43
-
44
- log.info('IAST telemetry logs starting')
45
-
46
- config = msg.config
47
- application = msg.application
48
- host = msg.host
49
-
50
- if (msg.heartbeatInterval) {
51
- interval = setInterval(sendLogs, msg.heartbeatInterval)
52
- interval.unref()
53
- }
54
-
55
- return true
56
- }
57
-
58
- function onTelemetryStop () {
59
- stop()
60
- }
61
-
62
- function start () {
63
- telemetryStartChannel.subscribe(onTelemetryStart)
64
- telemetryStopChannel.subscribe(onTelemetryStop)
65
- }
66
-
67
- function stop () {
68
- if (!isLogCollectionEnabled(config)) return
69
-
70
- log.info('IAST telemetry logs stopping')
71
-
72
- config = null
73
- application = null
74
- host = null
75
-
76
- if (telemetryStartChannel.hasSubscribers) {
77
- telemetryStartChannel.unsubscribe(onTelemetryStart)
78
- }
79
-
80
- if (telemetryStopChannel.hasSubscribers) {
81
- telemetryStopChannel.unsubscribe(onTelemetryStop)
82
- }
83
-
84
- clearInterval(interval)
85
- }
86
-
87
- module.exports = { start, stop, publish, isLevelEnabled }
@@ -1,3 +0,0 @@
1
- 'use strict'
2
-
3
- module.exports = require('./src')
@@ -1,121 +0,0 @@
1
- 'use strict'
2
-
3
- const {
4
- Channel,
5
- channel
6
- } = require('diagnostics_channel') // eslint-disable-line n/no-restricted-require
7
-
8
- const [major, minor] = process.versions.node.split('.')
9
- const channels = new WeakSet()
10
-
11
- // Our own DC with a limited subset of functionality stable across Node versions.
12
- // TODO: Move the rest of the polyfill here.
13
- // TODO: Switch to using global subscribe/unsubscribe/hasSubscribers.
14
- const dc = { channel }
15
-
16
- // Prevent going to 0 subscribers to avoid bug in Node.
17
- // See https://github.com/nodejs/node/pull/47520
18
- if (major === '19' && minor === '9') {
19
- dc.channel = function () {
20
- const ch = channel.apply(this, arguments)
21
-
22
- if (!channels.has(ch)) {
23
- const subscribe = ch.subscribe
24
- const unsubscribe = ch.unsubscribe
25
-
26
- ch.subscribe = function () {
27
- delete ch.subscribe
28
- delete ch.unsubscribe
29
-
30
- const result = subscribe.apply(this, arguments)
31
-
32
- this.subscribe(() => {}) // Keep it active forever.
33
-
34
- return result
35
- }
36
-
37
- if (ch.unsubscribe === Channel.prototype.unsubscribe) {
38
- // Needed because another subscriber could have subscribed to something
39
- // that we unsubscribe to before the library is loaded.
40
- ch.unsubscribe = function () {
41
- delete ch.subscribe
42
- delete ch.unsubscribe
43
-
44
- this.subscribe(() => {}) // Keep it active forever.
45
-
46
- return unsubscribe.apply(this, arguments)
47
- }
48
- }
49
-
50
- channels.add(ch)
51
- }
52
-
53
- return ch
54
- }
55
- }
56
-
57
- if (!Channel.prototype.runStores) {
58
- const ActiveChannelPrototype = getActiveChannelPrototype()
59
-
60
- Channel.prototype.bindStore = ActiveChannelPrototype.bindStore = function (store, transform) {
61
- if (!this._stores) {
62
- this._stores = new Map()
63
- }
64
- this._stores.set(store, transform)
65
- }
66
-
67
- Channel.prototype.unbindStore = ActiveChannelPrototype.unbindStore = function (store) {
68
- if (!this._stores) return
69
- this._stores.delete(store)
70
- }
71
-
72
- Channel.prototype.runStores = ActiveChannelPrototype.runStores = function (data, fn, thisArg, ...args) {
73
- if (!this._stores) return Reflect.apply(fn, thisArg, args)
74
-
75
- let run = () => {
76
- this.publish(data)
77
- return Reflect.apply(fn, thisArg, args)
78
- }
79
-
80
- for (const entry of this._stores.entries()) {
81
- const store = entry[0]
82
- const transform = entry[1]
83
- run = wrapStoreRun(store, data, run, transform)
84
- }
85
-
86
- return run()
87
- }
88
- }
89
-
90
- function defaultTransform (data) {
91
- return data
92
- }
93
-
94
- function wrapStoreRun (store, data, next, transform = defaultTransform) {
95
- return () => {
96
- let context
97
- try {
98
- context = transform(data)
99
- } catch (err) {
100
- process.nextTick(() => {
101
- throw err
102
- })
103
- return next()
104
- }
105
-
106
- return store.run(context, next)
107
- }
108
- }
109
-
110
- function getActiveChannelPrototype () {
111
- const dummyChannel = channel('foo')
112
- const listener = () => {}
113
-
114
- dummyChannel.subscribe(listener)
115
- const ActiveChannelPrototype = Object.getPrototypeOf(dummyChannel)
116
- dummyChannel.unsubscribe(listener)
117
-
118
- return ActiveChannelPrototype
119
- }
120
-
121
- module.exports = dc