dd-trace 5.64.0 → 5.66.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.
- package/package.json +8 -8
- package/packages/datadog-instrumentations/src/express.js +3 -7
- package/packages/datadog-instrumentations/src/graphql.js +10 -6
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -2
- package/packages/datadog-instrumentations/src/playwright.js +25 -9
- package/packages/datadog-instrumentations/src/prisma.js +8 -10
- package/packages/datadog-instrumentations/src/ws.js +136 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +30 -3
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +9 -6
- package/packages/datadog-plugin-aws-sdk/src/util.js +61 -1
- package/packages/datadog-plugin-express/src/code_origin.js +11 -0
- package/packages/datadog-plugin-graphql/src/index.js +3 -0
- package/packages/datadog-plugin-ws/src/close.js +69 -0
- package/packages/datadog-plugin-ws/src/index.js +26 -0
- package/packages/datadog-plugin-ws/src/producer.js +60 -0
- package/packages/datadog-plugin-ws/src/receiver.js +70 -0
- package/packages/datadog-plugin-ws/src/server.js +79 -0
- package/packages/datadog-shimmer/src/shimmer.js +11 -2
- package/packages/dd-trace/src/appsec/blocking.js +29 -0
- package/packages/dd-trace/src/appsec/channels.js +4 -2
- package/packages/dd-trace/src/appsec/index.js +7 -2
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +1 -0
- package/packages/dd-trace/src/appsec/rasp/index.js +25 -7
- package/packages/dd-trace/src/appsec/rasp/lfi.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/utils.js +13 -2
- package/packages/dd-trace/src/azure_metadata.js +5 -4
- package/packages/dd-trace/src/config.js +12 -0
- package/packages/dd-trace/src/datastreams/pathway.js +1 -1
- package/packages/dd-trace/src/dogstatsd.js +17 -20
- package/packages/dd-trace/src/guardrails/index.js +11 -3
- package/packages/dd-trace/src/guardrails/telemetry.js +15 -16
- package/packages/dd-trace/src/llmobs/tagger.js +2 -1
- package/packages/dd-trace/src/log/writer.js +1 -1
- package/packages/dd-trace/src/plugin_manager.js +8 -2
- package/packages/dd-trace/src/plugins/index.js +2 -1
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +48 -45
- package/packages/dd-trace/src/profiling/profilers/wall.js +9 -3
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +175 -126
- package/packages/dd-trace/src/service-naming/schemas/v0/index.js +2 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/websocket.js +30 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/index.js +2 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/websocket.js +30 -0
- package/packages/dd-trace/src/supported-configurations.json +3 -1
|
@@ -4,72 +4,90 @@
|
|
|
4
4
|
|
|
5
5
|
const v8 = require('v8')
|
|
6
6
|
const os = require('os')
|
|
7
|
+
const process = require('process')
|
|
7
8
|
const { DogStatsDClient, MetricsAggregationClient } = require('../dogstatsd')
|
|
8
9
|
const log = require('../log')
|
|
9
|
-
const { performance, PerformanceObserver } = require('perf_hooks')
|
|
10
|
+
const { performance, PerformanceObserver, monitorEventLoopDelay } = require('perf_hooks')
|
|
10
11
|
const { getEnvironmentVariable } = require('../config-helper')
|
|
11
12
|
|
|
12
|
-
const { NODE_MAJOR
|
|
13
|
+
const { NODE_MAJOR } = require('../../../../version')
|
|
14
|
+
// TODO: This environment variable may not be changed, since the agent expects a flush every ten seconds.
|
|
15
|
+
// It is only a variable for testing. Think about alternatives.
|
|
13
16
|
const DD_RUNTIME_METRICS_FLUSH_INTERVAL = getEnvironmentVariable('DD_RUNTIME_METRICS_FLUSH_INTERVAL') ?? '10000'
|
|
14
17
|
const INTERVAL = Number.parseInt(DD_RUNTIME_METRICS_FLUSH_INTERVAL, 10)
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
// See: https://github.com/nodejs/node/issues/39548
|
|
18
|
-
const hasGCObserver = NODE_MAJOR >= 18 || (NODE_MAJOR === 16 && NODE_MINOR >= 7)
|
|
19
|
+
const eventLoopDelayResolution = 4
|
|
19
20
|
|
|
20
21
|
let nativeMetrics = null
|
|
21
22
|
let gcObserver = null
|
|
22
|
-
|
|
23
|
-
let
|
|
24
|
-
let
|
|
25
|
-
let
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
let interval = null
|
|
24
|
+
let client = null
|
|
25
|
+
let lastTime = 0n
|
|
26
|
+
let lastCpuUsage = null
|
|
27
|
+
let eventLoopDelayObserver = null
|
|
28
|
+
|
|
29
|
+
// !!!!!!!!!!!
|
|
30
|
+
// IMPORTANT
|
|
31
|
+
// !!!!!!!!!!!
|
|
32
|
+
//
|
|
33
|
+
// ALL metrics that relate to time are handled in nanoseconds in the backend.
|
|
34
|
+
// https://github.com/DataDog/dogweb/blob/prod/integration/node/node_metadata.csv
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
32
37
|
start (config) {
|
|
38
|
+
this.stop()
|
|
33
39
|
const clientConfig = DogStatsDClient.generateClientConfig(config)
|
|
34
|
-
const watchers = []
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
startGCObserver()
|
|
39
|
-
} else {
|
|
40
|
-
watchers.push('gc')
|
|
41
|
-
}
|
|
42
|
-
}
|
|
41
|
+
const trackEventLoop = config.runtimeMetrics.eventLoop !== false
|
|
42
|
+
const trackGc = config.runtimeMetrics.gc !== false
|
|
43
43
|
|
|
44
|
-
if (
|
|
45
|
-
|
|
44
|
+
if (trackGc) {
|
|
45
|
+
startGCObserver()
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
// Using no-gc prevents the native gc metrics from being tracked. Not
|
|
49
|
+
// passing any options means all metrics are tracked.
|
|
50
|
+
// TODO: This is a workaround. We should find a better solution.
|
|
51
|
+
const watchers = trackEventLoop ? ['loop'] : ['no-gc']
|
|
52
|
+
|
|
48
53
|
try {
|
|
49
54
|
nativeMetrics = require('@datadog/native-metrics')
|
|
50
55
|
nativeMetrics.start(...watchers)
|
|
51
|
-
} catch (
|
|
52
|
-
log.error('Error starting native metrics',
|
|
56
|
+
} catch (error) {
|
|
57
|
+
log.error('Error starting native metrics', error)
|
|
53
58
|
nativeMetrics = null
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
client = new MetricsAggregationClient(new DogStatsDClient(clientConfig))
|
|
57
62
|
|
|
58
|
-
|
|
63
|
+
lastTime = performance.now()
|
|
59
64
|
|
|
60
65
|
if (nativeMetrics) {
|
|
61
66
|
interval = setInterval(() => {
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
captureNativeMetrics(trackEventLoop, trackGc)
|
|
68
|
+
captureCommonMetrics(trackEventLoop)
|
|
64
69
|
client.flush()
|
|
65
70
|
}, INTERVAL)
|
|
66
71
|
} else {
|
|
67
|
-
|
|
72
|
+
lastCpuUsage = process.cpuUsage()
|
|
73
|
+
|
|
74
|
+
if (trackEventLoop) {
|
|
75
|
+
eventLoopDelayObserver = monitorEventLoopDelay({ resolution: eventLoopDelayResolution })
|
|
76
|
+
eventLoopDelayObserver.enable()
|
|
77
|
+
}
|
|
68
78
|
|
|
69
79
|
interval = setInterval(() => {
|
|
70
|
-
captureCommonMetrics()
|
|
71
80
|
captureCpuUsage()
|
|
81
|
+
captureCommonMetrics(trackEventLoop)
|
|
72
82
|
captureHeapSpace()
|
|
83
|
+
if (trackEventLoop) {
|
|
84
|
+
// Experimental: The Node.js implementation deviates from the native metrics.
|
|
85
|
+
// We normalize the metrics to the same format but the Node.js values
|
|
86
|
+
// are that way lower than they should be, while they are still nearer
|
|
87
|
+
// to the native ones that way.
|
|
88
|
+
// We use these only as fallback values.
|
|
89
|
+
captureEventLoopDelay()
|
|
90
|
+
}
|
|
73
91
|
client.flush()
|
|
74
92
|
}, INTERVAL)
|
|
75
93
|
}
|
|
@@ -78,12 +96,21 @@ const runtimeMetrics = module.exports = {
|
|
|
78
96
|
},
|
|
79
97
|
|
|
80
98
|
stop () {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
99
|
+
nativeMetrics?.stop()
|
|
100
|
+
nativeMetrics = null
|
|
84
101
|
|
|
85
102
|
clearInterval(interval)
|
|
86
|
-
|
|
103
|
+
interval = null
|
|
104
|
+
|
|
105
|
+
client = null
|
|
106
|
+
lastTime = 0n
|
|
107
|
+
lastCpuUsage = null
|
|
108
|
+
|
|
109
|
+
gcObserver?.disconnect()
|
|
110
|
+
gcObserver = null
|
|
111
|
+
|
|
112
|
+
eventLoopDelayObserver?.disable()
|
|
113
|
+
eventLoopDelayObserver = null
|
|
87
114
|
},
|
|
88
115
|
|
|
89
116
|
track (span) {
|
|
@@ -99,19 +126,19 @@ const runtimeMetrics = module.exports = {
|
|
|
99
126
|
},
|
|
100
127
|
|
|
101
128
|
boolean (name, value, tag) {
|
|
102
|
-
client
|
|
129
|
+
client?.boolean(name, value, tag)
|
|
103
130
|
},
|
|
104
131
|
|
|
105
132
|
histogram (name, value, tag) {
|
|
106
|
-
client
|
|
133
|
+
client?.histogram(name, value, tag)
|
|
107
134
|
},
|
|
108
135
|
|
|
109
136
|
count (name, count, tag, monotonic = false) {
|
|
110
|
-
client
|
|
137
|
+
client?.count(name, count, tag, monotonic)
|
|
111
138
|
},
|
|
112
139
|
|
|
113
140
|
gauge (name, value, tag) {
|
|
114
|
-
client
|
|
141
|
+
client?.gauge(name, value, tag)
|
|
115
142
|
},
|
|
116
143
|
|
|
117
144
|
increment (name, tag, monotonic) {
|
|
@@ -123,30 +150,20 @@ const runtimeMetrics = module.exports = {
|
|
|
123
150
|
}
|
|
124
151
|
}
|
|
125
152
|
|
|
126
|
-
function reset () {
|
|
127
|
-
interval = null
|
|
128
|
-
client = null
|
|
129
|
-
time = null
|
|
130
|
-
cpuUsage = null
|
|
131
|
-
nativeMetrics = null
|
|
132
|
-
gcObserver && gcObserver.disconnect()
|
|
133
|
-
gcObserver = null
|
|
134
|
-
}
|
|
135
|
-
|
|
136
153
|
function captureCpuUsage () {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const elapsedMs = elapsedTime[0] * 1000 + elapsedTime[1] / 1_000_000
|
|
146
|
-
const userPercent = 100 * elapsedUsage.user / 1000 / elapsedMs
|
|
147
|
-
const systemPercent = 100 * elapsedUsage.system / 1000 / elapsedMs
|
|
154
|
+
const currentCpuUsage = process.cpuUsage()
|
|
155
|
+
const elapsedUsageUser = currentCpuUsage.user - lastCpuUsage.user
|
|
156
|
+
const elapsedUsageSystem = currentCpuUsage.system - lastCpuUsage.system
|
|
157
|
+
|
|
158
|
+
const currentTime = performance.now() // Milliseconds with decimal places
|
|
159
|
+
const elapsedUsDividedBy100 = (currentTime - lastTime) * 10
|
|
160
|
+
const userPercent = elapsedUsageUser / elapsedUsDividedBy100
|
|
161
|
+
const systemPercent = elapsedUsageSystem / elapsedUsDividedBy100
|
|
148
162
|
const totalPercent = userPercent + systemPercent
|
|
149
163
|
|
|
164
|
+
lastTime = currentTime
|
|
165
|
+
lastCpuUsage = currentCpuUsage
|
|
166
|
+
|
|
150
167
|
client.gauge('runtime.node.cpu.system', systemPercent.toFixed(2))
|
|
151
168
|
client.gauge('runtime.node.cpu.user', userPercent.toFixed(2))
|
|
152
169
|
client.gauge('runtime.node.cpu.total', totalPercent.toFixed(2))
|
|
@@ -160,12 +177,44 @@ function captureMemoryUsage () {
|
|
|
160
177
|
client.gauge('runtime.node.mem.rss', stats.rss)
|
|
161
178
|
client.gauge('runtime.node.mem.total', os.totalmem())
|
|
162
179
|
client.gauge('runtime.node.mem.free', os.freemem())
|
|
180
|
+
client.gauge('runtime.node.mem.external', stats.external)
|
|
181
|
+
// TODO: Add arrayBuffers to the metrics. That also requires the
|
|
182
|
+
// node_metadata.csv to be updated for the website.
|
|
183
|
+
//
|
|
184
|
+
// client.gauge('runtime.node.mem.arrayBuffers', stats.arrayBuffers)
|
|
185
|
+
}
|
|
163
186
|
|
|
164
|
-
|
|
187
|
+
function captureUptime () {
|
|
188
|
+
// WARNING: lastTime must be updated in the same interval before this function is called!
|
|
189
|
+
// This is a faster `process.uptime()`.
|
|
190
|
+
client.gauge('runtime.node.process.uptime', Math.round((lastTime + 499) / 1000))
|
|
165
191
|
}
|
|
166
192
|
|
|
167
|
-
function
|
|
168
|
-
|
|
193
|
+
function captureEventLoopDelay () {
|
|
194
|
+
eventLoopDelayObserver.disable()
|
|
195
|
+
|
|
196
|
+
if (eventLoopDelayObserver.count !== 0) {
|
|
197
|
+
const minimum = eventLoopDelayResolution * 1e6
|
|
198
|
+
const avg = Math.max(eventLoopDelayObserver.mean - minimum, 0)
|
|
199
|
+
const sum = Math.round(avg * eventLoopDelayObserver.count)
|
|
200
|
+
|
|
201
|
+
if (sum !== 0) {
|
|
202
|
+
// Normalize the metrics to the same format as the native metrics.
|
|
203
|
+
const stats = {
|
|
204
|
+
min: Math.max(eventLoopDelayObserver.min - minimum, 0),
|
|
205
|
+
max: Math.max(eventLoopDelayObserver.max - minimum, 0),
|
|
206
|
+
sum,
|
|
207
|
+
total: sum,
|
|
208
|
+
avg,
|
|
209
|
+
count: eventLoopDelayObserver.count,
|
|
210
|
+
p95: Math.max(eventLoopDelayObserver.percentile(95) - minimum, 0)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
histogram('runtime.node.event_loop.delay', stats)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
eventLoopDelayObserver = monitorEventLoopDelay({ resolution: eventLoopDelayResolution })
|
|
217
|
+
eventLoopDelayObserver.enable()
|
|
169
218
|
}
|
|
170
219
|
|
|
171
220
|
function captureHeapStats () {
|
|
@@ -176,14 +225,17 @@ function captureHeapStats () {
|
|
|
176
225
|
client.gauge('runtime.node.heap.total_physical_size', stats.total_physical_size)
|
|
177
226
|
client.gauge('runtime.node.heap.total_available_size', stats.total_available_size)
|
|
178
227
|
client.gauge('runtime.node.heap.heap_size_limit', stats.heap_size_limit)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
228
|
+
client.gauge('runtime.node.heap.malloced_memory', stats.malloced_memory)
|
|
229
|
+
client.gauge('runtime.node.heap.peak_malloced_memory', stats.peak_malloced_memory)
|
|
230
|
+
// TODO: Add number_of_native_contexts and number_of_detached_contexts to the
|
|
231
|
+
// metrics. Those metrics allow to identify memory leaks. Adding them also
|
|
232
|
+
// requires the node_metadata.csv to be updated for the website.
|
|
233
|
+
//
|
|
234
|
+
// client.gauge('runtime.node.heap.number_of_native_contexts', stats.number_of_native_contexts)
|
|
235
|
+
// client.gauge('runtime.node.heap.number_of_detached_contexts', stats.number_of_detached_contexts)
|
|
182
236
|
}
|
|
183
237
|
|
|
184
238
|
function captureHeapSpace () {
|
|
185
|
-
if (!v8.getHeapSpaceStatistics) return
|
|
186
|
-
|
|
187
239
|
const stats = v8.getHeapSpaceStatistics()
|
|
188
240
|
|
|
189
241
|
for (let i = 0, l = stats.length; i < l; i++) {
|
|
@@ -197,55 +249,63 @@ function captureHeapSpace () {
|
|
|
197
249
|
}
|
|
198
250
|
|
|
199
251
|
/**
|
|
200
|
-
* Gathers and reports Event Loop Utilization (ELU) since last run
|
|
252
|
+
* Gathers and reports Event Loop Utilization (ELU) since last run, or from the
|
|
253
|
+
* start of the process on first run.
|
|
201
254
|
*
|
|
202
255
|
* ELU is a measure of how busy the event loop is, like running JavaScript or
|
|
203
256
|
* waiting on *Sync functions. The value is between 0 (idle) and 1 (exhausted).
|
|
204
|
-
*
|
|
205
|
-
* performance.eventLoopUtilization available in Node.js >= v14.10, >= v12.19, >= v16
|
|
206
257
|
*/
|
|
207
|
-
let
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
// if elu is undefined (first run) the measurement is from start of process
|
|
211
|
-
elu = performance.eventLoopUtilization(elu)
|
|
258
|
+
let lastElu = { idle: 0, active: 0 }
|
|
259
|
+
function captureELU () {
|
|
260
|
+
const elu = performance.eventLoopUtilization()
|
|
212
261
|
|
|
213
|
-
|
|
214
|
-
|
|
262
|
+
const idle = elu.idle - lastElu.idle
|
|
263
|
+
const active = elu.active - lastElu.active
|
|
264
|
+
const utilization = active / (idle + active)
|
|
265
|
+
|
|
266
|
+
lastElu = elu
|
|
267
|
+
|
|
268
|
+
client.gauge('runtime.node.event_loop.utilization', utilization)
|
|
215
269
|
}
|
|
216
270
|
|
|
217
|
-
function captureCommonMetrics () {
|
|
271
|
+
function captureCommonMetrics (trackEventLoop) {
|
|
218
272
|
captureMemoryUsage()
|
|
219
|
-
|
|
273
|
+
captureUptime()
|
|
220
274
|
captureHeapStats()
|
|
221
|
-
|
|
275
|
+
if (trackEventLoop) {
|
|
276
|
+
captureELU()
|
|
277
|
+
}
|
|
222
278
|
}
|
|
223
279
|
|
|
224
|
-
function captureNativeMetrics () {
|
|
280
|
+
function captureNativeMetrics (trackEventLoop, trackGc) {
|
|
225
281
|
const stats = nativeMetrics.stats()
|
|
226
282
|
const spaces = stats.heap.spaces
|
|
227
|
-
const elapsedTime = process.hrtime(time)
|
|
228
283
|
|
|
229
|
-
|
|
284
|
+
const currentTime = performance.now() // Milliseconds with decimal places
|
|
285
|
+
const elapsedUsDividedBy100 = (currentTime - lastTime) * 10
|
|
286
|
+
lastTime = currentTime
|
|
230
287
|
|
|
231
|
-
const
|
|
232
|
-
const
|
|
233
|
-
const systemPercent = 100 * stats.cpu.system / elapsedUs
|
|
288
|
+
const userPercent = stats.cpu.user / elapsedUsDividedBy100
|
|
289
|
+
const systemPercent = stats.cpu.system / elapsedUsDividedBy100
|
|
234
290
|
const totalPercent = userPercent + systemPercent
|
|
235
291
|
|
|
236
292
|
client.gauge('runtime.node.cpu.system', systemPercent.toFixed(2))
|
|
237
293
|
client.gauge('runtime.node.cpu.user', userPercent.toFixed(2))
|
|
238
294
|
client.gauge('runtime.node.cpu.total', totalPercent.toFixed(2))
|
|
239
295
|
|
|
240
|
-
|
|
296
|
+
if (trackEventLoop) {
|
|
297
|
+
histogram('runtime.node.event_loop.delay', stats.eventLoop)
|
|
298
|
+
}
|
|
241
299
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
300
|
+
if (trackGc) {
|
|
301
|
+
for (const [type, value] of Object.entries(stats.gc)) {
|
|
302
|
+
if (type === 'all') {
|
|
303
|
+
histogram('runtime.node.gc.pause', value)
|
|
304
|
+
} else {
|
|
305
|
+
histogram('runtime.node.gc.pause.by.type', value, `gc_type:${type}`)
|
|
306
|
+
}
|
|
247
307
|
}
|
|
248
|
-
}
|
|
308
|
+
}
|
|
249
309
|
|
|
250
310
|
for (let i = 0, l = spaces.length; i < l; i++) {
|
|
251
311
|
const tag = `heap_space:${spaces[i].space_name}`
|
|
@@ -258,13 +318,19 @@ function captureNativeMetrics () {
|
|
|
258
318
|
}
|
|
259
319
|
|
|
260
320
|
function histogram (name, stats, tag) {
|
|
321
|
+
if (stats.count === 0) {
|
|
322
|
+
return
|
|
323
|
+
}
|
|
261
324
|
client.gauge(`${name}.min`, stats.min, tag)
|
|
262
325
|
client.gauge(`${name}.max`, stats.max, tag)
|
|
263
326
|
client.increment(`${name}.sum`, stats.sum, tag)
|
|
264
327
|
client.increment(`${name}.total`, stats.sum, tag)
|
|
265
328
|
client.gauge(`${name}.avg`, stats.avg, tag)
|
|
266
329
|
client.increment(`${name}.count`, stats.count, tag)
|
|
267
|
-
|
|
330
|
+
if (stats.median !== undefined) {
|
|
331
|
+
// TODO: Consider adding the median to the Node.js histogram/adding stddev to native metrics.
|
|
332
|
+
client.gauge(`${name}.median`, stats.median, tag)
|
|
333
|
+
}
|
|
268
334
|
client.gauge(`${name}.95percentile`, stats.p95, tag)
|
|
269
335
|
}
|
|
270
336
|
|
|
@@ -276,42 +342,25 @@ function startGCObserver () {
|
|
|
276
342
|
const type = gcType(entry.detail?.kind || entry.kind)
|
|
277
343
|
const duration = entry.duration * 1_000_000
|
|
278
344
|
|
|
279
|
-
|
|
280
|
-
|
|
345
|
+
// These are individual metrics for each type of GC.
|
|
346
|
+
client.histogram('runtime.node.gc.pause.by.type', duration, `gc_type:${type}`)
|
|
347
|
+
client.histogram('runtime.node.gc.pause', duration)
|
|
281
348
|
}
|
|
282
349
|
})
|
|
283
350
|
|
|
284
351
|
gcObserver.observe({ type: 'gc' })
|
|
285
352
|
}
|
|
286
353
|
|
|
354
|
+
const minorGCType = NODE_MAJOR >= 22 ? 'minor_mark_sweep' : 'minor_mark_compact'
|
|
355
|
+
|
|
287
356
|
function gcType (kind) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
} else if (NODE_MAJOR >= 18) {
|
|
298
|
-
switch (kind) {
|
|
299
|
-
case 1: return 'scavenge'
|
|
300
|
-
case 2: return 'minor_mark_compact'
|
|
301
|
-
case 4: return 'mark_sweep_compact'
|
|
302
|
-
case 8: return 'incremental_marking'
|
|
303
|
-
case 16: return 'process_weak_callbacks'
|
|
304
|
-
case 31: return 'all'
|
|
305
|
-
}
|
|
306
|
-
} else {
|
|
307
|
-
switch (kind) {
|
|
308
|
-
case 1: return 'scavenge'
|
|
309
|
-
case 2: return 'mark_sweep_compact'
|
|
310
|
-
case 4: return 'incremental_marking'
|
|
311
|
-
case 8: return 'process_weak_callbacks'
|
|
312
|
-
case 15: return 'all'
|
|
313
|
-
}
|
|
357
|
+
switch (kind) {
|
|
358
|
+
case 1: return 'scavenge'
|
|
359
|
+
case 2: return minorGCType
|
|
360
|
+
case 4: return 'mark_sweep_compact' // Deprecated, might be removed soon.
|
|
361
|
+
case 8: return 'incremental_marking'
|
|
362
|
+
case 16: return 'process_weak_callbacks'
|
|
363
|
+
case 31: return 'all'
|
|
364
|
+
default: return 'unknown'
|
|
314
365
|
}
|
|
315
|
-
|
|
316
|
-
return 'unknown'
|
|
317
366
|
}
|
|
@@ -6,5 +6,6 @@ const storage = require('./storage')
|
|
|
6
6
|
const graphql = require('./graphql')
|
|
7
7
|
const web = require('./web')
|
|
8
8
|
const serverless = require('./serverless')
|
|
9
|
+
const websocket = require('./websocket')
|
|
9
10
|
|
|
10
|
-
module.exports = new SchemaDefinition({ messaging, storage, web, graphql, serverless })
|
|
11
|
+
module.exports = new SchemaDefinition({ messaging, storage, web, graphql, serverless, websocket })
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const websocket = {
|
|
4
|
+
request: {
|
|
5
|
+
ws: {
|
|
6
|
+
opName: () => 'web.request',
|
|
7
|
+
serviceName: ({ pluginConfig, tracerService }) => pluginConfig.service || tracerService
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
producer: {
|
|
11
|
+
ws: {
|
|
12
|
+
opName: () => 'websocket.send',
|
|
13
|
+
serviceName: ({ pluginConfig, tracerService }) => pluginConfig.service || tracerService
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
consumer: {
|
|
17
|
+
ws: {
|
|
18
|
+
opName: () => 'websocket.receive',
|
|
19
|
+
serviceName: ({ pluginConfig, tracerService }) => pluginConfig.service || tracerService
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
close: {
|
|
23
|
+
ws: {
|
|
24
|
+
opName: () => 'websocket.close',
|
|
25
|
+
serviceName: ({ pluginConfig, tracerService }) => pluginConfig.service || tracerService
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = websocket
|
|
@@ -6,5 +6,6 @@ const storage = require('./storage')
|
|
|
6
6
|
const graphql = require('./graphql')
|
|
7
7
|
const web = require('./web')
|
|
8
8
|
const serverless = require('./serverless')
|
|
9
|
+
const websocket = require('./websocket')
|
|
9
10
|
|
|
10
|
-
module.exports = new SchemaDefinition({ messaging, storage, web, graphql, serverless })
|
|
11
|
+
module.exports = new SchemaDefinition({ messaging, storage, web, graphql, serverless, websocket })
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const websocket = {
|
|
4
|
+
request: {
|
|
5
|
+
ws: {
|
|
6
|
+
opName: () => 'web.request',
|
|
7
|
+
serviceName: ({ pluginConfig, tracerService }) => pluginConfig.service || tracerService
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
producer: {
|
|
11
|
+
ws: {
|
|
12
|
+
opName: () => 'websocket.send',
|
|
13
|
+
serviceName: ({ pluginConfig, tracerService }) => pluginConfig.service || tracerService
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
consumer: {
|
|
17
|
+
ws: {
|
|
18
|
+
opName: () => 'websocket.receive',
|
|
19
|
+
serviceName: ({ pluginConfig, tracerService }) => pluginConfig.service || tracerService
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
close: {
|
|
23
|
+
ws: {
|
|
24
|
+
opName: () => 'websocket.close',
|
|
25
|
+
serviceName: ({ pluginConfig, tracerService }) => pluginConfig.service || tracerService
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = websocket
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
"DD_APPSEC_STACK_TRACE_ENABLED": ["A"],
|
|
32
32
|
"DD_APPSEC_TRACE_RATE_LIMIT": ["A"],
|
|
33
33
|
"DD_APPSEC_WAF_TIMEOUT": ["A"],
|
|
34
|
-
"DD_AZURE_APP_SERVICES": ["A"],
|
|
35
34
|
"DD_CIVISIBILITY_AGENTLESS_ENABLED": ["A"],
|
|
36
35
|
"DD_CIVISIBILITY_AGENTLESS_URL": ["A"],
|
|
37
36
|
"DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER": ["A"],
|
|
@@ -415,6 +414,9 @@
|
|
|
415
414
|
"DD_TRACE_VITEST_ENABLED": ["A"],
|
|
416
415
|
"DD_TRACE_VITEST_RUNNER_ENABLED": ["A"],
|
|
417
416
|
"DD_TRACE_VM_ENABLED": ["A"],
|
|
417
|
+
"DD_TRACE_WEBSOCKET_MESSAGES_ENABLED":["A"],
|
|
418
|
+
"DD_TRACE_WEBSOCKET_MESSAGES_INHERIT_SAMPLING": ["A"],
|
|
419
|
+
"DD_TRACE_WEBSOCKET_MESSAGES_SEPARATE_TRACES":["A"],
|
|
418
420
|
"DD_TRACE_WHEN_ENABLED": ["A"],
|
|
419
421
|
"DD_TRACE_WINSTON_ENABLED": ["A"],
|
|
420
422
|
"DD_TRACE_WORKERPOOL_ENABLED": ["A"],
|