dd-trace 4.47.1 → 4.49.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
|
@@ -52,45 +52,59 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
|
|
|
52
52
|
const send = producer.send
|
|
53
53
|
const bootstrapServers = this._brokers
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
const innerAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
55
|
+
const kafkaClusterIdPromise = getKafkaClusterId(this)
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
57
|
+
producer.send = function () {
|
|
58
|
+
const wrappedSend = (clusterId) => {
|
|
59
|
+
const innerAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (message !== null && typeof message === 'object') {
|
|
67
|
-
message.headers = message.headers || {}
|
|
68
|
-
}
|
|
61
|
+
return innerAsyncResource.runInAsyncScope(() => {
|
|
62
|
+
if (!producerStartCh.hasSubscribers) {
|
|
63
|
+
return send.apply(this, arguments)
|
|
69
64
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
producerFinishCh.publish(undefined)
|
|
77
|
-
producerCommitCh.publish(res)
|
|
78
|
-
}),
|
|
79
|
-
innerAsyncResource.bind(err => {
|
|
80
|
-
if (err) {
|
|
81
|
-
producerErrorCh.publish(err)
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const { topic, messages = [] } = arguments[0]
|
|
68
|
+
for (const message of messages) {
|
|
69
|
+
if (message !== null && typeof message === 'object') {
|
|
70
|
+
message.headers = message.headers || {}
|
|
82
71
|
}
|
|
83
|
-
|
|
84
|
-
})
|
|
85
|
-
)
|
|
72
|
+
}
|
|
73
|
+
producerStartCh.publish({ topic, messages, bootstrapServers, clusterId })
|
|
86
74
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
75
|
+
const result = send.apply(this, arguments)
|
|
76
|
+
|
|
77
|
+
result.then(
|
|
78
|
+
innerAsyncResource.bind(res => {
|
|
79
|
+
producerFinishCh.publish(undefined)
|
|
80
|
+
producerCommitCh.publish(res)
|
|
81
|
+
}),
|
|
82
|
+
innerAsyncResource.bind(err => {
|
|
83
|
+
if (err) {
|
|
84
|
+
producerErrorCh.publish(err)
|
|
85
|
+
}
|
|
86
|
+
producerFinishCh.publish(undefined)
|
|
87
|
+
})
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return result
|
|
91
|
+
} catch (e) {
|
|
92
|
+
producerErrorCh.publish(e)
|
|
93
|
+
producerFinishCh.publish(undefined)
|
|
94
|
+
throw e
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!isPromise(kafkaClusterIdPromise)) {
|
|
100
|
+
// promise is already resolved
|
|
101
|
+
return wrappedSend(kafkaClusterIdPromise)
|
|
102
|
+
} else {
|
|
103
|
+
// promise is not resolved
|
|
104
|
+
return kafkaClusterIdPromise.then((clusterId) => {
|
|
105
|
+
return wrappedSend(clusterId)
|
|
106
|
+
})
|
|
107
|
+
}
|
|
94
108
|
}
|
|
95
109
|
return producer
|
|
96
110
|
})
|
|
@@ -100,15 +114,17 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
|
|
|
100
114
|
return createConsumer.apply(this, arguments)
|
|
101
115
|
}
|
|
102
116
|
|
|
103
|
-
const
|
|
117
|
+
const kafkaClusterIdPromise = getKafkaClusterId(this)
|
|
118
|
+
|
|
119
|
+
const eachMessageExtractor = (args, clusterId) => {
|
|
104
120
|
const { topic, partition, message } = args[0]
|
|
105
|
-
return { topic, partition, message, groupId }
|
|
121
|
+
return { topic, partition, message, groupId, clusterId }
|
|
106
122
|
}
|
|
107
123
|
|
|
108
|
-
const eachBatchExtractor = (args) => {
|
|
124
|
+
const eachBatchExtractor = (args, clusterId) => {
|
|
109
125
|
const { batch } = args[0]
|
|
110
126
|
const { topic, partition, messages } = batch
|
|
111
|
-
return { topic, partition, messages, groupId }
|
|
127
|
+
return { topic, partition, messages, groupId, clusterId }
|
|
112
128
|
}
|
|
113
129
|
|
|
114
130
|
const consumer = createConsumer.apply(this, arguments)
|
|
@@ -116,43 +132,53 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
|
|
|
116
132
|
consumer.on(consumer.events.COMMIT_OFFSETS, commitsFromEvent)
|
|
117
133
|
|
|
118
134
|
const run = consumer.run
|
|
119
|
-
|
|
120
135
|
const groupId = arguments[0].groupId
|
|
136
|
+
|
|
121
137
|
consumer.run = function ({ eachMessage, eachBatch, ...runArgs }) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
138
|
+
const wrapConsume = (clusterId) => {
|
|
139
|
+
return run({
|
|
140
|
+
eachMessage: wrappedCallback(
|
|
141
|
+
eachMessage,
|
|
142
|
+
consumerStartCh,
|
|
143
|
+
consumerFinishCh,
|
|
144
|
+
consumerErrorCh,
|
|
145
|
+
eachMessageExtractor,
|
|
146
|
+
clusterId
|
|
147
|
+
),
|
|
148
|
+
eachBatch: wrappedCallback(
|
|
149
|
+
eachBatch,
|
|
150
|
+
batchConsumerStartCh,
|
|
151
|
+
batchConsumerFinishCh,
|
|
152
|
+
batchConsumerErrorCh,
|
|
153
|
+
eachBatchExtractor,
|
|
154
|
+
clusterId
|
|
155
|
+
),
|
|
156
|
+
...runArgs
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!isPromise(kafkaClusterIdPromise)) {
|
|
161
|
+
// promise is already resolved
|
|
162
|
+
return wrapConsume(kafkaClusterIdPromise)
|
|
163
|
+
} else {
|
|
164
|
+
// promise is not resolved
|
|
165
|
+
return kafkaClusterIdPromise.then((clusterId) => {
|
|
166
|
+
return wrapConsume(clusterId)
|
|
167
|
+
})
|
|
168
|
+
}
|
|
143
169
|
}
|
|
144
|
-
|
|
145
170
|
return consumer
|
|
146
171
|
})
|
|
147
172
|
return Kafka
|
|
148
173
|
})
|
|
149
174
|
|
|
150
|
-
const
|
|
175
|
+
const wrappedCallback = (fn, startCh, finishCh, errorCh, extractArgs, clusterId) => {
|
|
151
176
|
return typeof fn === 'function'
|
|
152
177
|
? function (...args) {
|
|
153
178
|
const innerAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
154
179
|
return innerAsyncResource.runInAsyncScope(() => {
|
|
155
|
-
const extractedArgs = extractArgs(args)
|
|
180
|
+
const extractedArgs = extractArgs(args, clusterId)
|
|
181
|
+
|
|
156
182
|
startCh.publish(extractedArgs)
|
|
157
183
|
try {
|
|
158
184
|
const result = fn.apply(this, args)
|
|
@@ -179,3 +205,37 @@ const wrapFunction = (fn, startCh, finishCh, errorCh, extractArgs) => {
|
|
|
179
205
|
}
|
|
180
206
|
: fn
|
|
181
207
|
}
|
|
208
|
+
|
|
209
|
+
const getKafkaClusterId = (kafka) => {
|
|
210
|
+
if (kafka._ddKafkaClusterId) {
|
|
211
|
+
return kafka._ddKafkaClusterId
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (!kafka.admin) {
|
|
215
|
+
return null
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const admin = kafka.admin()
|
|
219
|
+
|
|
220
|
+
if (!admin.describeCluster) {
|
|
221
|
+
return null
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return admin.connect()
|
|
225
|
+
.then(() => {
|
|
226
|
+
return admin.describeCluster()
|
|
227
|
+
})
|
|
228
|
+
.then((clusterInfo) => {
|
|
229
|
+
const clusterId = clusterInfo?.clusterId
|
|
230
|
+
kafka._ddKafkaClusterId = clusterId
|
|
231
|
+
admin.disconnect()
|
|
232
|
+
return clusterId
|
|
233
|
+
})
|
|
234
|
+
.catch((error) => {
|
|
235
|
+
throw error
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function isPromise (obj) {
|
|
240
|
+
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'
|
|
241
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { addHook, channel } = require('../helpers/instrument')
|
|
2
2
|
const shimmer = require('../../../datadog-shimmer')
|
|
3
|
-
const { getCallSites } = require('../../../dd-trace/src/plugins/util/
|
|
3
|
+
const { getCallSites } = require('../../../dd-trace/src/plugins/util/stacktrace')
|
|
4
4
|
const { testToStartLine } = require('./utils')
|
|
5
5
|
|
|
6
6
|
const parameterizedTestCh = channel('ci:mocha:test:parameterize')
|
|
@@ -280,12 +280,12 @@ function getOnFailHandler (isMain) {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
function getOnTestRetryHandler () {
|
|
283
|
-
return function (test) {
|
|
283
|
+
return function (test, err) {
|
|
284
284
|
const asyncResource = getTestAsyncResource(test)
|
|
285
285
|
if (asyncResource) {
|
|
286
286
|
const isFirstAttempt = test._currentRetry === 0
|
|
287
287
|
asyncResource.runInAsyncScope(() => {
|
|
288
|
-
testRetryCh.publish(isFirstAttempt)
|
|
288
|
+
testRetryCh.publish({ isFirstAttempt, err })
|
|
289
289
|
})
|
|
290
290
|
}
|
|
291
291
|
const key = getTestToArKey(test)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../datadog-shimmer')
|
|
4
|
+
const { channel, addHook, AsyncResource } = require('./helpers/instrument')
|
|
5
|
+
|
|
6
|
+
const multerReadCh = channel('datadog:multer:read:finish')
|
|
7
|
+
|
|
8
|
+
function publishRequestBodyAndNext (req, res, next) {
|
|
9
|
+
return shimmer.wrapFunction(next, next => function () {
|
|
10
|
+
if (multerReadCh.hasSubscribers && req) {
|
|
11
|
+
const abortController = new AbortController()
|
|
12
|
+
const body = req.body
|
|
13
|
+
|
|
14
|
+
multerReadCh.publish({ req, res, body, abortController })
|
|
15
|
+
|
|
16
|
+
if (abortController.signal.aborted) return
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return next.apply(this, arguments)
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
addHook({
|
|
24
|
+
name: 'multer',
|
|
25
|
+
file: 'lib/make-middleware.js',
|
|
26
|
+
versions: ['^1.4.4-lts.1']
|
|
27
|
+
}, makeMiddleware => {
|
|
28
|
+
return shimmer.wrapFunction(makeMiddleware, makeMiddleware => function () {
|
|
29
|
+
const middleware = makeMiddleware.apply(this, arguments)
|
|
30
|
+
|
|
31
|
+
return shimmer.wrapFunction(middleware, middleware => function wrapMulterMiddleware (req, res, next) {
|
|
32
|
+
const nextResource = new AsyncResource('bound-anonymous-fn')
|
|
33
|
+
arguments[2] = nextResource.bind(publishRequestBodyAndNext(req, res, next))
|
|
34
|
+
return middleware.apply(this, arguments)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
})
|
|
@@ -6,11 +6,14 @@ const {
|
|
|
6
6
|
AsyncResource
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
8
|
const shimmer = require('../../datadog-shimmer')
|
|
9
|
+
const semver = require('semver')
|
|
9
10
|
|
|
10
|
-
addHook({ name: 'mysql2', file: 'lib/connection.js', versions: ['>=1'] }, Connection => {
|
|
11
|
+
addHook({ name: 'mysql2', file: 'lib/connection.js', versions: ['>=1'] }, (Connection, version) => {
|
|
11
12
|
const startCh = channel('apm:mysql2:query:start')
|
|
12
13
|
const finishCh = channel('apm:mysql2:query:finish')
|
|
13
14
|
const errorCh = channel('apm:mysql2:query:error')
|
|
15
|
+
const startOuterQueryCh = channel('datadog:mysql2:outerquery:start')
|
|
16
|
+
const shouldEmitEndAfterQueryAbort = semver.intersects(version, '>=1.3.3')
|
|
14
17
|
|
|
15
18
|
shimmer.wrap(Connection.prototype, 'addCommand', addCommand => function (cmd) {
|
|
16
19
|
if (!startCh.hasSubscribers) return addCommand.apply(this, arguments)
|
|
@@ -28,6 +31,76 @@ addHook({ name: 'mysql2', file: 'lib/connection.js', versions: ['>=1'] }, Connec
|
|
|
28
31
|
return asyncResource.bind(addCommand, this).apply(this, arguments)
|
|
29
32
|
})
|
|
30
33
|
|
|
34
|
+
shimmer.wrap(Connection.prototype, 'query', query => function (sql, values, cb) {
|
|
35
|
+
if (!startOuterQueryCh.hasSubscribers) return query.apply(this, arguments)
|
|
36
|
+
|
|
37
|
+
if (typeof sql === 'object') sql = sql?.sql
|
|
38
|
+
|
|
39
|
+
if (!sql) return query.apply(this, arguments)
|
|
40
|
+
|
|
41
|
+
const abortController = new AbortController()
|
|
42
|
+
startOuterQueryCh.publish({ sql, abortController })
|
|
43
|
+
|
|
44
|
+
if (abortController.signal.aborted) {
|
|
45
|
+
const addCommand = this.addCommand
|
|
46
|
+
this.addCommand = function (cmd) { return cmd }
|
|
47
|
+
|
|
48
|
+
let queryCommand
|
|
49
|
+
try {
|
|
50
|
+
queryCommand = query.apply(this, arguments)
|
|
51
|
+
} finally {
|
|
52
|
+
this.addCommand = addCommand
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
cb = queryCommand.onResult
|
|
56
|
+
|
|
57
|
+
process.nextTick(() => {
|
|
58
|
+
if (cb) {
|
|
59
|
+
cb(abortController.signal.reason)
|
|
60
|
+
} else {
|
|
61
|
+
queryCommand.emit('error', abortController.signal.reason)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (shouldEmitEndAfterQueryAbort) {
|
|
65
|
+
queryCommand.emit('end')
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
return queryCommand
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return query.apply(this, arguments)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
shimmer.wrap(Connection.prototype, 'execute', execute => function (sql, values, cb) {
|
|
76
|
+
if (!startOuterQueryCh.hasSubscribers) return execute.apply(this, arguments)
|
|
77
|
+
|
|
78
|
+
if (typeof sql === 'object') sql = sql?.sql
|
|
79
|
+
|
|
80
|
+
if (!sql) return execute.apply(this, arguments)
|
|
81
|
+
|
|
82
|
+
const abortController = new AbortController()
|
|
83
|
+
startOuterQueryCh.publish({ sql, abortController })
|
|
84
|
+
|
|
85
|
+
if (abortController.signal.aborted) {
|
|
86
|
+
const addCommand = this.addCommand
|
|
87
|
+
this.addCommand = function (cmd) { return cmd }
|
|
88
|
+
|
|
89
|
+
let result
|
|
90
|
+
try {
|
|
91
|
+
result = execute.apply(this, arguments)
|
|
92
|
+
} finally {
|
|
93
|
+
this.addCommand = addCommand
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
result?.onResult(abortController.signal.reason)
|
|
97
|
+
|
|
98
|
+
return result
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return execute.apply(this, arguments)
|
|
102
|
+
})
|
|
103
|
+
|
|
31
104
|
return Connection
|
|
32
105
|
|
|
33
106
|
function bindExecute (cmd, execute, asyncResource) {
|
|
@@ -79,3 +152,149 @@ addHook({ name: 'mysql2', file: 'lib/connection.js', versions: ['>=1'] }, Connec
|
|
|
79
152
|
}, cmd))
|
|
80
153
|
}
|
|
81
154
|
})
|
|
155
|
+
|
|
156
|
+
addHook({ name: 'mysql2', file: 'lib/pool.js', versions: ['>=1'] }, (Pool, version) => {
|
|
157
|
+
const startOuterQueryCh = channel('datadog:mysql2:outerquery:start')
|
|
158
|
+
const shouldEmitEndAfterQueryAbort = semver.intersects(version, '>=1.3.3')
|
|
159
|
+
|
|
160
|
+
shimmer.wrap(Pool.prototype, 'query', query => function (sql, values, cb) {
|
|
161
|
+
if (!startOuterQueryCh.hasSubscribers) return query.apply(this, arguments)
|
|
162
|
+
|
|
163
|
+
if (typeof sql === 'object') sql = sql?.sql
|
|
164
|
+
|
|
165
|
+
if (!sql) return query.apply(this, arguments)
|
|
166
|
+
|
|
167
|
+
const abortController = new AbortController()
|
|
168
|
+
startOuterQueryCh.publish({ sql, abortController })
|
|
169
|
+
|
|
170
|
+
if (abortController.signal.aborted) {
|
|
171
|
+
const getConnection = this.getConnection
|
|
172
|
+
this.getConnection = function () {}
|
|
173
|
+
|
|
174
|
+
let queryCommand
|
|
175
|
+
try {
|
|
176
|
+
queryCommand = query.apply(this, arguments)
|
|
177
|
+
} finally {
|
|
178
|
+
this.getConnection = getConnection
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
process.nextTick(() => {
|
|
182
|
+
if (queryCommand.onResult) {
|
|
183
|
+
queryCommand.onResult(abortController.signal.reason)
|
|
184
|
+
} else {
|
|
185
|
+
queryCommand.emit('error', abortController.signal.reason)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (shouldEmitEndAfterQueryAbort) {
|
|
189
|
+
queryCommand.emit('end')
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
return queryCommand
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return query.apply(this, arguments)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
shimmer.wrap(Pool.prototype, 'execute', execute => function (sql, values, cb) {
|
|
200
|
+
if (!startOuterQueryCh.hasSubscribers) return execute.apply(this, arguments)
|
|
201
|
+
|
|
202
|
+
if (typeof sql === 'object') sql = sql?.sql
|
|
203
|
+
|
|
204
|
+
if (!sql) return execute.apply(this, arguments)
|
|
205
|
+
|
|
206
|
+
const abortController = new AbortController()
|
|
207
|
+
startOuterQueryCh.publish({ sql, abortController })
|
|
208
|
+
|
|
209
|
+
if (abortController.signal.aborted) {
|
|
210
|
+
if (typeof values === 'function') {
|
|
211
|
+
cb = values
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
process.nextTick(() => {
|
|
215
|
+
cb(abortController.signal.reason)
|
|
216
|
+
})
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return execute.apply(this, arguments)
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
return Pool
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
// PoolNamespace.prototype.query does not exist in mysql2<2.3.0
|
|
227
|
+
addHook({ name: 'mysql2', file: 'lib/pool_cluster.js', versions: ['>=2.3.0'] }, PoolCluster => {
|
|
228
|
+
const startOuterQueryCh = channel('datadog:mysql2:outerquery:start')
|
|
229
|
+
const wrappedPoolNamespaces = new WeakSet()
|
|
230
|
+
|
|
231
|
+
shimmer.wrap(PoolCluster.prototype, 'of', of => function () {
|
|
232
|
+
const poolNamespace = of.apply(this, arguments)
|
|
233
|
+
|
|
234
|
+
if (startOuterQueryCh.hasSubscribers && !wrappedPoolNamespaces.has(poolNamespace)) {
|
|
235
|
+
shimmer.wrap(poolNamespace, 'query', query => function (sql, values, cb) {
|
|
236
|
+
if (typeof sql === 'object') sql = sql?.sql
|
|
237
|
+
|
|
238
|
+
if (!sql) return query.apply(this, arguments)
|
|
239
|
+
|
|
240
|
+
const abortController = new AbortController()
|
|
241
|
+
startOuterQueryCh.publish({ sql, abortController })
|
|
242
|
+
|
|
243
|
+
if (abortController.signal.aborted) {
|
|
244
|
+
const getConnection = this.getConnection
|
|
245
|
+
this.getConnection = function () {}
|
|
246
|
+
|
|
247
|
+
let queryCommand
|
|
248
|
+
try {
|
|
249
|
+
queryCommand = query.apply(this, arguments)
|
|
250
|
+
} finally {
|
|
251
|
+
this.getConnection = getConnection
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
process.nextTick(() => {
|
|
255
|
+
if (queryCommand.onResult) {
|
|
256
|
+
queryCommand.onResult(abortController.signal.reason)
|
|
257
|
+
} else {
|
|
258
|
+
queryCommand.emit('error', abortController.signal.reason)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
queryCommand.emit('end')
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
return queryCommand
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return query.apply(this, arguments)
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
shimmer.wrap(poolNamespace, 'execute', execute => function (sql, values, cb) {
|
|
271
|
+
if (typeof sql === 'object') sql = sql?.sql
|
|
272
|
+
|
|
273
|
+
if (!sql) return execute.apply(this, arguments)
|
|
274
|
+
|
|
275
|
+
const abortController = new AbortController()
|
|
276
|
+
startOuterQueryCh.publish({ sql, abortController })
|
|
277
|
+
|
|
278
|
+
if (abortController.signal.aborted) {
|
|
279
|
+
if (typeof values === 'function') {
|
|
280
|
+
cb = values
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
process.nextTick(() => {
|
|
284
|
+
cb(abortController.signal.reason)
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
return
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return execute.apply(this, arguments)
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
wrappedPoolNamespaces.add(poolNamespace)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return poolNamespace
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
return PoolCluster
|
|
300
|
+
})
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const { addHook } = require('./helpers/instrument')
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
const ch = tracingChannel('apm:openai:request')
|
|
6
|
+
const dc = require('dc-polyfill')
|
|
7
|
+
const ch = dc.tracingChannel('apm:openai:request')
|
|
8
8
|
|
|
9
9
|
const V4_PACKAGE_SHIMS = [
|
|
10
10
|
{
|
|
@@ -0,0 +1,127 @@
|
|
|
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:protobufjs:serialize-start')
|
|
6
|
+
const deserializeChannel = dc.channel('apm:protobufjs:deserialize-end')
|
|
7
|
+
|
|
8
|
+
function wrapSerialization (messageClass) {
|
|
9
|
+
if (messageClass?.encode) {
|
|
10
|
+
shimmer.wrap(messageClass, 'encode', original => function () {
|
|
11
|
+
if (!serializeChannel.hasSubscribers) {
|
|
12
|
+
return original.apply(this, arguments)
|
|
13
|
+
}
|
|
14
|
+
serializeChannel.publish({ messageClass: this })
|
|
15
|
+
return original.apply(this, arguments)
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function wrapDeserialization (messageClass) {
|
|
21
|
+
if (messageClass?.decode) {
|
|
22
|
+
shimmer.wrap(messageClass, 'decode', original => function () {
|
|
23
|
+
if (!deserializeChannel.hasSubscribers) {
|
|
24
|
+
return original.apply(this, arguments)
|
|
25
|
+
}
|
|
26
|
+
const result = original.apply(this, arguments)
|
|
27
|
+
deserializeChannel.publish({ messageClass: result })
|
|
28
|
+
return result
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function wrapSetup (messageClass) {
|
|
34
|
+
if (messageClass?.setup) {
|
|
35
|
+
shimmer.wrap(messageClass, 'setup', original => function () {
|
|
36
|
+
const result = original.apply(this, arguments)
|
|
37
|
+
|
|
38
|
+
wrapSerialization(messageClass)
|
|
39
|
+
wrapDeserialization(messageClass)
|
|
40
|
+
|
|
41
|
+
return result
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function wrapProtobufClasses (root) {
|
|
47
|
+
if (!root) {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (root.decode) {
|
|
52
|
+
wrapSetup(root)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (root.nestedArray) {
|
|
56
|
+
for (const subRoot of root.nestedArray) {
|
|
57
|
+
wrapProtobufClasses(subRoot)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function wrapReflection (protobuf) {
|
|
63
|
+
const reflectionMethods = [
|
|
64
|
+
{
|
|
65
|
+
target: protobuf.Root,
|
|
66
|
+
name: 'fromJSON'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
target: protobuf.Type.prototype,
|
|
70
|
+
name: 'fromObject'
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
reflectionMethods.forEach(method => {
|
|
75
|
+
shimmer.wrap(method.target, method.name, original => function () {
|
|
76
|
+
const result = original.apply(this, arguments)
|
|
77
|
+
if (result.nested) {
|
|
78
|
+
for (const type in result.nested) {
|
|
79
|
+
wrapSetup(result.nested[type])
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (result.$type) {
|
|
83
|
+
wrapSetup(result.$type)
|
|
84
|
+
}
|
|
85
|
+
return result
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function isPromise (obj) {
|
|
91
|
+
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
addHook({
|
|
95
|
+
name: 'protobufjs',
|
|
96
|
+
versions: ['>=6.8.0']
|
|
97
|
+
}, protobuf => {
|
|
98
|
+
shimmer.wrap(protobuf.Root.prototype, 'load', original => function () {
|
|
99
|
+
const result = original.apply(this, arguments)
|
|
100
|
+
if (isPromise(result)) {
|
|
101
|
+
return result.then(root => {
|
|
102
|
+
wrapProtobufClasses(root)
|
|
103
|
+
return root
|
|
104
|
+
})
|
|
105
|
+
} else {
|
|
106
|
+
// If result is not a promise, directly wrap the protobuf classes
|
|
107
|
+
wrapProtobufClasses(result)
|
|
108
|
+
return result
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
shimmer.wrap(protobuf.Root.prototype, 'loadSync', original => function () {
|
|
113
|
+
const root = original.apply(this, arguments)
|
|
114
|
+
wrapProtobufClasses(root)
|
|
115
|
+
return root
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
shimmer.wrap(protobuf, 'Type', Original => function () {
|
|
119
|
+
const typeInstance = new Original(...arguments)
|
|
120
|
+
wrapSetup(typeInstance)
|
|
121
|
+
return typeInstance
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
wrapReflection(protobuf)
|
|
125
|
+
|
|
126
|
+
return protobuf
|
|
127
|
+
})
|