dd-trace 5.72.0 → 5.73.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 +2 -0
- package/index.d.ts +21 -0
- package/package.json +8 -6
- package/packages/datadog-esbuild/index.js +8 -0
- package/packages/datadog-instrumentations/src/azure-service-bus.js +49 -22
- package/packages/datadog-instrumentations/src/cookie-parser.js +2 -0
- package/packages/datadog-instrumentations/src/jest.js +59 -14
- package/packages/datadog-instrumentations/src/mocha/utils.js +3 -4
- package/packages/datadog-plugin-amqplib/src/consumer.js +1 -1
- package/packages/datadog-plugin-azure-functions/src/index.js +24 -14
- package/packages/datadog-plugin-azure-service-bus/src/index.js +1 -1
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +60 -12
- package/packages/datadog-plugin-jest/src/index.js +53 -18
- package/packages/datadog-plugin-ws/src/close.js +1 -1
- package/packages/datadog-plugin-ws/src/producer.js +1 -1
- package/packages/datadog-plugin-ws/src/receiver.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +9 -1
- package/packages/dd-trace/src/appsec/reporter.js +2 -3
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +5 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +8 -3
- package/packages/dd-trace/src/llmobs/plugins/base.js +11 -12
- package/packages/dd-trace/src/llmobs/sdk.js +20 -4
- package/packages/dd-trace/src/llmobs/tagger.js +12 -0
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +7 -127
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +19 -134
- package/packages/dd-trace/src/opentelemetry/otlp/metrics.proto +720 -0
- package/packages/dd-trace/src/opentelemetry/otlp/metrics_service.proto +78 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +177 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +163 -0
- package/packages/dd-trace/src/opentelemetry/{protos → otlp}/protobuf_loader.js +24 -6
- package/packages/dd-trace/src/supported-configurations.json +1 -0
- /package/packages/dd-trace/src/opentelemetry/{protos → otlp}/common.proto +0 -0
- /package/packages/dd-trace/src/opentelemetry/{protos → otlp}/logs.proto +0 -0
- /package/packages/dd-trace/src/opentelemetry/{protos → otlp}/logs_service.proto +0 -0
- /package/packages/dd-trace/src/opentelemetry/{protos → otlp}/resource.proto +0 -0
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -64,6 +64,8 @@ dev,globals,MIT,Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://si
|
|
|
64
64
|
dev,graphql,MIT,Copyright 2015 Facebook Inc.
|
|
65
65
|
dev,jszip,MIT,Copyright 2015-2016 Stuart Knightley and contributors
|
|
66
66
|
dev,mocha,MIT,Copyright 2011-2018 JS Foundation and contributors https://js.foundation
|
|
67
|
+
dev,mocha-multi-reporters,MIT,Copyright 2015-2019 Yousaf Nabi and Stanley Ng
|
|
68
|
+
dev,mocha-junit-reporter,MIT, Copyright 2015 Michael Allen
|
|
67
69
|
dev,multer,MIT,Copyright 2014 Hage Yaapa
|
|
68
70
|
dev,nock,MIT,Copyright 2017 Pedro Teixeira and other contributors
|
|
69
71
|
dev,nyc,ISC,Copyright 2015 Contributors
|
package/index.d.ts
CHANGED
|
@@ -2938,6 +2938,15 @@ declare namespace tracer {
|
|
|
2938
2938
|
*/
|
|
2939
2939
|
submitEvaluation (spanContext: llmobs.ExportedLLMObsSpan, options: llmobs.EvaluationOptions): void
|
|
2940
2940
|
|
|
2941
|
+
|
|
2942
|
+
/**
|
|
2943
|
+
* Annotates all spans, including auto-instrumented spans, with the provided tags created in the context of the callback function.
|
|
2944
|
+
* @param options The annotation context options.
|
|
2945
|
+
* @param fn The callback over which to apply the annotation context options.
|
|
2946
|
+
* @returns The result of the function.
|
|
2947
|
+
*/
|
|
2948
|
+
annotationContext<T> (options: llmobs.AnnotationContextOptions, fn: () => T): T
|
|
2949
|
+
|
|
2941
2950
|
/**
|
|
2942
2951
|
* Flushes any remaining spans and evaluation metrics to LLM Observability.
|
|
2943
2952
|
*/
|
|
@@ -3099,6 +3108,18 @@ declare namespace tracer {
|
|
|
3099
3108
|
tags?: { [key: string]: any }
|
|
3100
3109
|
}
|
|
3101
3110
|
|
|
3111
|
+
interface AnnotationContextOptions {
|
|
3112
|
+
/**
|
|
3113
|
+
* Dictionary of JSON serializable key-value tag pairs to set or update on the LLMObs span regarding the span's context.
|
|
3114
|
+
*/
|
|
3115
|
+
tags?: { [key: string]: any },
|
|
3116
|
+
|
|
3117
|
+
/**
|
|
3118
|
+
* Set to override the span name for any spans annotated within the returned context.
|
|
3119
|
+
*/
|
|
3120
|
+
name?: string,
|
|
3121
|
+
}
|
|
3122
|
+
|
|
3102
3123
|
/**
|
|
3103
3124
|
* An object containing the span ID and trace ID of interest
|
|
3104
3125
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.73.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"test:llmobs:sdk:ci": "nyc --no-clean --include \"packages/dd-trace/src/llmobs/**/*.js\" -- npm run test:llmobs:sdk",
|
|
45
45
|
"test:llmobs:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/llmobs/plugins/@($(echo $PLUGINS))/*.spec.js\"",
|
|
46
46
|
"test:llmobs:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/src/llmobs/**/*.js\" -- npm run test:llmobs:plugins",
|
|
47
|
-
"test:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test
|
|
47
|
+
"test:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/**/@($(echo ${SPEC:-'*'})).spec.js\"",
|
|
48
48
|
"test:plugins:ci": "yarn services && nyc --no-clean --include \"packages/datadog-plugin-@($(echo $PLUGINS))/src/**/*.js\" -- npm run test:plugins",
|
|
49
49
|
"test:plugins:ci:flaky": "yarn services && nyc --no-clean --include \"packages/datadog-plugin-@($(echo $PLUGINS))/src/**/*.js\" -- npm run test:plugins -- --bail --retries 2",
|
|
50
50
|
"test:plugins:upstream": "node ./packages/dd-trace/test/plugins/suite.js",
|
|
@@ -120,10 +120,10 @@
|
|
|
120
120
|
],
|
|
121
121
|
"dependencies": {
|
|
122
122
|
"@datadog/libdatadog": "0.7.0",
|
|
123
|
-
"@datadog/native-appsec": "10.
|
|
123
|
+
"@datadog/native-appsec": "10.3.0",
|
|
124
124
|
"@datadog/native-iast-taint-tracking": "4.0.0",
|
|
125
125
|
"@datadog/native-metrics": "3.1.1",
|
|
126
|
-
"@datadog/openfeature-node-server": "0.1.0-preview.
|
|
126
|
+
"@datadog/openfeature-node-server": "0.1.0-preview.12",
|
|
127
127
|
"@datadog/pprof": "5.11.1",
|
|
128
128
|
"@datadog/sketches-js": "2.1.1",
|
|
129
129
|
"@datadog/wasm-js-rewriter": "4.0.1",
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
},
|
|
159
159
|
"peerDependencies": {
|
|
160
160
|
"@openfeature/core": "^1.9.0",
|
|
161
|
-
"@openfeature/server-sdk": "~1.
|
|
161
|
+
"@openfeature/server-sdk": "~1.19.0"
|
|
162
162
|
},
|
|
163
163
|
"peerDependenciesMeta": {
|
|
164
164
|
"@openfeature/core": {
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
"@eslint/js": "^9.29.0",
|
|
175
175
|
"@msgpack/msgpack": "^3.1.2",
|
|
176
176
|
"@openfeature/core": "^1.8.1",
|
|
177
|
-
"@openfeature/server-sdk": "~1.
|
|
177
|
+
"@openfeature/server-sdk": "~1.19.0",
|
|
178
178
|
"@stylistic/eslint-plugin": "^5.0.0",
|
|
179
179
|
"@types/chai": "^4.3.16",
|
|
180
180
|
"@types/mocha": "^10.0.10",
|
|
@@ -198,6 +198,8 @@
|
|
|
198
198
|
"graphql": "*",
|
|
199
199
|
"jszip": "^3.10.1",
|
|
200
200
|
"mocha": "^11.6.0",
|
|
201
|
+
"mocha-junit-reporter": "^2.2.1",
|
|
202
|
+
"mocha-multi-reporters": "^1.5.1",
|
|
201
203
|
"multer": "^2.0.2",
|
|
202
204
|
"nock": "^13.5.6",
|
|
203
205
|
"nyc": "^15.1.0",
|
|
@@ -115,6 +115,14 @@ module.exports.setup = function (build) {
|
|
|
115
115
|
${isSourceMapEnabled ? `globalThis.__DD_ESBUILD_BASEPATH = '${require('../dd-trace/src/util').ddBasePath}';` : ''}
|
|
116
116
|
${build.initialOptions.banner.js}`
|
|
117
117
|
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
require.resolve('@openfeature/core')
|
|
121
|
+
} catch (error) {
|
|
122
|
+
build.initialOptions.external ??= []
|
|
123
|
+
build.initialOptions.external.push('@openfeature/core')
|
|
124
|
+
}
|
|
125
|
+
|
|
118
126
|
if (isESMBuild(build)) {
|
|
119
127
|
if (!build.initialOptions.banner.js.includes('import { createRequire as $dd_createRequire } from \'module\'')) {
|
|
120
128
|
build.initialOptions.banner.js = `import { createRequire as $dd_createRequire } from 'module';
|
|
@@ -1,38 +1,65 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
|
-
channel,
|
|
5
4
|
addHook
|
|
6
5
|
} = require('./helpers/instrument')
|
|
7
6
|
|
|
8
7
|
const shimmer = require('../../datadog-shimmer')
|
|
8
|
+
const dc = require('dc-polyfill')
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
const producerErrorCh = channel('apm:azure-service-bus:send:error')
|
|
12
|
-
const producerFinishCh = channel('apm:azure-service-bus:send:finish')
|
|
10
|
+
const producerCh = dc.tracingChannel('apm:azure-service-bus:send')
|
|
13
11
|
|
|
14
12
|
addHook({ name: '@azure/service-bus', versions: ['>=7.9.2'], patchDefault: false }, (obj) => {
|
|
15
13
|
const ServiceBusClient = obj.ServiceBusClient
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
let didItShim = false
|
|
15
|
+
shimmer.wrap(ServiceBusClient.prototype, 'createSender',
|
|
16
|
+
createSender => function (queueOrTopicName) {
|
|
17
|
+
const sender = createSender.apply(this, arguments)
|
|
18
|
+
if (didItShim) return sender
|
|
19
|
+
const senderPrototype = sender.constructor.prototype
|
|
20
|
+
const senderSenderPrototype = sender._sender.constructor.prototype
|
|
21
|
+
shimmer.wrap(senderPrototype, 'scheduleMessages', scheduleMessages =>
|
|
22
|
+
function (msg, scheduledEnqueueTimeUtc) {
|
|
23
|
+
const functionName = scheduleMessages.name
|
|
24
|
+
const config = this._context.config
|
|
25
|
+
const entityPath = this._entityPath
|
|
26
|
+
return producerCh.tracePromise(
|
|
27
|
+
scheduleMessages,
|
|
28
|
+
{ config, entityPath, functionName, msg, scheduledEnqueueTimeUtc },
|
|
29
|
+
this, ...arguments
|
|
32
30
|
)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
shimmer.wrap(senderPrototype, 'createMessageBatch', createMessageBatch => async function () {
|
|
34
|
+
const batch = await createMessageBatch.apply(this, arguments)
|
|
35
|
+
shimmer.wrap(batch.constructor.prototype, 'tryAddMessage', tryAddMessage => function (msg) {
|
|
36
|
+
const functionName = tryAddMessage.name
|
|
37
|
+
const config = this._context.config
|
|
38
|
+
return producerCh.tracePromise(
|
|
39
|
+
tryAddMessage, { config, functionName, batch, msg }, this, ...arguments)
|
|
40
|
+
})
|
|
41
|
+
return batch
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
shimmer.wrap(senderSenderPrototype, 'send', send => function (msg) {
|
|
45
|
+
const functionName = send.name
|
|
46
|
+
const config = this._context.config
|
|
47
|
+
const entityPath = this.entityPath
|
|
48
|
+
return producerCh.tracePromise(
|
|
49
|
+
send, { config, entityPath, functionName, msg }, this, ...arguments
|
|
50
|
+
)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
shimmer.wrap(senderSenderPrototype, 'sendBatch', sendBatch => function (msg) {
|
|
54
|
+
const functionName = sendBatch.name
|
|
55
|
+
const config = this._context.config
|
|
56
|
+
const entityPath = this.entityPath
|
|
57
|
+
return producerCh.tracePromise(
|
|
58
|
+
sendBatch, { config, entityPath, functionName, msg }, this, ...arguments
|
|
59
|
+
)
|
|
33
60
|
})
|
|
61
|
+
didItShim = true
|
|
62
|
+
return sender
|
|
34
63
|
})
|
|
35
|
-
return sender
|
|
36
|
-
})
|
|
37
64
|
return obj
|
|
38
65
|
})
|
|
@@ -25,6 +25,8 @@ addHook({
|
|
|
25
25
|
name: 'cookie-parser',
|
|
26
26
|
versions: ['>=1.0.0']
|
|
27
27
|
}, cookieParser => {
|
|
28
|
+
// This prevents the non default export from entering the wrapping process
|
|
29
|
+
if (cookieParser.default) return cookieParser
|
|
28
30
|
return shimmer.wrapFunction(cookieParser, cookieParser => function () {
|
|
29
31
|
const cookieMiddleware = cookieParser.apply(this, arguments)
|
|
30
32
|
|
|
@@ -29,6 +29,7 @@ const testSessionConfigurationCh = channel('ci:jest:session:configuration')
|
|
|
29
29
|
|
|
30
30
|
const testSuiteStartCh = channel('ci:jest:test-suite:start')
|
|
31
31
|
const testSuiteFinishCh = channel('ci:jest:test-suite:finish')
|
|
32
|
+
const testSuiteErrorCh = channel('ci:jest:test-suite:error')
|
|
32
33
|
|
|
33
34
|
const workerReportTraceCh = channel('ci:jest:worker-report:trace')
|
|
34
35
|
const workerReportCoverageCh = channel('ci:jest:worker-report:coverage')
|
|
@@ -397,7 +398,8 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
397
398
|
isJestRetry,
|
|
398
399
|
isDisabled,
|
|
399
400
|
isQuarantined,
|
|
400
|
-
isModified
|
|
401
|
+
isModified,
|
|
402
|
+
testSuiteAbsolutePath: this.testSuiteAbsolutePath
|
|
401
403
|
}
|
|
402
404
|
testContexts.set(event.test, ctx)
|
|
403
405
|
|
|
@@ -809,11 +811,15 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
809
811
|
|
|
810
812
|
try {
|
|
811
813
|
const { err, testManagementTests: receivedTestManagementTests } = await testManagementTestsPromise
|
|
812
|
-
if (
|
|
814
|
+
if (err) {
|
|
815
|
+
isTestManagementTestsEnabled = false
|
|
816
|
+
testManagementTests = {}
|
|
817
|
+
} else {
|
|
813
818
|
testManagementTests = receivedTestManagementTests
|
|
814
819
|
}
|
|
815
820
|
} catch (err) {
|
|
816
821
|
log.error('Jest test management tests error', err)
|
|
822
|
+
isTestManagementTestsEnabled = false
|
|
817
823
|
}
|
|
818
824
|
}
|
|
819
825
|
|
|
@@ -1092,7 +1098,8 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
1092
1098
|
testEnvironmentOptions: environment.testEnvironmentOptions,
|
|
1093
1099
|
testSourceFile: environment.testSourceFile,
|
|
1094
1100
|
displayName: environment.displayName,
|
|
1095
|
-
frameworkVersion: jestVersion
|
|
1101
|
+
frameworkVersion: jestVersion,
|
|
1102
|
+
testSuiteAbsolutePath: environment.testSuiteAbsolutePath
|
|
1096
1103
|
})
|
|
1097
1104
|
return adapter.apply(this, arguments).then(suiteResults => {
|
|
1098
1105
|
const { numFailingTests, skipped, failureMessage: errorMessage } = suiteResults
|
|
@@ -1116,12 +1123,17 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
1116
1123
|
const coverageFiles = getFilesWithPath(getCoveredFilenamesFromCoverage(environment.global.__coverage__))
|
|
1117
1124
|
const mockedFiles = getFilesWithPath(testSuiteMockedFiles.get(environment.testSuiteAbsolutePath) || [])
|
|
1118
1125
|
|
|
1119
|
-
testSuiteCodeCoverageCh.publish({
|
|
1126
|
+
testSuiteCodeCoverageCh.publish({
|
|
1127
|
+
coverageFiles,
|
|
1128
|
+
testSuite: environment.testSourceFile,
|
|
1129
|
+
mockedFiles,
|
|
1130
|
+
testSuiteAbsolutePath: environment.testSuiteAbsolutePath
|
|
1131
|
+
})
|
|
1120
1132
|
}
|
|
1121
|
-
testSuiteFinishCh.publish({ status, errorMessage })
|
|
1133
|
+
testSuiteFinishCh.publish({ status, errorMessage, testSuiteAbsolutePath: environment.testSuiteAbsolutePath })
|
|
1122
1134
|
return suiteResults
|
|
1123
1135
|
}).catch(error => {
|
|
1124
|
-
testSuiteFinishCh.publish({ status: 'fail', error })
|
|
1136
|
+
testSuiteFinishCh.publish({ status: 'fail', error, testSuiteAbsolutePath: environment.testSuiteAbsolutePath })
|
|
1125
1137
|
throw error
|
|
1126
1138
|
})
|
|
1127
1139
|
})
|
|
@@ -1301,16 +1313,49 @@ addHook({
|
|
|
1301
1313
|
})
|
|
1302
1314
|
|
|
1303
1315
|
shimmer.wrap(Runtime.prototype, 'requireModuleOrMock', requireModuleOrMock => function (from, moduleName) {
|
|
1304
|
-
//
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1316
|
+
// `requireModuleOrMock` may log errors to the console. If we don't remove ourselves
|
|
1317
|
+
// from the stack trace, the user might see a useless stack trace rather than the error
|
|
1318
|
+
// that `jest` tries to show.
|
|
1319
|
+
const originalPrepareStackTrace = Error.prepareStackTrace
|
|
1320
|
+
Error.prepareStackTrace = function (error, structuredStackTrace) {
|
|
1321
|
+
const filteredStackTrace = structuredStackTrace
|
|
1322
|
+
.filter(callSite => !callSite.getFileName()?.includes('datadog-instrumentations/src/jest.js'))
|
|
1323
|
+
|
|
1324
|
+
return originalPrepareStackTrace(error, filteredStackTrace)
|
|
1308
1325
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1326
|
+
try {
|
|
1327
|
+
// TODO: do this for every library that we instrument
|
|
1328
|
+
if (LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.has(moduleName)) {
|
|
1329
|
+
// To bypass jest's own require engine
|
|
1330
|
+
return this._requireCoreModule(moduleName)
|
|
1331
|
+
}
|
|
1332
|
+
// This means that `@fast-check/jest` is used in the test file.
|
|
1333
|
+
if (moduleName === '@fast-check/jest') {
|
|
1334
|
+
testSuiteAbsolutePathsWithFastCheck.add(this._testPath)
|
|
1335
|
+
}
|
|
1336
|
+
const returnedValue = requireModuleOrMock.apply(this, arguments)
|
|
1337
|
+
if (process.exitCode === 1) {
|
|
1338
|
+
if (this.loggedReferenceErrors.size > 0) {
|
|
1339
|
+
const errorMessage = [...this.loggedReferenceErrors][0]
|
|
1340
|
+
testSuiteErrorCh.publish({
|
|
1341
|
+
errorMessage,
|
|
1342
|
+
testSuiteAbsolutePath: this._testPath
|
|
1343
|
+
})
|
|
1344
|
+
} else {
|
|
1345
|
+
testSuiteErrorCh.publish({
|
|
1346
|
+
errorMessage: 'An error occurred while importing a module',
|
|
1347
|
+
testSuiteAbsolutePath: this._testPath
|
|
1348
|
+
})
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
return returnedValue
|
|
1352
|
+
} catch (error) {
|
|
1353
|
+
testSuiteErrorCh.publish({ error, testSuiteAbsolutePath: this._testPath })
|
|
1354
|
+
throw error
|
|
1355
|
+
} finally {
|
|
1356
|
+
// Restore original prepareStackTrace
|
|
1357
|
+
Error.prepareStackTrace = originalPrepareStackTrace
|
|
1312
1358
|
}
|
|
1313
|
-
return requireModuleOrMock.apply(this, arguments)
|
|
1314
1359
|
})
|
|
1315
1360
|
|
|
1316
1361
|
return runtimePackage
|
|
@@ -163,14 +163,13 @@ function runnableWrapper (RunnablePackage, libraryConfig) {
|
|
|
163
163
|
const ctx = getTestContext(test)
|
|
164
164
|
|
|
165
165
|
if (ctx) {
|
|
166
|
-
const originalFn = this.fn
|
|
167
166
|
// we bind the test fn to the correct context
|
|
168
|
-
const newFn = function () {
|
|
167
|
+
const newFn = shimmer.wrapFunction(this.fn, originalFn => function () {
|
|
169
168
|
return testFnCh.runStores(ctx, () => originalFn.apply(this, arguments))
|
|
170
|
-
}
|
|
169
|
+
})
|
|
171
170
|
|
|
172
171
|
// we store the original function, not to lose it
|
|
173
|
-
originalFns.set(newFn,
|
|
172
|
+
originalFns.set(newFn, this.fn)
|
|
174
173
|
this.fn = newFn
|
|
175
174
|
|
|
176
175
|
wrappedFunctions.add(this.fn)
|
|
@@ -10,7 +10,7 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
|
10
10
|
static operation = 'consume'
|
|
11
11
|
|
|
12
12
|
bindStart (ctx) {
|
|
13
|
-
const { method, fields, message, queue } = ctx
|
|
13
|
+
const { method, fields = {}, message, queue } = ctx
|
|
14
14
|
|
|
15
15
|
if (method !== 'basic.deliver' && method !== 'basic.get') return
|
|
16
16
|
|
|
@@ -24,10 +24,10 @@ class AzureFunctionsPlugin extends TracingPlugin {
|
|
|
24
24
|
static prefix = 'tracing:datadog:azure:functions:invoke'
|
|
25
25
|
|
|
26
26
|
bindStart (ctx) {
|
|
27
|
-
const childOf = extractTraceContext(this._tracer, ctx)
|
|
28
27
|
const meta = getMetaForTrigger(ctx)
|
|
29
28
|
const triggerType = triggerMap[ctx.methodName]
|
|
30
29
|
const isMessagingService = (triggerType === 'ServiceBus' || triggerType === 'EventHubs')
|
|
30
|
+
const childOf = isMessagingService ? null : extractTraceContext(this._tracer, ctx)
|
|
31
31
|
const span = this.startSpan(this.operationName(), {
|
|
32
32
|
childOf,
|
|
33
33
|
service: this.serviceName(),
|
|
@@ -36,7 +36,7 @@ class AzureFunctionsPlugin extends TracingPlugin {
|
|
|
36
36
|
}, ctx)
|
|
37
37
|
|
|
38
38
|
if (isMessagingService) {
|
|
39
|
-
setSpanLinks(this.tracer, span, ctx)
|
|
39
|
+
setSpanLinks(triggerType, this.tracer, span, ctx)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
ctx.span = span
|
|
@@ -116,29 +116,39 @@ function extractTraceContext (tracer, ctx) {
|
|
|
116
116
|
switch (String(triggerMap[ctx.methodName])) {
|
|
117
117
|
case 'Http':
|
|
118
118
|
return tracer.extract('http_headers', Object.fromEntries(ctx.httpRequest.headers))
|
|
119
|
-
case 'ServiceBus':
|
|
120
|
-
return tracer.extract('text_map', ctx.invocationContext.triggerMetadata.applicationProperties)
|
|
121
119
|
default:
|
|
122
120
|
null
|
|
123
121
|
}
|
|
124
122
|
}
|
|
125
123
|
|
|
126
|
-
|
|
124
|
+
// message & messages & batch with cardinality of 1 == applicationProperties
|
|
125
|
+
// messages with cardinality of many == applicationPropertiesArray
|
|
126
|
+
function setSpanLinks (triggerType, tracer, span, ctx) {
|
|
127
127
|
const cardinality = ctx.invocationContext.options.trigger.cardinality
|
|
128
128
|
const triggerMetadata = ctx.invocationContext.triggerMetadata
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
129
|
+
const isServiceBus = triggerType === 'ServiceBus'
|
|
130
|
+
|
|
131
|
+
const properties = isServiceBus
|
|
132
|
+
? triggerMetadata.applicationProperties
|
|
133
|
+
: triggerMetadata.properties
|
|
134
|
+
|
|
135
|
+
const propertiesArray = isServiceBus
|
|
136
|
+
? triggerMetadata.applicationPropertiesArray
|
|
137
|
+
: triggerMetadata.propertiesArray
|
|
138
|
+
|
|
139
|
+
const addLinkFromProperties = (props) => {
|
|
140
|
+
if (!props || Object.keys(props).length === 0) return
|
|
141
|
+
const spanContext = tracer.extract('text_map', props)
|
|
138
142
|
if (spanContext) {
|
|
139
143
|
span.addLink(spanContext)
|
|
140
144
|
}
|
|
141
145
|
}
|
|
146
|
+
|
|
147
|
+
if (cardinality === 'many' && propertiesArray?.length > 0) {
|
|
148
|
+
propertiesArray.forEach(addLinkFromProperties)
|
|
149
|
+
} else if (cardinality === 'one') {
|
|
150
|
+
addLinkFromProperties(properties)
|
|
151
|
+
}
|
|
142
152
|
}
|
|
143
153
|
|
|
144
154
|
module.exports = AzureFunctionsPlugin
|
|
@@ -4,7 +4,7 @@ const ProducerPlugin = require('./producer')
|
|
|
4
4
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
5
5
|
|
|
6
6
|
class AzureServiceBusPlugin extends CompositePlugin {
|
|
7
|
-
static id
|
|
7
|
+
static get id () { return 'azure-service-bus' }
|
|
8
8
|
static get plugins () {
|
|
9
9
|
return {
|
|
10
10
|
producer: ProducerPlugin
|
|
@@ -1,36 +1,84 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
3
4
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
4
5
|
|
|
5
6
|
class AzureServiceBusProducerPlugin extends ProducerPlugin {
|
|
6
|
-
static id
|
|
7
|
-
static operation
|
|
7
|
+
static get id () { return 'azure-service-bus' }
|
|
8
|
+
static get operation () { return 'send' }
|
|
9
|
+
static get prefix () { return 'tracing:apm:azure-service-bus:send' }
|
|
8
10
|
|
|
9
11
|
bindStart (ctx) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
// we do not want to make these spans when batch linking is disabled.
|
|
13
|
+
if (!batchLinksAreEnabled() && ctx.functionName === 'tryAddMessage') {
|
|
14
|
+
return ctx.currentStore
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const qualifiedSenderNamespace = ctx.config.host
|
|
12
18
|
const span = this.startSpan({
|
|
13
|
-
resource:
|
|
19
|
+
resource: ctx.entityPath,
|
|
14
20
|
type: 'messaging',
|
|
15
21
|
meta: {
|
|
16
22
|
component: 'azure-service-bus',
|
|
17
|
-
'messaging.destination.name':
|
|
23
|
+
'messaging.destination.name': ctx.entityPath,
|
|
18
24
|
'messaging.operation': 'send',
|
|
19
25
|
'messaging.system': 'servicebus',
|
|
20
26
|
'network.destination.name': qualifiedSenderNamespace,
|
|
21
27
|
}
|
|
22
28
|
}, ctx)
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
msg.applicationProperties = {}
|
|
28
|
-
}
|
|
30
|
+
if (ctx.functionName === 'tryAddMessage') {
|
|
31
|
+
span._spanContext._name = 'azure.servicebus.create'
|
|
32
|
+
span.setTag('messaging.operation', 'create')
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
if (ctx.msg.messageID !== undefined) {
|
|
35
|
+
span.setTag('message.id', ctx.msg)
|
|
36
|
+
}
|
|
31
37
|
|
|
38
|
+
if (batchLinksAreEnabled()) {
|
|
39
|
+
ctx.batch._spanContexts.push(span.context())
|
|
40
|
+
injectTraceContext(this.tracer, span, ctx.msg)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (ctx.functionName === 'send' || ctx.functionName === 'sendBatch' || ctx.functionName === 'scheduleMessages') {
|
|
45
|
+
const messages = ctx.msg
|
|
46
|
+
const isBatch = messages.constructor?.name === 'ServiceBusMessageBatchImpl'
|
|
47
|
+
if (isBatch) {
|
|
48
|
+
span.setTag('messaging.batch.message_count', messages.count)
|
|
49
|
+
if (batchLinksAreEnabled()) {
|
|
50
|
+
messages._spanContexts.forEach(spanContext => {
|
|
51
|
+
span.addLink(spanContext)
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
} else if (Array.isArray(messages)) {
|
|
55
|
+
span.setTag('messaging.batch.message_count', messages.length)
|
|
56
|
+
messages.forEach(event => {
|
|
57
|
+
injectTraceContext(this.tracer, span, event)
|
|
58
|
+
})
|
|
59
|
+
} else {
|
|
60
|
+
injectTraceContext(this.tracer, span, messages)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
32
63
|
return ctx.currentStore
|
|
33
64
|
}
|
|
65
|
+
|
|
66
|
+
asyncEnd (ctx) {
|
|
67
|
+
super.finish()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function injectTraceContext (tracer, span, msg) {
|
|
72
|
+
if (!msg.applicationProperties) {
|
|
73
|
+
msg.applicationProperties = {}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
tracer.inject(span, 'text_map', msg.applicationProperties)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function batchLinksAreEnabled () {
|
|
80
|
+
const sb = getEnvironmentVariable('DD_TRACE_AZURE_SERVICEBUS_BATCH_LINKS_ENABLED')
|
|
81
|
+
return sb !== 'false'
|
|
34
82
|
}
|
|
35
83
|
|
|
36
84
|
module.exports = AzureServiceBusProducerPlugin
|