dd-trace 5.23.1 → 5.25.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/LICENSE-3rdparty.csv +1 -1
- package/ext/types.d.ts +1 -0
- package/ext/types.js +1 -0
- package/index.d.ts +361 -0
- package/package.json +18 -13
- package/packages/datadog-code-origin/index.js +38 -0
- package/packages/datadog-core/index.js +2 -2
- package/packages/datadog-core/src/utils/src/parse-tags.js +33 -0
- package/packages/datadog-esbuild/index.js +4 -2
- package/packages/datadog-instrumentations/src/amqplib.js +65 -5
- package/packages/datadog-instrumentations/src/avsc.js +37 -0
- package/packages/datadog-instrumentations/src/azure-functions.js +48 -0
- package/packages/datadog-instrumentations/src/child_process.js +144 -27
- package/packages/datadog-instrumentations/src/express.js +37 -4
- package/packages/datadog-instrumentations/src/fastify.js +12 -1
- package/packages/datadog-instrumentations/src/fs.js +27 -7
- package/packages/datadog-instrumentations/src/helpers/hooks.js +6 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +9 -0
- package/packages/datadog-instrumentations/src/jest.js +2 -1
- package/packages/datadog-instrumentations/src/kafkajs.js +123 -63
- package/packages/datadog-instrumentations/src/mocha/common.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/utils.js +2 -2
- package/packages/datadog-instrumentations/src/multer.js +37 -0
- package/packages/datadog-instrumentations/src/mysql2.js +220 -1
- package/packages/datadog-instrumentations/src/openai.js +2 -2
- package/packages/datadog-instrumentations/src/protobufjs.js +127 -0
- package/packages/datadog-instrumentations/src/url.js +84 -0
- package/packages/datadog-instrumentations/src/utils/src/extract-package-and-module-path.js +7 -4
- package/packages/datadog-instrumentations/src/winston.js +22 -0
- package/packages/datadog-plugin-amqplib/src/consumer.js +4 -4
- package/packages/datadog-plugin-avsc/src/index.js +9 -0
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +169 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
- package/packages/datadog-plugin-azure-functions/src/index.js +77 -0
- package/packages/datadog-plugin-fastify/src/code_origin.js +31 -0
- package/packages/datadog-plugin-fastify/src/index.js +10 -12
- package/packages/datadog-plugin-fastify/src/tracing.js +19 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +8 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +8 -0
- package/packages/datadog-plugin-grpc/src/client.js +3 -0
- package/packages/datadog-plugin-grpc/src/server.js +3 -0
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +6 -3
- package/packages/datadog-plugin-kafkajs/src/consumer.js +8 -4
- package/packages/datadog-plugin-kafkajs/src/producer.js +10 -4
- package/packages/datadog-plugin-mocha/src/index.js +4 -1
- package/packages/datadog-plugin-openai/src/index.js +9 -1015
- package/packages/datadog-plugin-openai/src/tracing.js +1023 -0
- package/packages/datadog-plugin-protobufjs/src/index.js +14 -0
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +180 -0
- package/packages/dd-trace/src/appsec/addresses.js +8 -1
- package/packages/dd-trace/src/appsec/channels.js +7 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +13 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +8 -1
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/index.js +3 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +1 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +55 -7
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +15 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -2
- package/packages/dd-trace/src/appsec/index.js +61 -43
- package/packages/dd-trace/src/appsec/rasp/command_injection.js +49 -0
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +99 -0
- package/packages/dd-trace/src/appsec/rasp/index.js +27 -10
- package/packages/dd-trace/src/appsec/rasp/lfi.js +112 -0
- package/packages/dd-trace/src/appsec/rasp/sql_injection.js +24 -4
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +4 -3
- package/packages/dd-trace/src/appsec/rasp/utils.js +4 -2
- package/packages/dd-trace/src/appsec/recommended.json +3 -7
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +6 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +10 -0
- package/packages/dd-trace/src/appsec/reporter.js +17 -9
- package/packages/dd-trace/src/appsec/sdk/track_event.js +10 -3
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +1 -1
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +4 -0
- package/packages/dd-trace/src/azure_metadata.js +120 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +97 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +90 -0
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -14
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +19 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +53 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +8 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +43 -0
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +53 -0
- package/packages/dd-trace/src/config.js +86 -6
- package/packages/dd-trace/src/constants.js +3 -1
- package/packages/dd-trace/src/datastreams/pathway.js +1 -0
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +25 -17
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +52 -5
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +4 -4
- package/packages/dd-trace/src/debugger/devtools_client/send.js +29 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +187 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +40 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +252 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +6 -0
- package/packages/dd-trace/src/debugger/devtools_client/state.js +19 -4
- package/packages/dd-trace/src/debugger/index.js +10 -3
- package/packages/dd-trace/src/exporters/common/request.js +8 -34
- package/packages/dd-trace/src/exporters/common/url-to-http-options-polyfill.js +31 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +34 -0
- package/packages/dd-trace/src/llmobs/constants/text.js +6 -0
- package/packages/dd-trace/src/llmobs/constants/writers.js +13 -0
- package/packages/dd-trace/src/llmobs/index.js +103 -0
- package/packages/dd-trace/src/llmobs/noop.js +82 -0
- package/packages/dd-trace/src/llmobs/plugins/base.js +65 -0
- package/packages/dd-trace/src/llmobs/plugins/openai.js +205 -0
- package/packages/dd-trace/src/llmobs/sdk.js +377 -0
- package/packages/dd-trace/src/llmobs/span_processor.js +195 -0
- package/packages/dd-trace/src/llmobs/storage.js +7 -0
- package/packages/dd-trace/src/llmobs/tagger.js +322 -0
- package/packages/dd-trace/src/llmobs/util.js +176 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +111 -0
- package/packages/dd-trace/src/llmobs/writers/evaluations.js +29 -0
- package/packages/dd-trace/src/llmobs/writers/spans/agentProxy.js +23 -0
- package/packages/dd-trace/src/llmobs/writers/spans/agentless.js +17 -0
- package/packages/dd-trace/src/llmobs/writers/spans/base.js +49 -0
- package/packages/dd-trace/src/noop/proxy.js +3 -0
- package/packages/dd-trace/src/noop/span.js +3 -0
- package/packages/dd-trace/src/opentelemetry/span.js +1 -1
- package/packages/dd-trace/src/opentelemetry/tracer.js +1 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +73 -12
- package/packages/dd-trace/src/opentracing/span.js +12 -0
- package/packages/dd-trace/src/opentracing/tracer.js +8 -1
- package/packages/dd-trace/src/payload-tagging/config/aws.json +71 -3
- package/packages/dd-trace/src/payload-tagging/index.js +1 -1
- package/packages/dd-trace/src/payload-tagging/jsonpath-plus.js +2094 -0
- package/packages/dd-trace/src/plugin_manager.js +4 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +2 -0
- package/packages/dd-trace/src/plugins/index.js +3 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
- package/packages/dd-trace/src/plugins/outbound.js +9 -0
- package/packages/dd-trace/src/plugins/schema.js +35 -0
- package/packages/dd-trace/src/plugins/util/ci.js +23 -1
- package/packages/dd-trace/src/plugins/util/serverless.js +7 -0
- package/packages/dd-trace/src/plugins/util/stacktrace.js +94 -0
- package/packages/dd-trace/src/plugins/util/tags.js +7 -0
- package/packages/dd-trace/src/plugins/util/test.js +20 -22
- package/packages/dd-trace/src/plugins/util/web.js +6 -4
- package/packages/dd-trace/src/priority_sampler.js +16 -0
- package/packages/dd-trace/src/profiling/config.js +3 -1
- package/packages/dd-trace/src/profiling/exporters/agent.js +7 -5
- package/packages/dd-trace/src/profiling/profiler.js +24 -14
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +95 -66
- package/packages/dd-trace/src/proxy.js +20 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/index.js +2 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +12 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/index.js +2 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +12 -0
- package/packages/dd-trace/src/span_processor.js +5 -0
- package/packages/dd-trace/src/telemetry/index.js +11 -1
- package/packages/datadog-core/src/storage/async_resource.js +0 -108
- package/packages/datadog-core/src/storage/index.js +0 -5
|
@@ -25,6 +25,70 @@ addHook({ name: 'amqplib', file: 'lib/defs.js', versions: [MIN_VERSION] }, defs
|
|
|
25
25
|
return defs
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
+
addHook({ name: 'amqplib', file: 'lib/channel_model.js', versions: [MIN_VERSION] }, x => {
|
|
29
|
+
shimmer.wrap(x.Channel.prototype, 'get', getMessage => function (queue, options) {
|
|
30
|
+
return getMessage.apply(this, arguments).then(message => {
|
|
31
|
+
if (message === null) {
|
|
32
|
+
return message
|
|
33
|
+
}
|
|
34
|
+
startCh.publish({ method: 'basic.get', message, fields: message.fields, queue })
|
|
35
|
+
// finish right away
|
|
36
|
+
finishCh.publish()
|
|
37
|
+
return message
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
shimmer.wrap(x.Channel.prototype, 'consume', consume => function (queue, callback, options) {
|
|
41
|
+
if (!startCh.hasSubscribers) {
|
|
42
|
+
return consume.apply(this, arguments)
|
|
43
|
+
}
|
|
44
|
+
arguments[1] = (message, ...args) => {
|
|
45
|
+
if (message === null) {
|
|
46
|
+
return callback(message, ...args)
|
|
47
|
+
}
|
|
48
|
+
startCh.publish({ method: 'basic.deliver', message, fields: message.fields, queue })
|
|
49
|
+
const result = callback(message, ...args)
|
|
50
|
+
finishCh.publish()
|
|
51
|
+
return result
|
|
52
|
+
}
|
|
53
|
+
return consume.apply(this, arguments)
|
|
54
|
+
})
|
|
55
|
+
return x
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
addHook({ name: 'amqplib', file: 'lib/callback_model.js', versions: [MIN_VERSION] }, channel => {
|
|
59
|
+
shimmer.wrap(channel.Channel.prototype, 'get', getMessage => function (queue, options, callback) {
|
|
60
|
+
if (!startCh.hasSubscribers) {
|
|
61
|
+
return getMessage.apply(this, arguments)
|
|
62
|
+
}
|
|
63
|
+
arguments[2] = (error, message, ...args) => {
|
|
64
|
+
if (error !== null || message === null) {
|
|
65
|
+
return callback(error, message, ...args)
|
|
66
|
+
}
|
|
67
|
+
startCh.publish({ method: 'basic.get', message, fields: message.fields, queue })
|
|
68
|
+
const result = callback(error, message, ...args)
|
|
69
|
+
finishCh.publish()
|
|
70
|
+
return result
|
|
71
|
+
}
|
|
72
|
+
return getMessage.apply(this, arguments)
|
|
73
|
+
})
|
|
74
|
+
shimmer.wrap(channel.Channel.prototype, 'consume', consume => function (queue, callback) {
|
|
75
|
+
if (!startCh.hasSubscribers) {
|
|
76
|
+
return consume.apply(this, arguments)
|
|
77
|
+
}
|
|
78
|
+
arguments[1] = (message, ...args) => {
|
|
79
|
+
if (message === null) {
|
|
80
|
+
return callback(message, ...args)
|
|
81
|
+
}
|
|
82
|
+
startCh.publish({ method: 'basic.deliver', message, fields: message.fields, queue })
|
|
83
|
+
const result = callback(message, ...args)
|
|
84
|
+
finishCh.publish()
|
|
85
|
+
return result
|
|
86
|
+
}
|
|
87
|
+
return consume.apply(this, arguments)
|
|
88
|
+
})
|
|
89
|
+
return channel
|
|
90
|
+
})
|
|
91
|
+
|
|
28
92
|
addHook({ name: 'amqplib', file: 'lib/channel.js', versions: [MIN_VERSION] }, channel => {
|
|
29
93
|
shimmer.wrap(channel.Channel.prototype, 'sendImmediately', sendImmediately => function (method, fields) {
|
|
30
94
|
return instrument(sendImmediately, this, arguments, methods[method], fields)
|
|
@@ -33,15 +97,11 @@ addHook({ name: 'amqplib', file: 'lib/channel.js', versions: [MIN_VERSION] }, ch
|
|
|
33
97
|
shimmer.wrap(channel.Channel.prototype, 'sendMessage', sendMessage => function (fields) {
|
|
34
98
|
return instrument(sendMessage, this, arguments, 'basic.publish', fields, arguments[2])
|
|
35
99
|
})
|
|
36
|
-
|
|
37
|
-
shimmer.wrap(channel.BaseChannel.prototype, 'dispatchMessage', dispatchMessage => function (fields, message) {
|
|
38
|
-
return instrument(dispatchMessage, this, arguments, 'basic.deliver', fields, message)
|
|
39
|
-
})
|
|
40
100
|
return channel
|
|
41
101
|
})
|
|
42
102
|
|
|
43
103
|
function instrument (send, channel, args, method, fields, message) {
|
|
44
|
-
if (!startCh.hasSubscribers) {
|
|
104
|
+
if (!startCh.hasSubscribers || method === 'basic.get') {
|
|
45
105
|
return send.apply(channel, args)
|
|
46
106
|
}
|
|
47
107
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const shimmer = require('../../datadog-shimmer')
|
|
2
|
+
const { addHook } = require('./helpers/instrument')
|
|
3
|
+
|
|
4
|
+
const dc = require('dc-polyfill')
|
|
5
|
+
const serializeChannel = dc.channel('apm:avsc:serialize-start')
|
|
6
|
+
const deserializeChannel = dc.channel('apm:avsc:deserialize-end')
|
|
7
|
+
|
|
8
|
+
function wrapSerialization (Type) {
|
|
9
|
+
shimmer.wrap(Type.prototype, 'toBuffer', original => function () {
|
|
10
|
+
if (!serializeChannel.hasSubscribers) {
|
|
11
|
+
return original.apply(this, arguments)
|
|
12
|
+
}
|
|
13
|
+
serializeChannel.publish({ messageClass: this })
|
|
14
|
+
return original.apply(this, arguments)
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function wrapDeserialization (Type) {
|
|
19
|
+
shimmer.wrap(Type.prototype, 'fromBuffer', original => function () {
|
|
20
|
+
if (!deserializeChannel.hasSubscribers) {
|
|
21
|
+
return original.apply(this, arguments)
|
|
22
|
+
}
|
|
23
|
+
const result = original.apply(this, arguments)
|
|
24
|
+
deserializeChannel.publish({ messageClass: result })
|
|
25
|
+
return result
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
addHook({
|
|
30
|
+
name: 'avsc',
|
|
31
|
+
versions: ['>=5.0.0']
|
|
32
|
+
}, avro => {
|
|
33
|
+
wrapDeserialization(avro.Type)
|
|
34
|
+
wrapSerialization(avro.Type)
|
|
35
|
+
|
|
36
|
+
return avro
|
|
37
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
addHook
|
|
5
|
+
} = require('./helpers/instrument')
|
|
6
|
+
const shimmer = require('../../datadog-shimmer')
|
|
7
|
+
const dc = require('dc-polyfill')
|
|
8
|
+
|
|
9
|
+
const azureFunctionsChannel = dc.tracingChannel('datadog:azure-functions:invoke')
|
|
10
|
+
|
|
11
|
+
addHook({ name: '@azure/functions', versions: ['>=4'] }, azureFunction => {
|
|
12
|
+
const { app } = azureFunction
|
|
13
|
+
|
|
14
|
+
shimmer.wrap(app, 'deleteRequest', wrapHandler)
|
|
15
|
+
shimmer.wrap(app, 'http', wrapHandler)
|
|
16
|
+
shimmer.wrap(app, 'get', wrapHandler)
|
|
17
|
+
shimmer.wrap(app, 'patch', wrapHandler)
|
|
18
|
+
shimmer.wrap(app, 'post', wrapHandler)
|
|
19
|
+
shimmer.wrap(app, 'put', wrapHandler)
|
|
20
|
+
|
|
21
|
+
return azureFunction
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// The http methods are overloaded so we need to check which type of argument was passed in order to wrap the handler
|
|
25
|
+
// The arguments are either an object with a handler property or the handler function itself
|
|
26
|
+
function wrapHandler (method) {
|
|
27
|
+
return function (name, arg) {
|
|
28
|
+
if (typeof arg === 'object' && arg.hasOwnProperty('handler')) {
|
|
29
|
+
const options = arg
|
|
30
|
+
shimmer.wrap(options, 'handler', handler => traceHandler(handler, name, method.name))
|
|
31
|
+
} else if (typeof arg === 'function') {
|
|
32
|
+
const handler = arg
|
|
33
|
+
arguments[1] = shimmer.wrapFunction(handler, handler => traceHandler(handler, name, method.name))
|
|
34
|
+
}
|
|
35
|
+
return method.apply(this, arguments)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function traceHandler (handler, functionName, methodName) {
|
|
40
|
+
return function (...args) {
|
|
41
|
+
const httpRequest = args[0]
|
|
42
|
+
const invocationContext = args[1]
|
|
43
|
+
return azureFunctionsChannel.tracePromise(
|
|
44
|
+
handler,
|
|
45
|
+
{ functionName, httpRequest, invocationContext, methodName },
|
|
46
|
+
this, ...args)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -13,19 +13,38 @@ const childProcessChannel = dc.tracingChannel('datadog:child_process:execution')
|
|
|
13
13
|
|
|
14
14
|
// ignored exec method because it calls to execFile directly
|
|
15
15
|
const execAsyncMethods = ['execFile', 'spawn']
|
|
16
|
-
const execSyncMethods = ['execFileSync', 'spawnSync']
|
|
17
16
|
|
|
18
17
|
const names = ['child_process', 'node:child_process']
|
|
19
18
|
|
|
20
19
|
// child_process and node:child_process returns the same object instance, we only want to add hooks once
|
|
21
20
|
let patched = false
|
|
21
|
+
|
|
22
|
+
function throwSyncError (error) {
|
|
23
|
+
throw error
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function returnSpawnSyncError (error, context) {
|
|
27
|
+
context.result = {
|
|
28
|
+
error,
|
|
29
|
+
status: null,
|
|
30
|
+
signal: null,
|
|
31
|
+
output: null,
|
|
32
|
+
stdout: null,
|
|
33
|
+
stderr: null,
|
|
34
|
+
pid: 0
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return context.result
|
|
38
|
+
}
|
|
39
|
+
|
|
22
40
|
names.forEach(name => {
|
|
23
41
|
addHook({ name }, childProcess => {
|
|
24
42
|
if (!patched) {
|
|
25
43
|
patched = true
|
|
26
|
-
shimmer.massWrap(childProcess, execAsyncMethods, wrapChildProcessAsyncMethod())
|
|
27
|
-
shimmer.
|
|
28
|
-
shimmer.wrap(childProcess, '
|
|
44
|
+
shimmer.massWrap(childProcess, execAsyncMethods, wrapChildProcessAsyncMethod(childProcess.ChildProcess))
|
|
45
|
+
shimmer.wrap(childProcess, 'execSync', wrapChildProcessSyncMethod(throwSyncError, true))
|
|
46
|
+
shimmer.wrap(childProcess, 'execFileSync', wrapChildProcessSyncMethod(throwSyncError))
|
|
47
|
+
shimmer.wrap(childProcess, 'spawnSync', wrapChildProcessSyncMethod(returnSpawnSyncError))
|
|
29
48
|
}
|
|
30
49
|
|
|
31
50
|
return childProcess
|
|
@@ -34,17 +53,21 @@ names.forEach(name => {
|
|
|
34
53
|
|
|
35
54
|
function normalizeArgs (args, shell) {
|
|
36
55
|
const childProcessInfo = {
|
|
37
|
-
command: args[0]
|
|
56
|
+
command: args[0],
|
|
57
|
+
file: args[0]
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
if (Array.isArray(args[1])) {
|
|
41
61
|
childProcessInfo.command = childProcessInfo.command + ' ' + args[1].join(' ')
|
|
62
|
+
childProcessInfo.fileArgs = args[1]
|
|
63
|
+
|
|
42
64
|
if (args[2] !== null && typeof args[2] === 'object') {
|
|
43
65
|
childProcessInfo.options = args[2]
|
|
44
66
|
}
|
|
45
67
|
} else if (args[1] !== null && typeof args[1] === 'object') {
|
|
46
68
|
childProcessInfo.options = args[1]
|
|
47
69
|
}
|
|
70
|
+
|
|
48
71
|
childProcessInfo.shell = shell ||
|
|
49
72
|
childProcessInfo.options?.shell === true ||
|
|
50
73
|
typeof childProcessInfo.options?.shell === 'string'
|
|
@@ -52,7 +75,21 @@ function normalizeArgs (args, shell) {
|
|
|
52
75
|
return childProcessInfo
|
|
53
76
|
}
|
|
54
77
|
|
|
55
|
-
function
|
|
78
|
+
function createContextFromChildProcessInfo (childProcessInfo) {
|
|
79
|
+
const context = {
|
|
80
|
+
command: childProcessInfo.command,
|
|
81
|
+
file: childProcessInfo.file,
|
|
82
|
+
shell: childProcessInfo.shell
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (childProcessInfo.fileArgs) {
|
|
86
|
+
context.fileArgs = childProcessInfo.fileArgs
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return context
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function wrapChildProcessSyncMethod (returnError, shell = false) {
|
|
56
93
|
return function wrapMethod (childProcessMethod) {
|
|
57
94
|
return function () {
|
|
58
95
|
if (!childProcessChannel.start.hasSubscribers || arguments.length === 0) {
|
|
@@ -61,14 +98,33 @@ function wrapChildProcessSyncMethod (shell = false) {
|
|
|
61
98
|
|
|
62
99
|
const childProcessInfo = normalizeArgs(arguments, shell)
|
|
63
100
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
101
|
+
const innerResource = new AsyncResource('bound-anonymous-fn')
|
|
102
|
+
return innerResource.runInAsyncScope(() => {
|
|
103
|
+
const context = createContextFromChildProcessInfo(childProcessInfo)
|
|
104
|
+
const abortController = new AbortController()
|
|
105
|
+
|
|
106
|
+
childProcessChannel.start.publish({ ...context, abortController })
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
if (abortController.signal.aborted) {
|
|
110
|
+
const error = abortController.signal.reason || new Error('Aborted')
|
|
111
|
+
// expected behaviors on error are different
|
|
112
|
+
return returnError(error, context)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const result = childProcessMethod.apply(this, arguments)
|
|
116
|
+
context.result = result
|
|
117
|
+
|
|
118
|
+
return result
|
|
119
|
+
} catch (err) {
|
|
120
|
+
context.error = err
|
|
121
|
+
childProcessChannel.error.publish(context)
|
|
122
|
+
|
|
123
|
+
throw err
|
|
124
|
+
} finally {
|
|
125
|
+
childProcessChannel.end.publish(context)
|
|
126
|
+
}
|
|
127
|
+
})
|
|
72
128
|
}
|
|
73
129
|
}
|
|
74
130
|
}
|
|
@@ -81,18 +137,52 @@ function wrapChildProcessCustomPromisifyMethod (customPromisifyMethod, shell) {
|
|
|
81
137
|
|
|
82
138
|
const childProcessInfo = normalizeArgs(arguments, shell)
|
|
83
139
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
140
|
+
const context = createContextFromChildProcessInfo(childProcessInfo)
|
|
141
|
+
|
|
142
|
+
const { start, end, asyncStart, asyncEnd, error } = childProcessChannel
|
|
143
|
+
const abortController = new AbortController()
|
|
144
|
+
|
|
145
|
+
start.publish({
|
|
146
|
+
...context,
|
|
147
|
+
abortController
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
let result
|
|
151
|
+
if (abortController.signal.aborted) {
|
|
152
|
+
result = Promise.reject(abortController.signal.reason || new Error('Aborted'))
|
|
153
|
+
} else {
|
|
154
|
+
try {
|
|
155
|
+
result = customPromisifyMethod.apply(this, arguments)
|
|
156
|
+
} catch (error) {
|
|
157
|
+
error.publish({ ...context, error })
|
|
158
|
+
throw error
|
|
159
|
+
} finally {
|
|
160
|
+
end.publish(context)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function reject (err) {
|
|
165
|
+
context.error = err
|
|
166
|
+
error.publish(context)
|
|
167
|
+
asyncStart.publish(context)
|
|
168
|
+
|
|
169
|
+
asyncEnd.publish(context)
|
|
170
|
+
return Promise.reject(err)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function resolve (result) {
|
|
174
|
+
context.result = result
|
|
175
|
+
asyncStart.publish(context)
|
|
176
|
+
|
|
177
|
+
asyncEnd.publish(context)
|
|
178
|
+
return result
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return Promise.prototype.then.call(result, resolve, reject)
|
|
92
182
|
}
|
|
93
183
|
}
|
|
94
184
|
|
|
95
|
-
function wrapChildProcessAsyncMethod (shell = false) {
|
|
185
|
+
function wrapChildProcessAsyncMethod (ChildProcess, shell = false) {
|
|
96
186
|
return function wrapMethod (childProcessMethod) {
|
|
97
187
|
function wrappedChildProcessMethod () {
|
|
98
188
|
if (!childProcessChannel.start.hasSubscribers || arguments.length === 0) {
|
|
@@ -101,11 +191,39 @@ function wrapChildProcessAsyncMethod (shell = false) {
|
|
|
101
191
|
|
|
102
192
|
const childProcessInfo = normalizeArgs(arguments, shell)
|
|
103
193
|
|
|
194
|
+
const cb = arguments[arguments.length - 1]
|
|
195
|
+
if (typeof cb === 'function') {
|
|
196
|
+
const callbackResource = new AsyncResource('bound-anonymous-fn')
|
|
197
|
+
arguments[arguments.length - 1] = callbackResource.bind(cb)
|
|
198
|
+
}
|
|
199
|
+
|
|
104
200
|
const innerResource = new AsyncResource('bound-anonymous-fn')
|
|
105
201
|
return innerResource.runInAsyncScope(() => {
|
|
106
|
-
|
|
202
|
+
const context = createContextFromChildProcessInfo(childProcessInfo)
|
|
203
|
+
const abortController = new AbortController()
|
|
204
|
+
|
|
205
|
+
childProcessChannel.start.publish({ ...context, abortController })
|
|
206
|
+
|
|
207
|
+
let childProcess
|
|
208
|
+
if (abortController.signal.aborted) {
|
|
209
|
+
childProcess = new ChildProcess()
|
|
210
|
+
childProcess.on('error', () => {}) // Original method does not crash when non subscribers
|
|
211
|
+
|
|
212
|
+
process.nextTick(() => {
|
|
213
|
+
const error = abortController.signal.reason || new Error('Aborted')
|
|
214
|
+
childProcess.emit('error', error)
|
|
215
|
+
|
|
216
|
+
const cb = arguments[arguments.length - 1]
|
|
217
|
+
if (typeof cb === 'function') {
|
|
218
|
+
cb(error)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
childProcess.emit('close')
|
|
222
|
+
})
|
|
223
|
+
} else {
|
|
224
|
+
childProcess = childProcessMethod.apply(this, arguments)
|
|
225
|
+
}
|
|
107
226
|
|
|
108
|
-
const childProcess = childProcessMethod.apply(this, arguments)
|
|
109
227
|
if (childProcess) {
|
|
110
228
|
let errorExecuted = false
|
|
111
229
|
|
|
@@ -120,8 +238,7 @@ function wrapChildProcessAsyncMethod (shell = false) {
|
|
|
120
238
|
childProcessChannel.error.publish()
|
|
121
239
|
}
|
|
122
240
|
childProcessChannel.asyncEnd.publish({
|
|
123
|
-
|
|
124
|
-
shell: childProcessInfo.shell,
|
|
241
|
+
...context,
|
|
125
242
|
result: code
|
|
126
243
|
})
|
|
127
244
|
})
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { createWrapRouterMethod } = require('./router')
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
5
|
const { addHook, channel } = require('./helpers/instrument')
|
|
6
|
+
const tracingChannel = require('dc-polyfill').tracingChannel
|
|
6
7
|
|
|
7
8
|
const handleChannel = channel('apm:express:request:handle')
|
|
8
9
|
|
|
@@ -35,6 +36,27 @@ function wrapResponseJson (json) {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
const responseRenderChannel = tracingChannel('datadog:express:response:render')
|
|
40
|
+
|
|
41
|
+
function wrapResponseRender (render) {
|
|
42
|
+
return function wrappedRender (view, options, callback) {
|
|
43
|
+
if (!responseRenderChannel.start.hasSubscribers) {
|
|
44
|
+
return render.apply(this, arguments)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return responseRenderChannel.traceSync(
|
|
48
|
+
render,
|
|
49
|
+
{
|
|
50
|
+
req: this.req,
|
|
51
|
+
view,
|
|
52
|
+
options
|
|
53
|
+
},
|
|
54
|
+
this,
|
|
55
|
+
...arguments
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
38
60
|
addHook({ name: 'express', versions: ['>=4'] }, express => {
|
|
39
61
|
shimmer.wrap(express.application, 'handle', wrapHandle)
|
|
40
62
|
shimmer.wrap(express.Router, 'use', wrapRouterMethod)
|
|
@@ -42,6 +64,7 @@ addHook({ name: 'express', versions: ['>=4'] }, express => {
|
|
|
42
64
|
|
|
43
65
|
shimmer.wrap(express.response, 'json', wrapResponseJson)
|
|
44
66
|
shimmer.wrap(express.response, 'jsonp', wrapResponseJson)
|
|
67
|
+
shimmer.wrap(express.response, 'render', wrapResponseRender)
|
|
45
68
|
|
|
46
69
|
return express
|
|
47
70
|
})
|
|
@@ -79,11 +102,21 @@ addHook({
|
|
|
79
102
|
})
|
|
80
103
|
|
|
81
104
|
const processParamsStartCh = channel('datadog:express:process_params:start')
|
|
82
|
-
|
|
83
|
-
return (original)
|
|
84
|
-
return function () {
|
|
105
|
+
function wrapProcessParamsMethod (requestPositionInArguments) {
|
|
106
|
+
return function wrapProcessParams (original) {
|
|
107
|
+
return function wrappedProcessParams () {
|
|
85
108
|
if (processParamsStartCh.hasSubscribers) {
|
|
86
|
-
|
|
109
|
+
const req = arguments[requestPositionInArguments]
|
|
110
|
+
const abortController = new AbortController()
|
|
111
|
+
|
|
112
|
+
processParamsStartCh.publish({
|
|
113
|
+
req,
|
|
114
|
+
res: req?.res,
|
|
115
|
+
abortController,
|
|
116
|
+
params: req?.params
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
if (abortController.signal.aborted) return
|
|
87
120
|
}
|
|
88
121
|
|
|
89
122
|
return original.apply(this, arguments)
|
|
@@ -5,6 +5,7 @@ const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
|
5
5
|
|
|
6
6
|
const errorChannel = channel('apm:fastify:middleware:error')
|
|
7
7
|
const handleChannel = channel('apm:fastify:request:handle')
|
|
8
|
+
const routeAddedChannel = channel('apm:fastify:route:added')
|
|
8
9
|
|
|
9
10
|
const parsingResources = new WeakMap()
|
|
10
11
|
|
|
@@ -16,6 +17,7 @@ function wrapFastify (fastify, hasParsingEvents) {
|
|
|
16
17
|
|
|
17
18
|
if (!app || typeof app.addHook !== 'function') return app
|
|
18
19
|
|
|
20
|
+
app.addHook('onRoute', onRoute)
|
|
19
21
|
app.addHook('onRequest', onRequest)
|
|
20
22
|
app.addHook('preHandler', preHandler)
|
|
21
23
|
|
|
@@ -86,8 +88,9 @@ function onRequest (request, reply, done) {
|
|
|
86
88
|
|
|
87
89
|
const req = getReq(request)
|
|
88
90
|
const res = getRes(reply)
|
|
91
|
+
const routeConfig = getRouteConfig(request)
|
|
89
92
|
|
|
90
|
-
handleChannel.publish({ req, res })
|
|
93
|
+
handleChannel.publish({ req, res, routeConfig })
|
|
91
94
|
|
|
92
95
|
return done()
|
|
93
96
|
}
|
|
@@ -142,6 +145,10 @@ function getRes (reply) {
|
|
|
142
145
|
return reply && (reply.raw || reply.res || reply)
|
|
143
146
|
}
|
|
144
147
|
|
|
148
|
+
function getRouteConfig (request) {
|
|
149
|
+
return request?.routeOptions?.config
|
|
150
|
+
}
|
|
151
|
+
|
|
145
152
|
function publishError (error, req) {
|
|
146
153
|
if (error) {
|
|
147
154
|
errorChannel.publish({ error, req })
|
|
@@ -150,6 +157,10 @@ function publishError (error, req) {
|
|
|
150
157
|
return error
|
|
151
158
|
}
|
|
152
159
|
|
|
160
|
+
function onRoute (routeOptions) {
|
|
161
|
+
routeAddedChannel.publish({ routeOptions, onRoute })
|
|
162
|
+
}
|
|
163
|
+
|
|
153
164
|
addHook({ name: 'fastify', versions: ['>=3'] }, fastify => {
|
|
154
165
|
const wrapped = shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, true))
|
|
155
166
|
|
|
@@ -266,24 +266,44 @@ function createWrapFunction (prefix = '', override = '') {
|
|
|
266
266
|
const lastIndex = arguments.length - 1
|
|
267
267
|
const cb = typeof arguments[lastIndex] === 'function' && arguments[lastIndex]
|
|
268
268
|
const innerResource = new AsyncResource('bound-anonymous-fn')
|
|
269
|
-
const
|
|
269
|
+
const params = getMethodParamsRelationByPrefix(prefix)[operation]
|
|
270
|
+
const abortController = new AbortController()
|
|
271
|
+
const message = { ...getMessage(method, params, arguments, this), abortController }
|
|
272
|
+
|
|
273
|
+
const finish = innerResource.bind(function (error) {
|
|
274
|
+
if (error !== null && typeof error === 'object') { // fs.exists receives a boolean
|
|
275
|
+
errorChannel.publish(error)
|
|
276
|
+
}
|
|
277
|
+
finishChannel.publish()
|
|
278
|
+
})
|
|
270
279
|
|
|
271
280
|
if (cb) {
|
|
272
281
|
const outerResource = new AsyncResource('bound-anonymous-fn')
|
|
273
282
|
|
|
274
283
|
arguments[lastIndex] = shimmer.wrapFunction(cb, cb => innerResource.bind(function (e) {
|
|
275
|
-
|
|
276
|
-
errorChannel.publish(e)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
finishChannel.publish()
|
|
280
|
-
|
|
284
|
+
finish(e)
|
|
281
285
|
return outerResource.runInAsyncScope(() => cb.apply(this, arguments))
|
|
282
286
|
}))
|
|
283
287
|
}
|
|
284
288
|
|
|
285
289
|
return innerResource.runInAsyncScope(() => {
|
|
286
290
|
startChannel.publish(message)
|
|
291
|
+
|
|
292
|
+
if (abortController.signal.aborted) {
|
|
293
|
+
const error = abortController.signal.reason || new Error('Aborted')
|
|
294
|
+
|
|
295
|
+
if (prefix === 'promises.') {
|
|
296
|
+
finish(error)
|
|
297
|
+
return Promise.reject(error)
|
|
298
|
+
} else if (name.includes('Sync') || !cb) {
|
|
299
|
+
finish(error)
|
|
300
|
+
throw error
|
|
301
|
+
} else if (cb) {
|
|
302
|
+
arguments[lastIndex](error)
|
|
303
|
+
return
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
287
307
|
try {
|
|
288
308
|
const result = original.apply(this, arguments)
|
|
289
309
|
if (cb) return result
|
|
@@ -5,6 +5,7 @@ module.exports = {
|
|
|
5
5
|
'@apollo/gateway': () => require('../apollo'),
|
|
6
6
|
'apollo-server-core': () => require('../apollo-server-core'),
|
|
7
7
|
'@aws-sdk/smithy-client': () => require('../aws-sdk'),
|
|
8
|
+
'@azure/functions': () => require('../azure-functions'),
|
|
8
9
|
'@cucumber/cucumber': () => require('../cucumber'),
|
|
9
10
|
'@playwright/test': () => require('../playwright'),
|
|
10
11
|
'@elastic/elasticsearch': () => require('../elasticsearch'),
|
|
@@ -27,6 +28,7 @@ module.exports = {
|
|
|
27
28
|
aerospike: () => require('../aerospike'),
|
|
28
29
|
amqp10: () => require('../amqp10'),
|
|
29
30
|
amqplib: () => require('../amqplib'),
|
|
31
|
+
avsc: () => require('../avsc'),
|
|
30
32
|
'aws-sdk': () => require('../aws-sdk'),
|
|
31
33
|
bluebird: () => require('../bluebird'),
|
|
32
34
|
'body-parser': () => require('../body-parser'),
|
|
@@ -77,6 +79,7 @@ module.exports = {
|
|
|
77
79
|
'mongodb-core': () => require('../mongodb-core'),
|
|
78
80
|
mongoose: () => require('../mongoose'),
|
|
79
81
|
mquery: () => require('../mquery'),
|
|
82
|
+
multer: () => require('../multer'),
|
|
80
83
|
mysql: () => require('../mysql'),
|
|
81
84
|
mysql2: () => require('../mysql2'),
|
|
82
85
|
net: () => require('../net'),
|
|
@@ -88,6 +91,7 @@ module.exports = {
|
|
|
88
91
|
'node:http2': () => require('../http2'),
|
|
89
92
|
'node:https': () => require('../http'),
|
|
90
93
|
'node:net': () => require('../net'),
|
|
94
|
+
'node:url': () => require('../url'),
|
|
91
95
|
nyc: () => require('../nyc'),
|
|
92
96
|
oracledb: () => require('../oracledb'),
|
|
93
97
|
openai: () => require('../openai'),
|
|
@@ -100,6 +104,7 @@ module.exports = {
|
|
|
100
104
|
playwright: () => require('../playwright'),
|
|
101
105
|
'promise-js': () => require('../promise-js'),
|
|
102
106
|
promise: () => require('../promise'),
|
|
107
|
+
protobufjs: () => require('../protobufjs'),
|
|
103
108
|
q: () => require('../q'),
|
|
104
109
|
qs: () => require('../qs'),
|
|
105
110
|
redis: () => require('../redis'),
|
|
@@ -111,6 +116,7 @@ module.exports = {
|
|
|
111
116
|
sharedb: () => require('../sharedb'),
|
|
112
117
|
tedious: () => require('../tedious'),
|
|
113
118
|
undici: () => require('../undici'),
|
|
119
|
+
url: () => require('../url'),
|
|
114
120
|
vitest: { esmFirst: true, fn: () => require('../vitest') },
|
|
115
121
|
when: () => require('../when'),
|
|
116
122
|
winston: () => require('../winston'),
|
|
@@ -22,6 +22,15 @@ const disabledInstrumentations = new Set(
|
|
|
22
22
|
DD_TRACE_DISABLED_INSTRUMENTATIONS ? DD_TRACE_DISABLED_INSTRUMENTATIONS.split(',') : []
|
|
23
23
|
)
|
|
24
24
|
|
|
25
|
+
// Check for DD_TRACE_<INTEGRATION>_ENABLED environment variables
|
|
26
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
27
|
+
const match = key.match(/^DD_TRACE_(.+)_ENABLED$/)
|
|
28
|
+
if (match && (value.toLowerCase() === 'false' || value === '0')) {
|
|
29
|
+
const integration = match[1].toLowerCase()
|
|
30
|
+
disabledInstrumentations.add(integration)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
25
34
|
const loadChannel = channel('dd-trace:instrumentation:load')
|
|
26
35
|
|
|
27
36
|
// Globals
|