dd-trace 5.101.0 → 5.103.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/ext/exporters.js +1 -0
- package/package.json +20 -17
- package/packages/datadog-esbuild/src/utils.js +2 -2
- package/packages/datadog-instrumentations/src/aerospike.js +2 -2
- package/packages/datadog-instrumentations/src/ai.js +9 -9
- package/packages/datadog-instrumentations/src/amqplib.js +6 -7
- package/packages/datadog-instrumentations/src/anthropic.js +10 -10
- package/packages/datadog-instrumentations/src/apollo-server-core.js +3 -3
- package/packages/datadog-instrumentations/src/apollo-server.js +5 -5
- package/packages/datadog-instrumentations/src/avsc.js +6 -6
- package/packages/datadog-instrumentations/src/aws-sdk.js +151 -67
- package/packages/datadog-instrumentations/src/azure-durable-functions.js +8 -8
- package/packages/datadog-instrumentations/src/bluebird.js +2 -2
- package/packages/datadog-instrumentations/src/body-parser.js +2 -2
- package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
- package/packages/datadog-instrumentations/src/child_process.js +12 -12
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +41 -24
- package/packages/datadog-instrumentations/src/connect.js +7 -7
- package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
- package/packages/datadog-instrumentations/src/cookie.js +2 -2
- package/packages/datadog-instrumentations/src/couchbase.js +73 -238
- package/packages/datadog-instrumentations/src/crypto.js +4 -4
- package/packages/datadog-instrumentations/src/cucumber.js +78 -17
- package/packages/datadog-instrumentations/src/dns.js +0 -3
- package/packages/datadog-instrumentations/src/elasticsearch.js +8 -11
- package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
- package/packages/datadog-instrumentations/src/electron.js +240 -0
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +6 -6
- package/packages/datadog-instrumentations/src/express-session.js +4 -4
- package/packages/datadog-instrumentations/src/express.js +10 -11
- package/packages/datadog-instrumentations/src/fastify.js +2 -2
- package/packages/datadog-instrumentations/src/fetch.js +5 -5
- package/packages/datadog-instrumentations/src/fs.js +14 -14
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +5 -7
- package/packages/datadog-instrumentations/src/google-genai.js +4 -4
- package/packages/datadog-instrumentations/src/graphql.js +13 -12
- package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
- package/packages/datadog-instrumentations/src/hapi.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +9 -9
- package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/kafka.js +41 -0
- package/packages/datadog-instrumentations/src/helpers/promise.js +2 -2
- package/packages/datadog-instrumentations/src/hono.js +2 -2
- package/packages/datadog-instrumentations/src/http/client.js +6 -6
- package/packages/datadog-instrumentations/src/http/server.js +9 -9
- package/packages/datadog-instrumentations/src/ioredis.js +16 -12
- package/packages/datadog-instrumentations/src/jest.js +382 -81
- package/packages/datadog-instrumentations/src/kafkajs.js +165 -174
- package/packages/datadog-instrumentations/src/knex.js +17 -17
- package/packages/datadog-instrumentations/src/koa.js +12 -12
- package/packages/datadog-instrumentations/src/ldapjs.js +5 -5
- package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
- package/packages/datadog-instrumentations/src/limitd-client.js +4 -4
- package/packages/datadog-instrumentations/src/lodash.js +4 -4
- package/packages/datadog-instrumentations/src/mariadb.js +13 -13
- package/packages/datadog-instrumentations/src/memcached.js +2 -2
- package/packages/datadog-instrumentations/src/microgateway-core.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +3 -3
- package/packages/datadog-instrumentations/src/mocha/main.js +85 -11
- package/packages/datadog-instrumentations/src/mocha/utils.js +133 -16
- package/packages/datadog-instrumentations/src/mocha/worker.js +7 -5
- package/packages/datadog-instrumentations/src/mongodb-core.js +42 -30
- package/packages/datadog-instrumentations/src/mongodb.js +5 -5
- package/packages/datadog-instrumentations/src/mongoose.js +21 -21
- package/packages/datadog-instrumentations/src/mquery.js +5 -5
- package/packages/datadog-instrumentations/src/multer.js +4 -4
- package/packages/datadog-instrumentations/src/mysql.js +16 -16
- package/packages/datadog-instrumentations/src/mysql2.js +4 -4
- package/packages/datadog-instrumentations/src/net.js +14 -8
- package/packages/datadog-instrumentations/src/nyc.js +5 -5
- package/packages/datadog-instrumentations/src/openai.js +19 -19
- package/packages/datadog-instrumentations/src/oracledb.js +6 -6
- package/packages/datadog-instrumentations/src/passport-utils.js +5 -5
- package/packages/datadog-instrumentations/src/pg.js +39 -25
- package/packages/datadog-instrumentations/src/pino.js +6 -10
- package/packages/datadog-instrumentations/src/playwright.js +445 -68
- package/packages/datadog-instrumentations/src/protobufjs.js +16 -16
- package/packages/datadog-instrumentations/src/redis.js +20 -12
- package/packages/datadog-instrumentations/src/restify.js +2 -2
- package/packages/datadog-instrumentations/src/router.js +12 -12
- package/packages/datadog-instrumentations/src/stripe.js +12 -12
- package/packages/datadog-instrumentations/src/vitest.js +107 -26
- package/packages/datadog-instrumentations/src/winston.js +4 -4
- package/packages/datadog-instrumentations/src/ws.js +7 -7
- package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
- package/packages/datadog-plugin-aws-sdk/src/base.js +70 -28
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +20 -13
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +46 -36
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +34 -23
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +14 -15
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +74 -55
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +20 -18
- package/packages/datadog-plugin-aws-sdk/src/util.js +22 -0
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -6
- package/packages/datadog-plugin-couchbase/src/index.js +58 -52
- package/packages/datadog-plugin-cucumber/src/index.js +5 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +215 -26
- package/packages/datadog-plugin-cypress/src/support.js +13 -1
- package/packages/datadog-plugin-electron/src/index.js +17 -0
- package/packages/datadog-plugin-electron/src/ipc.js +143 -0
- package/packages/datadog-plugin-electron/src/net.js +82 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -5
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +3 -1
- package/packages/datadog-plugin-graphql/src/execute.js +6 -28
- package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
- package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
- package/packages/datadog-plugin-graphql/src/utils.js +29 -0
- package/packages/datadog-plugin-grpc/src/client.js +6 -7
- package/packages/datadog-plugin-grpc/src/util.js +57 -22
- package/packages/datadog-plugin-http/src/client.js +3 -7
- package/packages/datadog-plugin-jest/src/index.js +92 -50
- package/packages/datadog-plugin-jest/src/util.js +1 -2
- package/packages/datadog-plugin-mocha/src/index.js +5 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +36 -69
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/services.js +2 -1
- package/packages/datadog-plugin-openai/src/tracing.js +12 -23
- package/packages/datadog-plugin-pg/src/index.js +3 -3
- package/packages/datadog-plugin-playwright/src/index.js +5 -1
- package/packages/datadog-plugin-redis/src/index.js +18 -23
- package/packages/datadog-plugin-vitest/src/index.js +8 -1
- package/packages/datadog-shimmer/src/shimmer.js +7 -1
- package/packages/dd-trace/src/aiguard/index.js +3 -1
- package/packages/dd-trace/src/aiguard/sdk.js +36 -30
- package/packages/dd-trace/src/aiguard/tags.js +20 -11
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +81 -81
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +4 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +83 -48
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +21 -24
- package/packages/dd-trace/src/appsec/reporter.js +3 -1
- package/packages/dd-trace/src/appsec/rule_manager.js +4 -2
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +31 -16
- package/packages/dd-trace/src/azure_metadata.js +17 -6
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
- package/packages/dd-trace/src/config/defaults.js +3 -14
- package/packages/dd-trace/src/config/generated-config-types.d.ts +3 -1
- package/packages/dd-trace/src/config/git_properties.js +2 -2
- package/packages/dd-trace/src/config/helper.js +4 -0
- package/packages/dd-trace/src/config/index.js +2 -2
- package/packages/dd-trace/src/config/major-overrides.js +98 -0
- package/packages/dd-trace/src/config/parsers.js +7 -1
- package/packages/dd-trace/src/config/supported-configurations.json +51 -38
- package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
- package/packages/dd-trace/src/datastreams/index.js +2 -1
- package/packages/dd-trace/src/datastreams/manager.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
- package/packages/dd-trace/src/debugger/index.js +7 -7
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +748 -232
- package/packages/dd-trace/src/encode/0.5.js +47 -10
- package/packages/dd-trace/src/encode/agentless-json.js +1 -1
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
- package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/electron/index.js +49 -0
- package/packages/dd-trace/src/external-logger/src/index.js +2 -1
- package/packages/dd-trace/src/git_metadata.js +10 -8
- package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
- package/packages/dd-trace/src/lambda/index.js +62 -14
- package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
- package/packages/dd-trace/src/llmobs/index.js +13 -2
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -2
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +6 -3
- package/packages/dd-trace/src/llmobs/sdk.js +24 -26
- package/packages/dd-trace/src/llmobs/span_processor.js +25 -5
- package/packages/dd-trace/src/llmobs/util.js +1 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
- package/packages/dd-trace/src/msgpack/chunk.js +6 -3
- package/packages/dd-trace/src/openfeature/noop.js +40 -36
- package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
- package/packages/dd-trace/src/openfeature/writers/exposures.js +33 -52
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +2 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +1 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +0 -22
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -11
- package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +49 -4
- package/packages/dd-trace/src/plugins/database.js +54 -12
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/plugin.js +2 -4
- package/packages/dd-trace/src/plugins/util/ci.js +9 -9
- package/packages/dd-trace/src/plugins/util/git-cache.js +23 -23
- package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
- package/packages/dd-trace/src/plugins/util/test.js +56 -12
- package/packages/dd-trace/src/plugins/util/url.js +1 -3
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +18 -16
- package/packages/dd-trace/src/plugins/util/web.js +5 -7
- package/packages/dd-trace/src/priority_sampler.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -23
- package/packages/dd-trace/src/profiling/profilers/wall.js +5 -6
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
- package/packages/dd-trace/src/rate_limiter.js +1 -1
- package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
- package/packages/dd-trace/src/ritm.js +2 -1
- package/packages/dd-trace/src/runtime_metrics/index.js +2 -2
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
- package/packages/dd-trace/src/scope.js +3 -10
- package/packages/dd-trace/src/serverless.js +6 -6
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +27 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +24 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
- package/packages/dd-trace/src/span_stats.js +1 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
- package/packages/dd-trace/src/tracer.js +7 -7
- package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
|
@@ -4,48 +4,146 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
4
4
|
const { channel, addHook } = require('./helpers/instrument')
|
|
5
5
|
|
|
6
6
|
const patchedClientConfigProtocols = new WeakSet()
|
|
7
|
+
const patchedCommandPrototypes = new WeakSet()
|
|
8
|
+
|
|
9
|
+
// Resource identifiers that already match the channel-suffix slug. Anything
|
|
10
|
+
// else falls back to `'default'`. Hoisted out of the per-call hot path so we
|
|
11
|
+
// don't allocate a fresh Array literal + run `.includes` on every AWS send.
|
|
12
|
+
const KNOWN_CHANNEL_SUFFIXES = new Set([
|
|
13
|
+
'cloudwatchlogs',
|
|
14
|
+
'dynamodb',
|
|
15
|
+
'eventbridge',
|
|
16
|
+
'kinesis',
|
|
17
|
+
'lambda',
|
|
18
|
+
'redshift',
|
|
19
|
+
's3',
|
|
20
|
+
'sfn',
|
|
21
|
+
'sns',
|
|
22
|
+
'sqs',
|
|
23
|
+
'states',
|
|
24
|
+
'stepfunctions',
|
|
25
|
+
'bedrockruntime',
|
|
26
|
+
])
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {object} ChannelBag
|
|
30
|
+
* @property {ReturnType<typeof channel>} start
|
|
31
|
+
* @property {ReturnType<typeof channel>} complete
|
|
32
|
+
* @property {ReturnType<typeof channel>} region
|
|
33
|
+
* @property {ReturnType<typeof channel>} responseStart
|
|
34
|
+
* @property {ReturnType<typeof channel>} responseFinish
|
|
35
|
+
* @property {ReturnType<typeof channel>} deserialize
|
|
36
|
+
* @property {ReturnType<typeof channel>} streamedChunk
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/** @type {Map<string, ChannelBag>} */
|
|
40
|
+
const channelBags = new Map()
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Returns the cached set of diagnostic-channel handles for a given AWS
|
|
44
|
+
* service slug. Each `channel(...)` call hashes the channel name into a
|
|
45
|
+
* shared registry and allocates a per-call template-literal string; doing
|
|
46
|
+
* that ~8 times per AWS send was a measurable per-request cost.
|
|
47
|
+
*
|
|
48
|
+
* @param {string} suffix
|
|
49
|
+
* @returns {ChannelBag}
|
|
50
|
+
*/
|
|
51
|
+
function getChannelBag (suffix) {
|
|
52
|
+
let bag = channelBags.get(suffix)
|
|
53
|
+
if (bag === undefined) {
|
|
54
|
+
bag = {
|
|
55
|
+
start: channel(`apm:aws:request:start:${suffix}`),
|
|
56
|
+
complete: channel(`apm:aws:request:complete:${suffix}`),
|
|
57
|
+
region: channel(`apm:aws:request:region:${suffix}`),
|
|
58
|
+
responseStart: channel(`apm:aws:response:start:${suffix}`),
|
|
59
|
+
responseFinish: channel(`apm:aws:response:finish:${suffix}`),
|
|
60
|
+
deserialize: channel(`apm:aws:response:deserialize:${suffix}`),
|
|
61
|
+
streamedChunk: channel(`apm:aws:response:streamed-chunk:${suffix}`),
|
|
62
|
+
}
|
|
63
|
+
channelBags.set(suffix, bag)
|
|
64
|
+
}
|
|
65
|
+
return bag
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** @type {WeakMap<Function, string>} */
|
|
69
|
+
const clientNameCache = new WeakMap()
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {Function} clientCtor
|
|
73
|
+
* @returns {string}
|
|
74
|
+
*/
|
|
75
|
+
function getClientName (clientCtor) {
|
|
76
|
+
let name = clientNameCache.get(clientCtor)
|
|
77
|
+
if (name === undefined) {
|
|
78
|
+
name = clientCtor.name.replace(/Client$/, '')
|
|
79
|
+
clientNameCache.set(clientCtor, name)
|
|
80
|
+
}
|
|
81
|
+
return name
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** @type {WeakMap<Function, string>} */
|
|
85
|
+
const operationCache = new WeakMap()
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {Function} commandCtor
|
|
89
|
+
* @returns {string}
|
|
90
|
+
*/
|
|
91
|
+
function getOperationName (commandCtor) {
|
|
92
|
+
let operation = operationCache.get(commandCtor)
|
|
93
|
+
if (operation === undefined) {
|
|
94
|
+
const commandName = commandCtor.name
|
|
95
|
+
operation = `${commandName[0].toLowerCase()}${commandName.slice(1).replace(/Command$/, '')}`
|
|
96
|
+
operationCache.set(commandCtor, operation)
|
|
97
|
+
}
|
|
98
|
+
return operation
|
|
99
|
+
}
|
|
7
100
|
|
|
8
101
|
function wrapRequest (send) {
|
|
102
|
+
// V8 deopts both this function and `send.apply(this, arguments)` once
|
|
103
|
+
// `arguments[0] = wrapCb(...)` materialises the arguments object on the
|
|
104
|
+
// hot path. Pass the (at most one-arg) call site through explicitly --
|
|
105
|
+
// `Request.send` only accepts an optional callback in both v2 and v3 SDKs.
|
|
9
106
|
return function wrappedRequest (cb) {
|
|
10
107
|
if (!this.service) return send.apply(this, arguments)
|
|
11
108
|
|
|
12
109
|
const serviceIdentifier = this.service.serviceIdentifier
|
|
13
110
|
const channelSuffix = getChannelSuffix(serviceIdentifier)
|
|
14
|
-
const
|
|
15
|
-
if (!
|
|
111
|
+
const channels = getChannelBag(channelSuffix)
|
|
112
|
+
if (!channels.start.hasSubscribers) return send.apply(this, arguments)
|
|
16
113
|
|
|
114
|
+
const cbExists = typeof cb === 'function'
|
|
17
115
|
const ctx = {
|
|
18
116
|
serviceIdentifier,
|
|
19
117
|
operation: this.operation,
|
|
20
118
|
awsRegion: this.service.config && this.service.config.region,
|
|
21
119
|
awsService: this.service.api && this.service.api.className,
|
|
22
120
|
request: this,
|
|
23
|
-
cbExists
|
|
121
|
+
cbExists,
|
|
24
122
|
}
|
|
25
123
|
|
|
124
|
+
// AWS SDK v2 mixes in its own `SequentialExecutor` (no `once`), so stick
|
|
125
|
+
// to `on('complete')`. The event fires exactly once per Request — even
|
|
126
|
+
// across retries — so we don't get duplicate publishes.
|
|
26
127
|
this.on('complete', response => {
|
|
27
128
|
ctx.response = response
|
|
28
|
-
|
|
129
|
+
channels.complete.publish(ctx)
|
|
29
130
|
})
|
|
30
131
|
|
|
31
|
-
if (
|
|
32
|
-
|
|
132
|
+
if (cbExists) {
|
|
133
|
+
return channels.start.runStores(ctx, send, this, wrapCb(cb, channels, ctx))
|
|
33
134
|
}
|
|
34
|
-
|
|
35
|
-
return startCh.runStores(ctx, send, this, ...arguments)
|
|
135
|
+
return channels.start.runStores(ctx, send, this)
|
|
36
136
|
}
|
|
37
137
|
}
|
|
38
138
|
|
|
39
|
-
function wrapDeserialize (deserialize,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return function () {
|
|
43
|
-
const response = arguments[responseIndex]
|
|
139
|
+
function wrapDeserialize (deserialize, headersCh, responseIndex = 0) {
|
|
140
|
+
return function (...args) {
|
|
141
|
+
const response = args[responseIndex]
|
|
44
142
|
if (headersCh.hasSubscribers) {
|
|
45
143
|
headersCh.publish({ headers: response.headers })
|
|
46
144
|
}
|
|
47
145
|
|
|
48
|
-
return deserialize.apply(this,
|
|
146
|
+
return deserialize.apply(this, args)
|
|
49
147
|
}
|
|
50
148
|
}
|
|
51
149
|
|
|
@@ -54,26 +152,32 @@ function wrapSmithySend (send) {
|
|
|
54
152
|
const cb = args.at(-1)
|
|
55
153
|
const serviceIdentifier = this.config.serviceId.toLowerCase()
|
|
56
154
|
const channelSuffix = getChannelSuffix(serviceIdentifier)
|
|
57
|
-
const
|
|
58
|
-
const clientName = this.constructor
|
|
59
|
-
const operation =
|
|
155
|
+
const channels = getChannelBag(channelSuffix)
|
|
156
|
+
const clientName = getClientName(this.constructor)
|
|
157
|
+
const operation = getOperationName(command.constructor)
|
|
60
158
|
const request = {
|
|
61
159
|
operation,
|
|
62
160
|
params: command.input,
|
|
63
161
|
}
|
|
64
162
|
|
|
65
|
-
const startCh = channel(`apm:aws:request:start:${channelSuffix}`)
|
|
66
|
-
const regionCh = channel(`apm:aws:request:region:${channelSuffix}`)
|
|
67
|
-
const responseStartChannel = channel(`apm:aws:response:start:${channelSuffix}`)
|
|
68
|
-
const responseFinishChannel = channel(`apm:aws:response:finish:${channelSuffix}`)
|
|
69
|
-
|
|
70
163
|
if (typeof command.deserialize === 'function') {
|
|
71
|
-
|
|
164
|
+
const proto = Object.getPrototypeOf(command)
|
|
165
|
+
// Wrap once per Command class via the prototype when `deserialize` is
|
|
166
|
+
// inherited; fall back to per-instance wrap when a command shadows it
|
|
167
|
+
// as an own property (rare in @aws-sdk v3).
|
|
168
|
+
if (proto && proto.deserialize === command.deserialize) {
|
|
169
|
+
if (!patchedCommandPrototypes.has(proto)) {
|
|
170
|
+
shimmer.wrap(proto, 'deserialize', deserialize => wrapDeserialize(deserialize, channels.deserialize))
|
|
171
|
+
patchedCommandPrototypes.add(proto)
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
shimmer.wrap(command, 'deserialize', deserialize => wrapDeserialize(deserialize, channels.deserialize))
|
|
175
|
+
}
|
|
72
176
|
} else if (this.config?.protocol?.deserializeResponse && !patchedClientConfigProtocols.has(this.config.protocol)) {
|
|
73
177
|
shimmer.wrap(
|
|
74
178
|
this.config.protocol,
|
|
75
179
|
'deserializeResponse',
|
|
76
|
-
deserializeResponse => wrapDeserialize(deserializeResponse,
|
|
180
|
+
deserializeResponse => wrapDeserialize(deserializeResponse, channels.deserialize, 2)
|
|
77
181
|
)
|
|
78
182
|
|
|
79
183
|
patchedClientConfigProtocols.add(this.config.protocol)
|
|
@@ -86,25 +190,25 @@ function wrapSmithySend (send) {
|
|
|
86
190
|
request,
|
|
87
191
|
}
|
|
88
192
|
|
|
89
|
-
return
|
|
193
|
+
return channels.start.runStores(ctx, () => {
|
|
90
194
|
// When the region is not set this never resolves so we can't await.
|
|
91
195
|
this.config.region().then(region => {
|
|
92
196
|
ctx.region = region
|
|
93
|
-
|
|
197
|
+
channels.region.publish(ctx)
|
|
94
198
|
})
|
|
95
199
|
|
|
96
200
|
if (typeof cb === 'function') {
|
|
97
201
|
args[args.length - 1] = shimmer.wrapFunction(cb, cb => function (err, result) {
|
|
98
202
|
addResponse(ctx, err, result)
|
|
99
203
|
|
|
100
|
-
handleCompletion(result, ctx,
|
|
204
|
+
handleCompletion(result, ctx, channels)
|
|
101
205
|
|
|
102
206
|
const responseCtx = { request, response: ctx.response }
|
|
103
207
|
|
|
104
|
-
|
|
208
|
+
channels.responseStart.runStores(responseCtx, () => {
|
|
105
209
|
cb.apply(this, arguments)
|
|
106
210
|
|
|
107
|
-
|
|
211
|
+
channels.responseFinish.publish(responseCtx)
|
|
108
212
|
})
|
|
109
213
|
})
|
|
110
214
|
} else { // always a promise
|
|
@@ -112,12 +216,12 @@ function wrapSmithySend (send) {
|
|
|
112
216
|
.then(
|
|
113
217
|
result => {
|
|
114
218
|
addResponse(ctx, null, result)
|
|
115
|
-
handleCompletion(result, ctx,
|
|
219
|
+
handleCompletion(result, ctx, channels)
|
|
116
220
|
return result
|
|
117
221
|
},
|
|
118
222
|
error => {
|
|
119
223
|
addResponse(ctx, error)
|
|
120
|
-
handleCompletion(null, ctx,
|
|
224
|
+
handleCompletion(null, ctx, channels)
|
|
121
225
|
throw error
|
|
122
226
|
}
|
|
123
227
|
)
|
|
@@ -128,35 +232,32 @@ function wrapSmithySend (send) {
|
|
|
128
232
|
}
|
|
129
233
|
}
|
|
130
234
|
|
|
131
|
-
function handleCompletion (result, ctx,
|
|
132
|
-
const completeChannel = channel(`apm:aws:request:complete:${channelSuffix}`)
|
|
133
|
-
const streamedChunkChannel = channel(`apm:aws:response:streamed-chunk:${channelSuffix}`)
|
|
134
|
-
|
|
235
|
+
function handleCompletion (result, ctx, channels) {
|
|
135
236
|
const iterator = result?.body?.[Symbol.asyncIterator]
|
|
136
237
|
if (!iterator) {
|
|
137
|
-
|
|
238
|
+
channels.complete.publish(ctx)
|
|
138
239
|
return
|
|
139
240
|
}
|
|
140
241
|
|
|
141
242
|
shimmer.wrap(result.body, Symbol.asyncIterator, function (asyncIterator) {
|
|
142
|
-
return function () {
|
|
143
|
-
const iterator = asyncIterator.apply(this,
|
|
243
|
+
return function (...args) {
|
|
244
|
+
const iterator = asyncIterator.apply(this, args)
|
|
144
245
|
shimmer.wrap(iterator, 'next', function (next) {
|
|
145
|
-
return function () {
|
|
146
|
-
return next.apply(this,
|
|
246
|
+
return function (...args) {
|
|
247
|
+
return next.apply(this, args)
|
|
147
248
|
.then(result => {
|
|
148
249
|
const { done, value: chunk } = result
|
|
149
|
-
|
|
250
|
+
channels.streamedChunk.publish({ ctx, chunk, done })
|
|
150
251
|
|
|
151
252
|
if (done) {
|
|
152
|
-
|
|
253
|
+
channels.complete.publish(ctx)
|
|
153
254
|
}
|
|
154
255
|
|
|
155
256
|
return result
|
|
156
257
|
})
|
|
157
258
|
.catch(err => {
|
|
158
259
|
addResponse(ctx, err)
|
|
159
|
-
|
|
260
|
+
channels.complete.publish(ctx)
|
|
160
261
|
throw err
|
|
161
262
|
})
|
|
162
263
|
}
|
|
@@ -167,30 +268,29 @@ function handleCompletion (result, ctx, channelSuffix) {
|
|
|
167
268
|
})
|
|
168
269
|
}
|
|
169
270
|
|
|
170
|
-
function wrapCb (cb,
|
|
271
|
+
function wrapCb (cb, channels, ctx) {
|
|
171
272
|
// eslint-disable-next-line n/handle-callback-err
|
|
172
273
|
return shimmer.wrapFunction(cb, cb => function wrappedCb (err, response) {
|
|
173
274
|
ctx = { request: ctx.request, response }
|
|
174
|
-
return
|
|
175
|
-
const finishChannel = channel(`apm:aws:response:finish:${serviceName}`)
|
|
275
|
+
return channels.responseStart.runStores(ctx, () => {
|
|
176
276
|
try {
|
|
177
277
|
let result = cb.apply(this, arguments)
|
|
178
278
|
if (result && result.then) {
|
|
179
279
|
result = result.then(x => {
|
|
180
|
-
|
|
280
|
+
channels.responseFinish.publish(ctx)
|
|
181
281
|
return x
|
|
182
282
|
}, e => {
|
|
183
283
|
ctx.error = e
|
|
184
|
-
|
|
284
|
+
channels.responseFinish.publish(ctx)
|
|
185
285
|
throw e
|
|
186
286
|
})
|
|
187
287
|
} else {
|
|
188
|
-
|
|
288
|
+
channels.responseFinish.publish(ctx)
|
|
189
289
|
}
|
|
190
290
|
return result
|
|
191
291
|
} catch (e) {
|
|
192
292
|
ctx.error = e
|
|
193
|
-
|
|
293
|
+
channels.responseFinish.publish(ctx)
|
|
194
294
|
throw e
|
|
195
295
|
}
|
|
196
296
|
})
|
|
@@ -211,23 +311,7 @@ function addResponse (ctx, error, result) {
|
|
|
211
311
|
function getChannelSuffix (name) {
|
|
212
312
|
// some resource identifiers have spaces between ex: bedrock runtime
|
|
213
313
|
name = String(name).replaceAll(' ', '')
|
|
214
|
-
return
|
|
215
|
-
'cloudwatchlogs',
|
|
216
|
-
'dynamodb',
|
|
217
|
-
'eventbridge',
|
|
218
|
-
'kinesis',
|
|
219
|
-
'lambda',
|
|
220
|
-
'redshift',
|
|
221
|
-
's3',
|
|
222
|
-
'sfn',
|
|
223
|
-
'sns',
|
|
224
|
-
'sqs',
|
|
225
|
-
'states',
|
|
226
|
-
'stepfunctions',
|
|
227
|
-
'bedrockruntime',
|
|
228
|
-
].includes(name)
|
|
229
|
-
? name
|
|
230
|
-
: 'default'
|
|
314
|
+
return KNOWN_CHANNEL_SUFFIXES.has(name) ? name : 'default'
|
|
231
315
|
}
|
|
232
316
|
|
|
233
317
|
addHook({ name: '@smithy/smithy-client', versions: ['>=1.0.3'] }, smithy => {
|
|
@@ -38,14 +38,14 @@ function entityWrapper (method) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function entityHandler (handler, entityName) {
|
|
41
|
-
return function () {
|
|
42
|
-
if (!azureDurableFunctionsChannel.hasSubscribers) return handler.apply(this,
|
|
41
|
+
return function (...args) {
|
|
42
|
+
if (!azureDurableFunctionsChannel.hasSubscribers) return handler.apply(this, args)
|
|
43
43
|
|
|
44
|
-
const entityContext =
|
|
44
|
+
const entityContext = args[0]
|
|
45
45
|
return azureDurableFunctionsChannel.traceSync(
|
|
46
46
|
handler,
|
|
47
47
|
{ trigger: 'Entity', functionName: entityName, operationName: entityContext?.df?.operationName },
|
|
48
|
-
this, ...
|
|
48
|
+
this, ...args)
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -55,19 +55,19 @@ function activityHandler (method) {
|
|
|
55
55
|
const isAsync =
|
|
56
56
|
handler && handler.constructor && handler.constructor.name === 'AsyncFunction'
|
|
57
57
|
|
|
58
|
-
return function () {
|
|
59
|
-
if (!azureDurableFunctionsChannel.hasSubscribers) return handler.apply(this,
|
|
58
|
+
return function (...args) {
|
|
59
|
+
if (!azureDurableFunctionsChannel.hasSubscribers) return handler.apply(this, args)
|
|
60
60
|
|
|
61
61
|
// use tracePromise if this is an async handler. otherwise, use traceSync
|
|
62
62
|
return isAsync
|
|
63
63
|
? azureDurableFunctionsChannel.tracePromise(
|
|
64
64
|
handler,
|
|
65
65
|
{ trigger: 'Activity', functionName: activityName },
|
|
66
|
-
this, ...
|
|
66
|
+
this, ...args)
|
|
67
67
|
: azureDurableFunctionsChannel.traceSync(
|
|
68
68
|
handler,
|
|
69
69
|
{ trigger: 'Activity', functionName: activityName },
|
|
70
|
-
this, ...
|
|
70
|
+
this, ...args)
|
|
71
71
|
}
|
|
72
72
|
})
|
|
73
73
|
return method.apply(this, arguments)
|
|
@@ -6,8 +6,8 @@ const { wrapThen } = require('./helpers/promise')
|
|
|
6
6
|
|
|
7
7
|
function createGetNewLibraryCopyWrap (originalLib) {
|
|
8
8
|
return function wrapGetNewLibraryCopy (getNewLibraryCopy) {
|
|
9
|
-
return function getNewLibraryCopyWithTrace () {
|
|
10
|
-
const libraryCopy = getNewLibraryCopy.apply(this,
|
|
9
|
+
return function getNewLibraryCopyWithTrace (...args) {
|
|
10
|
+
const libraryCopy = getNewLibraryCopy.apply(this, args)
|
|
11
11
|
shimmer.wrap(libraryCopy.prototype, '_then', wrapThen)
|
|
12
12
|
shimmer.wrap(libraryCopy, 'getNewLibraryCopy', createGetNewLibraryCopyWrap(originalLib))
|
|
13
13
|
return libraryCopy
|
|
@@ -6,7 +6,7 @@ const { channel, addHook, AsyncResource } = require('./helpers/instrument')
|
|
|
6
6
|
const bodyParserReadCh = channel('datadog:body-parser:read:finish')
|
|
7
7
|
|
|
8
8
|
function publishRequestBodyAndNext (req, res, next) {
|
|
9
|
-
return shimmer.wrapFunction(next, next => function () {
|
|
9
|
+
return shimmer.wrapFunction(next, next => function (...args) {
|
|
10
10
|
if (bodyParserReadCh.hasSubscribers && req) {
|
|
11
11
|
const abortController = new AbortController()
|
|
12
12
|
const body = req.body
|
|
@@ -16,7 +16,7 @@ function publishRequestBodyAndNext (req, res, next) {
|
|
|
16
16
|
if (abortController.signal.aborted) return
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
return next.apply(this,
|
|
19
|
+
return next.apply(this, args)
|
|
20
20
|
})
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -100,13 +100,13 @@ addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'], patchDefault: false }
|
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
addHook({ name: 'cassandra-driver', versions: ['>=3.3'], file: 'lib/request-execution.js' }, RequestExecution => {
|
|
103
|
-
shimmer.wrap(RequestExecution.prototype, '_sendOnConnection', _sendOnConnection => function () {
|
|
103
|
+
shimmer.wrap(RequestExecution.prototype, '_sendOnConnection', _sendOnConnection => function (...args) {
|
|
104
104
|
if (!startCh.hasSubscribers) {
|
|
105
|
-
return _sendOnConnection.apply(this,
|
|
105
|
+
return _sendOnConnection.apply(this, args)
|
|
106
106
|
}
|
|
107
107
|
startCtx = { hostname: this._connection.address, port: this._connection.port, ...startCtx }
|
|
108
108
|
connectCh.publish(startCtx)
|
|
109
|
-
return _sendOnConnection.apply(this,
|
|
109
|
+
return _sendOnConnection.apply(this, args)
|
|
110
110
|
})
|
|
111
111
|
return RequestExecution
|
|
112
112
|
})
|
|
@@ -122,9 +122,9 @@ addHook({ name: 'cassandra-driver', versions: ['3.3 - 4.3'], file: 'lib/request-
|
|
|
122
122
|
return start.apply(this, arguments)
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
arguments[0] = function () {
|
|
125
|
+
arguments[0] = function (...args) {
|
|
126
126
|
startCtx = { hostname: execution._connection.address, port: execution._connection.port, ...startCtx }
|
|
127
|
-
return connectCh.runStores(startCtx, getHostCallback, this, ...
|
|
127
|
+
return connectCh.runStores(startCtx, getHostCallback, this, ...args)
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
return start.apply(this, arguments)
|
|
@@ -143,9 +143,9 @@ addHook({ name: 'cassandra-driver', versions: ['3 - 3.2'], file: 'lib/request-ha
|
|
|
143
143
|
return send.apply(this, arguments)
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
arguments[2] = function () {
|
|
146
|
+
arguments[2] = function (...args) {
|
|
147
147
|
startCtx = { hostname: handler.connection.address, port: handler.connection.port, ...startCtx }
|
|
148
|
-
return connectCh.runStores(startCtx, callback, this, ...
|
|
148
|
+
return connectCh.runStores(startCtx, callback, this, ...args)
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
return send.apply(this, arguments)
|
|
@@ -82,12 +82,12 @@ function createContextFromChildProcessInfo (childProcessInfo) {
|
|
|
82
82
|
|
|
83
83
|
function wrapChildProcessSyncMethod (returnError, shell = false) {
|
|
84
84
|
return function wrapMethod (childProcessMethod) {
|
|
85
|
-
return function () {
|
|
86
|
-
if (!childProcessChannel.start.hasSubscribers ||
|
|
87
|
-
return childProcessMethod.apply(this,
|
|
85
|
+
return function (...args) {
|
|
86
|
+
if (!childProcessChannel.start.hasSubscribers || args.length === 0) {
|
|
87
|
+
return childProcessMethod.apply(this, args)
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
const callArgs = [...
|
|
90
|
+
const callArgs = [...args]
|
|
91
91
|
const childProcessInfo = normalizeArgs(callArgs, shell)
|
|
92
92
|
const context = createContextFromChildProcessInfo(childProcessInfo)
|
|
93
93
|
context.callArgs = callArgs
|
|
@@ -118,12 +118,12 @@ function wrapChildProcessSyncMethod (returnError, shell = false) {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
function wrapChildProcessCustomPromisifyMethod (customPromisifyMethod, shell) {
|
|
121
|
-
return function () {
|
|
122
|
-
if (!childProcessChannel.start.hasSubscribers ||
|
|
123
|
-
return customPromisifyMethod.apply(this,
|
|
121
|
+
return function (...args) {
|
|
122
|
+
if (!childProcessChannel.start.hasSubscribers || args.length === 0) {
|
|
123
|
+
return customPromisifyMethod.apply(this, args)
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
const callArgs = [...
|
|
126
|
+
const callArgs = [...args]
|
|
127
127
|
const childProcessInfo = normalizeArgs(callArgs, shell)
|
|
128
128
|
|
|
129
129
|
const context = createContextFromChildProcessInfo(childProcessInfo)
|
|
@@ -170,12 +170,12 @@ function wrapChildProcessCustomPromisifyMethod (customPromisifyMethod, shell) {
|
|
|
170
170
|
|
|
171
171
|
function wrapChildProcessAsyncMethod (ChildProcess, shell = false) {
|
|
172
172
|
return function wrapMethod (childProcessMethod) {
|
|
173
|
-
function wrappedChildProcessMethod () {
|
|
174
|
-
if (!childProcessChannel.start.hasSubscribers ||
|
|
175
|
-
return childProcessMethod.apply(this,
|
|
173
|
+
function wrappedChildProcessMethod (...args) {
|
|
174
|
+
if (!childProcessChannel.start.hasSubscribers || args.length === 0) {
|
|
175
|
+
return childProcessMethod.apply(this, args)
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
const callArgs = [...
|
|
178
|
+
const callArgs = [...args]
|
|
179
179
|
const childProcessInfo = normalizeArgs(callArgs, shell)
|
|
180
180
|
|
|
181
181
|
const context = createContextFromChildProcessInfo(childProcessInfo)
|
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
addHook,
|
|
8
8
|
channel,
|
|
9
9
|
} = require('./helpers/instrument')
|
|
10
|
+
const { cloneMessages } = require('./helpers/kafka')
|
|
10
11
|
|
|
11
12
|
// Create channels for Confluent Kafka JavaScript
|
|
12
13
|
const channels = {
|
|
@@ -47,8 +48,8 @@ function instrumentBaseModule (module) {
|
|
|
47
48
|
// Helper function to wrap producer classes
|
|
48
49
|
function wrapProducerClass (ProducerClass, className) {
|
|
49
50
|
return shimmer.wrap(module, className, function wrapProducer (Original) {
|
|
50
|
-
return function wrappedProducer () {
|
|
51
|
-
const producer = new Original(...
|
|
51
|
+
return function wrappedProducer (...args) {
|
|
52
|
+
const producer = new Original(...args)
|
|
52
53
|
|
|
53
54
|
// Hook the produce method
|
|
54
55
|
if (typeof producer?.produce === 'function') {
|
|
@@ -94,9 +95,9 @@ function instrumentBaseModule (module) {
|
|
|
94
95
|
// Helper function to wrap consumer classes
|
|
95
96
|
function wrapConsumerClass (ConsumerClass, className) {
|
|
96
97
|
return shimmer.wrap(module, className, function wrapConsumer (Original) {
|
|
97
|
-
return function wrappedConsumer () {
|
|
98
|
-
const consumer = new Original(...
|
|
99
|
-
const groupId = this.groupId || (
|
|
98
|
+
return function wrappedConsumer (...args) {
|
|
99
|
+
const consumer = new Original(...args)
|
|
100
|
+
const groupId = this.groupId || (args[0]?.['group.id'])
|
|
100
101
|
|
|
101
102
|
// Wrap the consume method
|
|
102
103
|
if (typeof consumer?.consume === 'function') {
|
|
@@ -196,11 +197,11 @@ function instrumentKafkaJS (kafkaJS) {
|
|
|
196
197
|
// Wrap the producer method if it exists
|
|
197
198
|
if (typeof kafka?.producer === 'function') {
|
|
198
199
|
shimmer.wrap(kafka, 'producer', function wrapProducerMethod (producerMethod) {
|
|
199
|
-
return function wrappedProducerMethod () {
|
|
200
|
-
const producer = producerMethod.apply(this,
|
|
200
|
+
return function wrappedProducerMethod (...args) {
|
|
201
|
+
const producer = producerMethod.apply(this, args)
|
|
201
202
|
|
|
202
|
-
if (!brokers &&
|
|
203
|
-
kafka._ddBrokers =
|
|
203
|
+
if (!brokers && args?.[0]?.['bootstrap.servers']) {
|
|
204
|
+
kafka._ddBrokers = args[0]['bootstrap.servers']
|
|
204
205
|
}
|
|
205
206
|
|
|
206
207
|
// Wrap the send method of the producer
|
|
@@ -211,46 +212,62 @@ function instrumentKafkaJS (kafkaJS) {
|
|
|
211
212
|
return send.apply(this, arguments)
|
|
212
213
|
}
|
|
213
214
|
|
|
215
|
+
const disableHeaderInjection = disabledHeaderWeakSet.has(producer)
|
|
216
|
+
|
|
217
|
+
// Hand the underlying client a shallow clone so neither
|
|
218
|
+
// injection nor the client's auto-fields (it sets
|
|
219
|
+
// `headers: null` on messages without headers) ever
|
|
220
|
+
// touch caller-owned objects. With injection disabled the
|
|
221
|
+
// clone must not seed `headers: {}` either: brokers that
|
|
222
|
+
// reject any header field cannot recover otherwise.
|
|
223
|
+
let outgoingPayload = payload
|
|
224
|
+
if (payload && Array.isArray(payload.messages)) {
|
|
225
|
+
outgoingPayload = {
|
|
226
|
+
...payload,
|
|
227
|
+
messages: cloneMessages(payload.messages, !disableHeaderInjection),
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
214
231
|
const ctx = {
|
|
215
|
-
topic:
|
|
216
|
-
messages:
|
|
232
|
+
topic: outgoingPayload?.topic,
|
|
233
|
+
messages: outgoingPayload?.messages || [],
|
|
217
234
|
bootstrapServers: kafka._ddBrokers,
|
|
218
|
-
disableHeaderInjection
|
|
235
|
+
disableHeaderInjection,
|
|
219
236
|
}
|
|
220
237
|
|
|
221
238
|
return channels.producerStart.runStores(ctx, () => {
|
|
222
239
|
try {
|
|
223
|
-
const result = send.
|
|
240
|
+
const result = send.call(this, outgoingPayload)
|
|
224
241
|
|
|
225
242
|
result.then((res) => {
|
|
226
243
|
ctx.result = res
|
|
227
244
|
channels.producerCommit.publish(ctx)
|
|
228
245
|
channels.producerFinish.publish(ctx)
|
|
229
|
-
}, (
|
|
230
|
-
if (
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
if (
|
|
246
|
+
}, (error) => {
|
|
247
|
+
if (error) {
|
|
248
|
+
// KafkaJS-compat reports `ERR_UNKNOWN` for brokers
|
|
249
|
+
// <0.11 that cannot parse headers. Stop injecting
|
|
250
|
+
// for this producer; subsequent sends to the same
|
|
251
|
+
// broker succeed.
|
|
252
|
+
if (error.name === 'KafkaJSError' && error.type === 'ERR_UNKNOWN') {
|
|
236
253
|
disabledHeaderWeakSet.add(producer)
|
|
237
254
|
log.error(
|
|
238
255
|
// eslint-disable-next-line @stylistic/max-len
|
|
239
256
|
'Kafka Broker responded with UNKNOWN_SERVER_ERROR (-1). Please look at broker logs for more information. Tracer message header injection for Kafka is disabled.'
|
|
240
257
|
)
|
|
241
258
|
}
|
|
242
|
-
ctx.error =
|
|
259
|
+
ctx.error = error
|
|
243
260
|
channels.producerError.publish(ctx)
|
|
244
261
|
}
|
|
245
262
|
channels.producerFinish.publish(ctx)
|
|
246
263
|
})
|
|
247
264
|
|
|
248
265
|
return result
|
|
249
|
-
} catch (
|
|
250
|
-
ctx.error =
|
|
266
|
+
} catch (error) {
|
|
267
|
+
ctx.error = error
|
|
251
268
|
channels.producerError.publish(ctx)
|
|
252
269
|
channels.producerFinish.publish(ctx)
|
|
253
|
-
throw
|
|
270
|
+
throw error
|
|
254
271
|
}
|
|
255
272
|
})
|
|
256
273
|
}
|