dd-trace 4.52.0 → 4.53.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 (144) hide show
  1. package/LICENSE-3rdparty.csv +8 -2
  2. package/ci/init.js +16 -0
  3. package/index.d.ts +31 -13
  4. package/init.js +4 -68
  5. package/loader-hook.mjs +4 -0
  6. package/package.json +16 -11
  7. package/packages/datadog-core/src/storage.js +39 -2
  8. package/packages/datadog-instrumentations/src/aerospike.js +1 -1
  9. package/packages/datadog-instrumentations/src/cucumber.js +29 -3
  10. package/packages/datadog-instrumentations/src/express.js +38 -4
  11. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +3 -3
  12. package/packages/datadog-instrumentations/src/helpers/hooks.js +0 -1
  13. package/packages/datadog-instrumentations/src/helpers/register.js +3 -4
  14. package/packages/datadog-instrumentations/src/http/client.js +1 -1
  15. package/packages/datadog-instrumentations/src/jest.js +27 -8
  16. package/packages/datadog-instrumentations/src/mocha/utils.js +2 -1
  17. package/packages/datadog-instrumentations/src/mysql2.js +13 -8
  18. package/packages/datadog-instrumentations/src/next.js +7 -4
  19. package/packages/datadog-instrumentations/src/passport-http.js +2 -14
  20. package/packages/datadog-instrumentations/src/passport-local.js +2 -14
  21. package/packages/datadog-instrumentations/src/passport-utils.js +43 -19
  22. package/packages/datadog-instrumentations/src/pg.js +6 -6
  23. package/packages/datadog-instrumentations/src/playwright.js +17 -4
  24. package/packages/datadog-instrumentations/src/router.js +97 -1
  25. package/packages/datadog-instrumentations/src/sequelize.js +9 -4
  26. package/packages/datadog-instrumentations/src/url.js +4 -0
  27. package/packages/datadog-instrumentations/src/vitest.js +27 -2
  28. package/packages/datadog-plugin-avsc/src/schema_iterator.js +8 -3
  29. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +154 -0
  30. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -1
  31. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
  32. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
  33. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
  34. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -1
  35. package/packages/datadog-plugin-aws-sdk/src/util.js +92 -0
  36. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
  37. package/packages/datadog-plugin-cucumber/src/index.js +39 -4
  38. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +3 -3
  39. package/packages/datadog-plugin-grpc/src/client.js +2 -2
  40. package/packages/datadog-plugin-grpc/src/util.js +1 -1
  41. package/packages/datadog-plugin-jest/src/index.js +39 -4
  42. package/packages/datadog-plugin-mocha/src/index.js +36 -2
  43. package/packages/datadog-plugin-oracledb/src/index.js +1 -1
  44. package/packages/datadog-plugin-vitest/src/index.js +34 -2
  45. package/packages/datadog-shimmer/src/shimmer.js +8 -4
  46. package/packages/dd-trace/src/appsec/addresses.js +3 -0
  47. package/packages/dd-trace/src/appsec/blocked_templates.js +1 -1
  48. package/packages/dd-trace/src/appsec/channels.js +1 -0
  49. package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +4 -0
  50. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
  51. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +1 -1
  52. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +1 -1
  53. package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +10 -3
  54. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +4 -0
  55. package/packages/dd-trace/src/appsec/iast/analyzers/template-injection-analyzer.js +4 -0
  56. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +6 -19
  57. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +3 -3
  58. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +64 -3
  59. package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +2 -1
  60. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +2 -2
  61. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
  62. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +32 -37
  63. package/packages/dd-trace/src/appsec/index.js +16 -10
  64. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +1 -0
  65. package/packages/dd-trace/src/appsec/remote_config/index.js +25 -1
  66. package/packages/dd-trace/src/appsec/reporter.js +3 -1
  67. package/packages/dd-trace/src/appsec/sdk/track_event.js +32 -19
  68. package/packages/dd-trace/src/appsec/telemetry.js +10 -0
  69. package/packages/dd-trace/src/appsec/user_tracking.js +168 -0
  70. package/packages/dd-trace/src/azure_metadata.js +4 -4
  71. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +5 -4
  72. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +39 -3
  73. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
  74. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
  75. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +1 -1
  76. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
  77. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +29 -9
  78. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -2
  79. package/packages/dd-trace/src/config.js +24 -32
  80. package/packages/dd-trace/src/constants.js +1 -0
  81. package/packages/dd-trace/src/crashtracking/crashtracker.js +3 -2
  82. package/packages/dd-trace/src/datastreams/processor.js +4 -6
  83. package/packages/dd-trace/src/datastreams/writer.js +6 -5
  84. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +80 -0
  85. package/packages/dd-trace/src/debugger/devtools_client/config.js +3 -1
  86. package/packages/dd-trace/src/debugger/devtools_client/defaults.js +6 -0
  87. package/packages/dd-trace/src/debugger/devtools_client/index.js +63 -8
  88. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +10 -67
  89. package/packages/dd-trace/src/debugger/devtools_client/send.js +2 -1
  90. package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -1
  91. package/packages/dd-trace/src/debugger/devtools_client/status.js +4 -4
  92. package/packages/dd-trace/src/debugger/index.js +14 -10
  93. package/packages/dd-trace/src/dogstatsd.js +2 -2
  94. package/packages/dd-trace/src/encode/0.4.js +23 -78
  95. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +0 -32
  96. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -2
  97. package/packages/dd-trace/src/encode/span-stats.js +0 -30
  98. package/packages/dd-trace/src/exporters/agent/writer.js +3 -3
  99. package/packages/dd-trace/src/exporters/common/request.js +1 -1
  100. package/packages/dd-trace/src/exporters/span-stats/writer.js +1 -1
  101. package/packages/dd-trace/src/flare/index.js +1 -1
  102. package/packages/dd-trace/src/guardrails/index.js +64 -0
  103. package/packages/dd-trace/src/guardrails/log.js +32 -0
  104. package/packages/dd-trace/src/guardrails/telemetry.js +78 -0
  105. package/packages/dd-trace/src/guardrails/util.js +10 -0
  106. package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -2
  107. package/packages/dd-trace/src/llmobs/storage.js +2 -3
  108. package/packages/dd-trace/src/llmobs/writers/base.js +2 -2
  109. package/packages/dd-trace/src/{encode → msgpack}/chunk.js +8 -5
  110. package/packages/dd-trace/src/msgpack/encoder.js +309 -0
  111. package/packages/dd-trace/src/msgpack/index.js +6 -0
  112. package/packages/dd-trace/src/opentelemetry/context_manager.js +2 -2
  113. package/packages/dd-trace/src/opentracing/propagation/text_map.js +12 -9
  114. package/packages/dd-trace/src/opentracing/span.js +1 -1
  115. package/packages/dd-trace/src/opentracing/tracer.js +2 -2
  116. package/packages/dd-trace/src/plugin_manager.js +4 -2
  117. package/packages/dd-trace/src/plugins/ci_plugin.js +47 -4
  118. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  119. package/packages/dd-trace/src/plugins/tracing.js +1 -1
  120. package/packages/dd-trace/src/plugins/util/git.js +7 -7
  121. package/packages/dd-trace/src/plugins/util/test.js +36 -3
  122. package/packages/dd-trace/src/plugins/util/web.js +2 -2
  123. package/packages/dd-trace/src/profiling/config.js +3 -0
  124. package/packages/dd-trace/src/profiling/exporters/agent.js +9 -68
  125. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +76 -0
  126. package/packages/dd-trace/src/profiling/exporters/file.js +8 -4
  127. package/packages/dd-trace/src/profiling/profiler.js +62 -10
  128. package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +22 -12
  129. package/packages/dd-trace/src/profiling/profilers/events.js +47 -8
  130. package/packages/dd-trace/src/profiling/profilers/wall.js +2 -17
  131. package/packages/dd-trace/src/profiling/webspan-utils.js +23 -0
  132. package/packages/dd-trace/src/proxy.js +7 -2
  133. package/packages/dd-trace/src/runtime_metrics.js +107 -4
  134. package/packages/dd-trace/src/serverless.js +1 -1
  135. package/packages/dd-trace/src/span_processor.js +10 -10
  136. package/packages/dd-trace/src/tagger.js +1 -1
  137. package/packages/dd-trace/src/telemetry/index.js +1 -0
  138. package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
  139. package/packages/dd-trace/src/telemetry/logs/log-collector.js +10 -2
  140. package/packages/dd-trace/src/telemetry/send-data.js +2 -2
  141. package/packages/dd-trace/src/util.js +5 -16
  142. package/packages/datadog-instrumentations/src/qs.js +0 -24
  143. package/packages/dd-trace/src/appsec/passport.js +0 -110
  144. package/packages/dd-trace/src/telemetry/init-telemetry.js +0 -75
@@ -55,7 +55,7 @@ function ackEmitting ({ id: probeId, version }) {
55
55
  }
56
56
 
57
57
  function ackError (err, { id: probeId, version }) {
58
- log.error(err)
58
+ log.error('[debugger:devtools_client] ackError', err)
59
59
 
60
60
  onlyUniqueUpdates(STATUSES.ERROR, probeId, version, () => {
61
61
  const payload = statusPayload(probeId, version, STATUSES.ERROR)
@@ -87,16 +87,16 @@ function send (payload) {
87
87
  }
88
88
 
89
89
  request(form, options, (err) => {
90
- if (err) log.error(err)
90
+ if (err) log.error('[debugger:devtools_client] Error sending debugger payload', err)
91
91
  })
92
92
  }
93
93
 
94
- function statusPayload (probeId, version, status) {
94
+ function statusPayload (probeId, probeVersion, status) {
95
95
  return {
96
96
  ddsource,
97
97
  service,
98
98
  debugger: {
99
- diagnostics: { probeId, runtimeId, version, status }
99
+ diagnostics: { probeId, runtimeId, probeVersion, status }
100
100
  }
101
101
  }
102
102
  }
@@ -18,7 +18,7 @@ module.exports = {
18
18
  function start (config, rc) {
19
19
  if (worker !== null) return
20
20
 
21
- log.debug('Starting Dynamic Instrumentation client...')
21
+ log.debug('[debugger] Starting Dynamic Instrumentation client...')
22
22
 
23
23
  const rcAckCallbacks = new Map()
24
24
  const rcChannel = new MessageChannel()
@@ -33,14 +33,14 @@ function start (config, rc) {
33
33
  const ack = rcAckCallbacks.get(ackId)
34
34
  if (ack === undefined) {
35
35
  // This should never happen, but just in case something changes in the future, we should guard against it
36
- log.error(`Received an unknown ackId: ${ackId}`)
37
- if (error) log.error(error)
36
+ log.error('[debugger] Received an unknown ackId: %s', ackId)
37
+ if (error) log.error('[debugger] Error starting Dynamic Instrumentation client', error)
38
38
  return
39
39
  }
40
40
  ack(error)
41
41
  rcAckCallbacks.delete(ackId)
42
42
  })
43
- rcChannel.port2.on('messageerror', (err) => log.error(err))
43
+ rcChannel.port2.on('messageerror', (err) => log.error('[debugger] received "messageerror" on RC port', err))
44
44
 
45
45
  worker = new Worker(
46
46
  join(__dirname, 'devtools_client', 'index.js'),
@@ -57,19 +57,17 @@ function start (config, rc) {
57
57
  }
58
58
  )
59
59
 
60
- worker.unref()
61
-
62
60
  worker.on('online', () => {
63
- log.debug(`Dynamic Instrumentation worker thread started successfully (thread id: ${worker.threadId})`)
61
+ log.debug('[debugger] Dynamic Instrumentation worker thread started successfully (thread id: %d)', worker.threadId)
64
62
  })
65
63
 
66
- worker.on('error', (err) => log.error(err))
67
- worker.on('messageerror', (err) => log.error(err))
64
+ worker.on('error', (err) => log.error('[debugger] worker thread error', err))
65
+ worker.on('messageerror', (err) => log.error('[debugger] received "messageerror" from worker', err))
68
66
 
69
67
  worker.on('exit', (code) => {
70
68
  const error = new Error(`Dynamic Instrumentation worker thread exited unexpectedly with code ${code}`)
71
69
 
72
- log.error(error)
70
+ log.error('[debugger] worker thread exited unexpectedly', error)
73
71
 
74
72
  // Be nice, clean up now that the worker thread encounted an issue and we can't continue
75
73
  rc.removeProductHandler('LIVE_DEBUGGING')
@@ -80,6 +78,12 @@ function start (config, rc) {
80
78
  rcAckCallbacks.delete(ackId)
81
79
  }
82
80
  })
81
+
82
+ worker.unref()
83
+ rcChannel.port1.unref()
84
+ rcChannel.port2.unref()
85
+ configChannel.port1.unref()
86
+ configChannel.port2.unref()
83
87
  }
84
88
 
85
89
  function configure (config) {
@@ -71,7 +71,7 @@ class DogStatsDClient {
71
71
  const buffer = Buffer.concat(queue)
72
72
  request(buffer, this._httpOptions, (err) => {
73
73
  if (err) {
74
- log.error('HTTP error from agent: ' + err.stack)
74
+ log.error('DogStatsDClient: HTTP error from agent: %s', err.message, err)
75
75
  if (err.status === 404) {
76
76
  // Inside this if-block, we have connectivity to the agent, but
77
77
  // we're not getting a 200 from the proxy endpoint. If it's a 404,
@@ -89,7 +89,7 @@ class DogStatsDClient {
89
89
  this._sendUdpFromQueue(queue, this._host, this._family)
90
90
  } else {
91
91
  lookup(this._host, (err, address, family) => {
92
- if (err) return log.error(err)
92
+ if (err) return log.error('DogStatsDClient: Host not found', err)
93
93
  this._sendUdpFromQueue(queue, address, family)
94
94
  })
95
95
  }
@@ -1,26 +1,20 @@
1
1
  'use strict'
2
2
 
3
3
  const { truncateSpan, normalizeSpan } = require('./tags-processors')
4
- const Chunk = require('./chunk')
4
+ const { Chunk, MsgpackEncoder } = require('../msgpack')
5
5
  const log = require('../log')
6
6
  const { isTrue } = require('../util')
7
7
  const coalesce = require('koalas')
8
8
 
9
9
  const SOFT_LIMIT = 8 * 1024 * 1024 // 8MB
10
10
 
11
- const float64Array = new Float64Array(1)
12
- const uInt8Float64Array = new Uint8Array(float64Array.buffer)
13
-
14
- float64Array[0] = -1
15
-
16
- const bigEndian = uInt8Float64Array[7] === 0
17
-
18
11
  function formatSpan (span) {
19
12
  return normalizeSpan(truncateSpan(span, false))
20
13
  }
21
14
 
22
15
  class AgentEncoder {
23
16
  constructor (writer, limit = SOFT_LIMIT) {
17
+ this._msgpack = new MsgpackEncoder()
24
18
  this._limit = limit
25
19
  this._traceBytes = new Chunk()
26
20
  this._stringBytes = new Chunk()
@@ -84,11 +78,11 @@ class AgentEncoder {
84
78
  bytes.reserve(1)
85
79
 
86
80
  if (span.type && span.meta_struct) {
87
- bytes.buffer[bytes.length++] = 0x8d
81
+ bytes.buffer[bytes.length - 1] = 0x8d
88
82
  } else if (span.type || span.meta_struct) {
89
- bytes.buffer[bytes.length++] = 0x8c
83
+ bytes.buffer[bytes.length - 1] = 0x8c
90
84
  } else {
91
- bytes.buffer[bytes.length++] = 0x8b
85
+ bytes.buffer[bytes.length - 1] = 0x8b
92
86
  }
93
87
 
94
88
  if (span.type) {
@@ -135,43 +129,31 @@ class AgentEncoder {
135
129
  this._cacheString('')
136
130
  }
137
131
 
138
- _encodeArrayPrefix (bytes, value) {
139
- const length = value.length
140
- const offset = bytes.length
132
+ _encodeBuffer (bytes, buffer) {
133
+ this._msgpack.encodeBin(bytes, buffer)
134
+ }
141
135
 
142
- bytes.reserve(5)
143
- bytes.length += 5
136
+ _encodeBool (bytes, value) {
137
+ this._msgpack.encodeBoolean(bytes, value)
138
+ }
144
139
 
145
- bytes.buffer[offset] = 0xdd
146
- bytes.buffer[offset + 1] = length >> 24
147
- bytes.buffer[offset + 2] = length >> 16
148
- bytes.buffer[offset + 3] = length >> 8
149
- bytes.buffer[offset + 4] = length
140
+ _encodeArrayPrefix (bytes, value) {
141
+ this._msgpack.encodeArrayPrefix(bytes, value)
150
142
  }
151
143
 
152
144
  _encodeMapPrefix (bytes, keysLength) {
153
- const offset = bytes.length
154
-
155
- bytes.reserve(5)
156
- bytes.length += 5
157
- bytes.buffer[offset] = 0xdf
158
- bytes.buffer[offset + 1] = keysLength >> 24
159
- bytes.buffer[offset + 2] = keysLength >> 16
160
- bytes.buffer[offset + 3] = keysLength >> 8
161
- bytes.buffer[offset + 4] = keysLength
145
+ this._msgpack.encodeMapPrefix(bytes, keysLength)
162
146
  }
163
147
 
164
148
  _encodeByte (bytes, value) {
165
- bytes.reserve(1)
166
-
167
- bytes.buffer[bytes.length++] = value
149
+ this._msgpack.encodeByte(bytes, value)
168
150
  }
169
151
 
152
+ // TODO: Use BigInt instead.
170
153
  _encodeId (bytes, id) {
171
154
  const offset = bytes.length
172
155
 
173
156
  bytes.reserve(9)
174
- bytes.length += 9
175
157
 
176
158
  id = id.toArray()
177
159
 
@@ -186,36 +168,16 @@ class AgentEncoder {
186
168
  bytes.buffer[offset + 8] = id[7]
187
169
  }
188
170
 
189
- _encodeInteger (bytes, value) {
190
- const offset = bytes.length
191
-
192
- bytes.reserve(5)
193
- bytes.length += 5
171
+ _encodeNumber (bytes, value) {
172
+ this._msgpack.encodeNumber(bytes, value)
173
+ }
194
174
 
195
- bytes.buffer[offset] = 0xce
196
- bytes.buffer[offset + 1] = value >> 24
197
- bytes.buffer[offset + 2] = value >> 16
198
- bytes.buffer[offset + 3] = value >> 8
199
- bytes.buffer[offset + 4] = value
175
+ _encodeInteger (bytes, value) {
176
+ this._msgpack.encodeInteger(bytes, value)
200
177
  }
201
178
 
202
179
  _encodeLong (bytes, value) {
203
- const offset = bytes.length
204
- const hi = (value / Math.pow(2, 32)) >> 0
205
- const lo = value >>> 0
206
-
207
- bytes.reserve(9)
208
- bytes.length += 9
209
-
210
- bytes.buffer[offset] = 0xcf
211
- bytes.buffer[offset + 1] = hi >> 24
212
- bytes.buffer[offset + 2] = hi >> 16
213
- bytes.buffer[offset + 3] = hi >> 8
214
- bytes.buffer[offset + 4] = hi
215
- bytes.buffer[offset + 5] = lo >> 24
216
- bytes.buffer[offset + 6] = lo >> 16
217
- bytes.buffer[offset + 7] = lo >> 8
218
- bytes.buffer[offset + 8] = lo
180
+ this._msgpack.encodeLong(bytes, value)
219
181
  }
220
182
 
221
183
  _encodeMap (bytes, value) {
@@ -252,23 +214,7 @@ class AgentEncoder {
252
214
  }
253
215
 
254
216
  _encodeFloat (bytes, value) {
255
- float64Array[0] = value
256
-
257
- const offset = bytes.length
258
- bytes.reserve(9)
259
- bytes.length += 9
260
-
261
- bytes.buffer[offset] = 0xcb
262
-
263
- if (bigEndian) {
264
- for (let i = 0; i <= 7; i++) {
265
- bytes.buffer[offset + i + 1] = uInt8Float64Array[i]
266
- }
267
- } else {
268
- for (let i = 7; i >= 0; i--) {
269
- bytes.buffer[bytes.length - i - 1] = uInt8Float64Array[i]
270
- }
271
- }
217
+ this._msgpack.encodeFloat(bytes, value)
272
218
  }
273
219
 
274
220
  _encodeMetaStruct (bytes, value) {
@@ -294,7 +240,6 @@ class AgentEncoder {
294
240
  const offset = bytes.length
295
241
 
296
242
  bytes.reserve(prefixLength)
297
- bytes.length += prefixLength
298
243
 
299
244
  this._encodeObject(bytes, value)
300
245
 
@@ -251,37 +251,6 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
251
251
  }
252
252
  }
253
253
 
254
- _encodeNumber (bytes, value) {
255
- if (Math.floor(value) !== value) { // float 64
256
- return this._encodeFloat(bytes, value)
257
- }
258
- return this._encodeLong(bytes, value)
259
- }
260
-
261
- _encodeLong (bytes, value) {
262
- const isPositive = value >= 0
263
-
264
- const hi = isPositive ? (value / Math.pow(2, 32)) >> 0 : Math.floor(value / Math.pow(2, 32))
265
- const lo = value >>> 0
266
- const flag = isPositive ? 0xcf : 0xd3
267
-
268
- const offset = bytes.length
269
-
270
- // int 64
271
- bytes.reserve(9)
272
- bytes.length += 9
273
-
274
- bytes.buffer[offset] = flag
275
- bytes.buffer[offset + 1] = hi >> 24
276
- bytes.buffer[offset + 2] = hi >> 16
277
- bytes.buffer[offset + 3] = hi >> 8
278
- bytes.buffer[offset + 4] = hi
279
- bytes.buffer[offset + 5] = lo >> 24
280
- bytes.buffer[offset + 6] = lo >> 16
281
- bytes.buffer[offset + 7] = lo >> 8
282
- bytes.buffer[offset + 8] = lo
283
- }
284
-
285
254
  _encode (bytes, trace) {
286
255
  if (this._isReset) {
287
256
  this._encodePayloadStart(bytes)
@@ -380,7 +349,6 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
380
349
  // Get offset of the events list to update the length of the array when calling `makePayload`
381
350
  this._eventsOffset = bytes.length
382
351
  bytes.reserve(5)
383
- bytes.length += 5
384
352
  }
385
353
 
386
354
  reset () {
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
  const { AgentEncoder } = require('./0.4')
3
- const Chunk = require('./chunk')
3
+ const { Chunk } = require('../msgpack')
4
4
 
5
5
  const {
6
6
  distributionMetric,
@@ -82,7 +82,6 @@ class CoverageCIVisibilityEncoder extends AgentEncoder {
82
82
  // Get offset of the coverages list to update the length of the array when calling `makePayload`
83
83
  this._coveragesOffset = bytes.length
84
84
  bytes.reserve(5)
85
- bytes.length += 5
86
85
  }
87
86
 
88
87
  makePayload () {
@@ -22,10 +22,6 @@ function truncate (value, maxLength, suffix = '') {
22
22
  }
23
23
 
24
24
  class SpanStatsEncoder extends AgentEncoder {
25
- _encodeBool (bytes, value) {
26
- this._encodeByte(bytes, value ? 0xc3 : 0xc2)
27
- }
28
-
29
25
  makePayload () {
30
26
  const traceSize = this._traceBytes.length
31
27
  const buffer = Buffer.allocUnsafe(traceSize)
@@ -34,32 +30,6 @@ class SpanStatsEncoder extends AgentEncoder {
34
30
  return buffer
35
31
  }
36
32
 
37
- _encodeMapPrefix (bytes, length) {
38
- const offset = bytes.length
39
-
40
- bytes.reserve(1)
41
- bytes.length += 1
42
-
43
- bytes.buffer[offset] = 0x80 + length
44
- }
45
-
46
- _encodeBuffer (bytes, buffer) {
47
- const length = buffer.length
48
- const offset = bytes.length
49
-
50
- bytes.reserve(5)
51
- bytes.length += 5
52
-
53
- bytes.buffer[offset] = 0xc6
54
- bytes.buffer[offset + 1] = length >> 24
55
- bytes.buffer[offset + 2] = length >> 16
56
- bytes.buffer[offset + 3] = length >> 8
57
- bytes.buffer[offset + 4] = length
58
-
59
- buffer.copy(bytes.buffer, offset + 5)
60
- bytes.length += length
61
- }
62
-
63
33
  _encodeStat (bytes, stat) {
64
34
  this._encodeMapPrefix(bytes, 12)
65
35
 
@@ -41,17 +41,17 @@ class Writer extends BaseWriter {
41
41
  startupLog({ agentError: err })
42
42
 
43
43
  if (err) {
44
- log.error(err)
44
+ log.error('Error sending payload to the agent (status code: %s)', err.status, err)
45
45
  done()
46
46
  return
47
47
  }
48
48
 
49
- log.debug(`Response from the agent: ${res}`)
49
+ log.debug('Response from the agent: %s', res)
50
50
 
51
51
  try {
52
52
  this._prioritySampler.update(JSON.parse(res).rate_by_service)
53
53
  } catch (e) {
54
- log.error(e)
54
+ log.error('Error updating prioritySampler rates', e)
55
55
 
56
56
  runtimeMetrics.increment(`${METRIC_PREFIX}.errors`, true)
57
57
  runtimeMetrics.increment(`${METRIC_PREFIX}.errors.by.name`, `name:${e.name}`, true)
@@ -86,7 +86,7 @@ function request (data, options, callback) {
86
86
  if (isGzip) {
87
87
  zlib.gunzip(buffer, (err, result) => {
88
88
  if (err) {
89
- log.error(`Could not gunzip response: ${err.message}`)
89
+ log.error('Could not gunzip response: %s', err.message)
90
90
  callback(null, '', res.statusCode)
91
91
  } else {
92
92
  callback(null, result.toString(), res.statusCode)
@@ -16,7 +16,7 @@ class Writer extends BaseWriter {
16
16
  _sendPayload (data, _, done) {
17
17
  makeRequest(data, this._url, (err, res) => {
18
18
  if (err) {
19
- log.error(err)
19
+ log.error('Error sending span stats', err)
20
20
  done()
21
21
  return
22
22
  }
@@ -83,7 +83,7 @@ const flare = {
83
83
  headers: form.getHeaders()
84
84
  }, (err) => {
85
85
  if (err) {
86
- log.error(err)
86
+ log.error('Error sending flare payload', err)
87
87
  }
88
88
  })
89
89
  }
@@ -0,0 +1,64 @@
1
+ 'use strict'
2
+
3
+ /* eslint-disable no-var */
4
+
5
+ var path = require('path')
6
+ var Module = require('module')
7
+ var isTrue = require('./util').isTrue
8
+ var log = require('./log')
9
+ var telemetry = require('./telemetry')
10
+ var nodeVersion = require('../../../../version')
11
+
12
+ var NODE_MAJOR = nodeVersion.NODE_MAJOR
13
+
14
+ function guard (fn) {
15
+ var initBailout = false
16
+ var clobberBailout = false
17
+ var forced = isTrue(process.env.DD_INJECT_FORCE)
18
+ var engines = require('../../../../package.json').engines
19
+ var minMajor = parseInt(engines.node.replace(/[^0-9]/g, ''))
20
+ var version = process.versions.node
21
+
22
+ if (process.env.DD_INJECTION_ENABLED) {
23
+ // If we're running via single-step install, and we're in the app's
24
+ // node_modules, then we should not initialize the tracer. This prevents
25
+ // single-step-installed tracer from clobbering the manually-installed tracer.
26
+ var resolvedInApp
27
+ var entrypoint = process.argv[1]
28
+ try {
29
+ resolvedInApp = Module.createRequire(entrypoint).resolve('dd-trace')
30
+ } catch (e) {
31
+ // Ignore. If we can't resolve the module, we assume it's not in the app.
32
+ }
33
+ if (resolvedInApp) {
34
+ var ourselves = path.normalize(path.join(__dirname, '..', '..', '..', '..', 'index.js'))
35
+ if (ourselves !== resolvedInApp) {
36
+ clobberBailout = true
37
+ }
38
+ }
39
+ }
40
+
41
+ // If the runtime doesn't match the engines field in package.json, then we
42
+ // should not initialize the tracer.
43
+ if (!clobberBailout && NODE_MAJOR < minMajor) {
44
+ initBailout = true
45
+ telemetry([
46
+ { name: 'abort', tags: ['reason:incompatible_runtime'] },
47
+ { name: 'abort.runtime', tags: [] }
48
+ ])
49
+ log.info('Aborting application instrumentation due to incompatible_runtime.')
50
+ log.info('Found incompatible runtime nodejs ' + version + ', Supported runtimes: nodejs ' + engines.node + '.')
51
+ if (forced) {
52
+ log.info('DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.')
53
+ }
54
+ }
55
+
56
+ if (!clobberBailout && (!initBailout || forced)) {
57
+ var result = fn()
58
+ telemetry('complete', ['injection_forced:' + (forced && initBailout ? 'true' : 'false')])
59
+ log.info('Application instrumentation bootstrapping complete')
60
+ return result
61
+ }
62
+ }
63
+
64
+ module.exports = guard
@@ -0,0 +1,32 @@
1
+ 'use strict'
2
+
3
+ /* eslint-disable no-var */
4
+ /* eslint-disable no-console */
5
+
6
+ var isTrue = require('./util').isTrue
7
+
8
+ var DD_TRACE_DEBUG = process.env.DD_TRACE_DEBUG
9
+ var DD_TRACE_LOG_LEVEL = process.env.DD_TRACE_LOG_LEVEL
10
+
11
+ var logLevels = {
12
+ trace: 20,
13
+ debug: 20,
14
+ info: 30,
15
+ warn: 40,
16
+ error: 50,
17
+ critical: 50,
18
+ off: 100
19
+ }
20
+
21
+ var logLevel = isTrue(DD_TRACE_DEBUG)
22
+ ? Number(DD_TRACE_LOG_LEVEL) || logLevels.debug
23
+ : logLevels.off
24
+
25
+ var log = {
26
+ debug: logLevel <= 20 ? console.debug.bind(console) : function () {},
27
+ info: logLevel <= 30 ? console.info.bind(console) : function () {},
28
+ warn: logLevel <= 40 ? console.warn.bind(console) : function () {},
29
+ error: logLevel <= 50 ? console.error.bind(console) : function () {}
30
+ }
31
+
32
+ module.exports = log
@@ -0,0 +1,78 @@
1
+ 'use strict'
2
+
3
+ /* eslint-disable no-var */
4
+ /* eslint-disable object-shorthand */
5
+
6
+ var fs = require('fs')
7
+ var spawn = require('child_process').spawn
8
+ var tracerVersion = require('../../../../package.json').version
9
+ var log = require('./log')
10
+
11
+ module.exports = sendTelemetry
12
+
13
+ if (!process.env.DD_INJECTION_ENABLED) {
14
+ module.exports = function () {}
15
+ }
16
+
17
+ if (!process.env.DD_TELEMETRY_FORWARDER_PATH) {
18
+ module.exports = function () {}
19
+ }
20
+
21
+ if (!fs.existsSync(process.env.DD_TELEMETRY_FORWARDER_PATH)) {
22
+ module.exports = function () {}
23
+ }
24
+
25
+ var metadata = {
26
+ language_name: 'nodejs',
27
+ language_version: process.versions.node,
28
+ runtime_name: 'nodejs',
29
+ runtime_version: process.versions.node,
30
+ tracer_version: tracerVersion,
31
+ pid: process.pid
32
+ }
33
+
34
+ var seen = []
35
+ function hasSeen (point) {
36
+ if (point.name === 'abort') {
37
+ // This one can only be sent once, regardless of tags
38
+ return seen.includes('abort')
39
+ }
40
+ if (point.name === 'abort.integration') {
41
+ // For now, this is the only other one we want to dedupe
42
+ var compiledPoint = point.name + point.tags.join('')
43
+ return seen.includes(compiledPoint)
44
+ }
45
+ return false
46
+ }
47
+
48
+ function sendTelemetry (name, tags) {
49
+ var points = name
50
+ if (typeof name === 'string') {
51
+ points = [{ name: name, tags: tags || [] }]
52
+ }
53
+ if (['1', 'true', 'True'].indexOf(process.env.DD_INJECT_FORCE) !== -1) {
54
+ points = points.filter(function (p) { return ['error', 'complete'].includes(p.name) })
55
+ }
56
+ points = points.filter(function (p) { return !hasSeen(p) })
57
+ for (var i = 0; i < points.length; i++) {
58
+ points[i].name = 'library_entrypoint.' + points[i].name
59
+ }
60
+ if (points.length === 0) {
61
+ return
62
+ }
63
+ var proc = spawn(process.env.DD_TELEMETRY_FORWARDER_PATH, ['library_entrypoint'], {
64
+ stdio: 'pipe'
65
+ })
66
+ proc.on('error', function () {
67
+ log.error('Failed to spawn telemetry forwarder')
68
+ })
69
+ proc.on('exit', function (code) {
70
+ if (code !== 0) {
71
+ log.error('Telemetry forwarder exited with code ' + code)
72
+ }
73
+ })
74
+ proc.stdin.on('error', function () {
75
+ log.error('Failed to write telemetry data to telemetry forwarder')
76
+ })
77
+ proc.stdin.end(JSON.stringify({ metadata: metadata, points: points }))
78
+ }
@@ -0,0 +1,10 @@
1
+ 'use strict'
2
+
3
+ /* eslint-disable object-shorthand */
4
+
5
+ function isTrue (str) {
6
+ str = String(str).toLowerCase()
7
+ return str === 'true' || str === '1'
8
+ }
9
+
10
+ module.exports = { isTrue: isTrue }
@@ -101,7 +101,7 @@ const registerLambdaHook = () => {
101
101
  try {
102
102
  moduleExports = hook(moduleExports)
103
103
  } catch (e) {
104
- log.error(e)
104
+ log.error('Error executing lambda hook', e)
105
105
  }
106
106
  }
107
107
 
@@ -120,7 +120,7 @@ const registerLambdaHook = () => {
120
120
  try {
121
121
  moduleExports = hook(moduleExports)
122
122
  } catch (e) {
123
- log.error(e)
123
+ log.error('Error executing lambda hook for datadog-lambda-js', e)
124
124
  }
125
125
  }
126
126
  }
@@ -1,7 +1,6 @@
1
1
  'use strict'
2
2
 
3
- // TODO: remove this and use namespaced storage once available
4
- const { AsyncLocalStorage } = require('async_hooks')
5
- const storage = new AsyncLocalStorage()
3
+ const { storage: createStorage } = require('../../../datadog-core')
4
+ const storage = createStorage('llmobs')
6
5
 
7
6
  module.exports = { storage }
@@ -74,11 +74,11 @@ class BaseLLMObsWriter {
74
74
  request(payload, options, (err, resp, code) => {
75
75
  if (err) {
76
76
  logger.error(
77
- `Error sending ${events.length} LLMObs ${this._eventType} events to ${this._url}: ${err.message}`
77
+ 'Error sending %d LLMObs %s events to %s: %s', events.length, this._eventType, this._url, err.message, err
78
78
  )
79
79
  } else if (code >= 300) {
80
80
  logger.error(
81
- `Error sending ${events.length} LLMObs ${this._eventType} events to ${this._url}: ${code}`
81
+ 'Error sending %d LLMObs %s events to %s: %s', events.length, this._eventType, this._url, code
82
82
  )
83
83
  } else {
84
84
  logger.debug(`Sent ${events.length} LLMObs ${this._eventType} events to ${this._url}`)