dd-trace 5.79.0 → 5.80.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 -0
- package/index.d.ts +11 -4
- package/initialize.mjs +10 -10
- package/package.json +2 -1
- package/packages/datadog-core/src/storage.js +4 -4
- package/packages/datadog-esbuild/src/utils.js +5 -1
- package/packages/datadog-instrumentations/src/aws-sdk.js +9 -2
- package/packages/datadog-instrumentations/src/azure-service-bus.js +43 -36
- package/packages/datadog-instrumentations/src/helpers/hook.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -1
- package/packages/datadog-instrumentations/src/jest.js +1 -1
- package/packages/datadog-instrumentations/src/playwright.js +20 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +3 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +14 -5
- package/packages/datadog-plugin-jest/src/util.js +3 -2
- package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -1
- package/packages/datadog-plugin-openai/src/stream-helpers.js +1 -1
- package/packages/datadog-shimmer/src/shimmer.js +2 -2
- package/packages/dd-trace/src/aiguard/sdk.js +12 -5
- package/packages/dd-trace/src/baggage.js +11 -0
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +1 -1
- package/packages/dd-trace/src/config_defaults.js +1 -0
- package/packages/dd-trace/src/encode/0.4.js +3 -3
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +2 -2
- package/packages/dd-trace/src/exporters/agent/writer.js +6 -13
- package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -2
- package/packages/dd-trace/src/llmobs/index.js +5 -5
- package/packages/dd-trace/src/llmobs/noop.js +6 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +1 -0
- package/packages/dd-trace/src/llmobs/plugins/openai.js +41 -35
- package/packages/dd-trace/src/llmobs/sdk.js +5 -1
- package/packages/dd-trace/src/llmobs/span_processor.js +5 -5
- package/packages/dd-trace/src/llmobs/tagger.js +31 -17
- package/packages/dd-trace/src/msgpack/chunk.js +2 -2
- package/packages/dd-trace/src/msgpack/encoder.js +2 -3
- package/packages/dd-trace/src/msgpack/index.js +2 -2
- package/packages/dd-trace/src/openfeature/flagging_provider.js +5 -3
- package/packages/dd-trace/src/opentelemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +11 -6
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +1 -9
- package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +1 -1
- package/packages/dd-trace/src/plugins/database.js +1 -0
- package/packages/dd-trace/src/plugins/plugin.js +7 -9
- package/packages/dd-trace/src/profiling/exporter_cli.js +7 -6
- package/packages/dd-trace/src/require-package-json.js +1 -1
- package/packages/dd-trace/src/service-naming/index.js +31 -4
- package/packages/dd-trace/src/span_processor.js +9 -9
- /package/packages/dd-trace/src/{format.js → span_format.js} +0 -0
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -56,6 +56,7 @@ dev,chai,MIT,Copyright 2017 Chai.js Assertion Library
|
|
|
56
56
|
dev,eslint,MIT,Copyright JS Foundation and other contributors https://js.foundation
|
|
57
57
|
dev,eslint-plugin-cypress,MIT,Copyright (c) 2019 Cypress.io
|
|
58
58
|
dev,eslint-plugin-import,MIT,Copyright 2015 Ben Mosher
|
|
59
|
+
dev,eslint-plugin-jsdoc,BSD-3-Clause,Copyright Gajus Kuizinas
|
|
59
60
|
dev,eslint-plugin-mocha,MIT,Copyright 2014 Mathias Schreck
|
|
60
61
|
dev,eslint-plugin-n,MIT,Copyright 2015 Toru Nagashima
|
|
61
62
|
dev,eslint-plugin-promise,ISC,jden and other contributors
|
package/index.d.ts
CHANGED
|
@@ -654,6 +654,13 @@ declare namespace tracer {
|
|
|
654
654
|
* @default false
|
|
655
655
|
*/
|
|
656
656
|
enabled?: boolean
|
|
657
|
+
/**
|
|
658
|
+
* Timeout in milliseconds for OpenFeature provider initialization.
|
|
659
|
+
* If configuration is not received within this time, initialization fails.
|
|
660
|
+
*
|
|
661
|
+
* @default 30000
|
|
662
|
+
*/
|
|
663
|
+
initializationTimeoutMs?: number
|
|
657
664
|
}
|
|
658
665
|
};
|
|
659
666
|
|
|
@@ -3011,15 +3018,15 @@ declare namespace tracer {
|
|
|
3011
3018
|
label: string,
|
|
3012
3019
|
|
|
3013
3020
|
/**
|
|
3014
|
-
* The type of evaluation metric, one of 'categorical' or '
|
|
3021
|
+
* The type of evaluation metric, one of 'categorical', 'score', or 'boolean'
|
|
3015
3022
|
*/
|
|
3016
|
-
metricType: 'categorical' | 'score',
|
|
3023
|
+
metricType: 'categorical' | 'score' | 'boolean',
|
|
3017
3024
|
|
|
3018
3025
|
/**
|
|
3019
3026
|
* The value of the evaluation metric.
|
|
3020
|
-
* Must be string for 'categorical' metrics
|
|
3027
|
+
* Must be string for 'categorical' metrics, number for 'score' metrics, and boolean for 'boolean' metrics.
|
|
3021
3028
|
*/
|
|
3022
|
-
value: string | number,
|
|
3029
|
+
value: string | number | boolean,
|
|
3023
3030
|
|
|
3024
3031
|
/**
|
|
3025
3032
|
* An object of string key-value pairs to tag the evaluation metric with.
|
package/initialize.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
* This file serves one of two purposes, depending on how it's used.
|
|
3
|
+
*
|
|
4
|
+
* If used with --import, it will import init.js and register the loader hook.
|
|
5
|
+
* If used with --loader, it will act as the loader hook, except that it will
|
|
6
|
+
* also import init.js inside the source code of the entrypoint file.
|
|
7
|
+
*
|
|
8
|
+
* The result is that no matter how this file is used, so long as it's with
|
|
9
|
+
* one of the two flags, the tracer will always be initialized, and the loader
|
|
10
|
+
* hook will always be active for ESM support.
|
|
11
|
+
*/
|
|
12
12
|
|
|
13
13
|
/* eslint n/no-unsupported-features/node-builtins: ['error', { ignores: ['module.register'] }] */
|
|
14
14
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.80.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -182,6 +182,7 @@
|
|
|
182
182
|
"eslint": "^9.39.0",
|
|
183
183
|
"eslint-plugin-cypress": "^5.2.0",
|
|
184
184
|
"eslint-plugin-import": "^2.32.0",
|
|
185
|
+
"eslint-plugin-jsdoc": "^61.1.12",
|
|
185
186
|
"eslint-plugin-mocha": "^11.2.0",
|
|
186
187
|
"eslint-plugin-n": "^17.23.1",
|
|
187
188
|
"eslint-plugin-promise": "^7.2.1",
|
|
@@ -15,7 +15,7 @@ const { AsyncLocalStorage } = require('async_hooks')
|
|
|
15
15
|
class DatadogStorage extends AsyncLocalStorage {
|
|
16
16
|
/**
|
|
17
17
|
*
|
|
18
|
-
* @param
|
|
18
|
+
* @param {Store} [store]
|
|
19
19
|
* @override
|
|
20
20
|
*/
|
|
21
21
|
enterWith (store) {
|
|
@@ -47,7 +47,7 @@ class DatadogStorage extends AsyncLocalStorage {
|
|
|
47
47
|
* retrieved through `getHandle()` can also be passed in to be used as the
|
|
48
48
|
* key. This is useful if you've stashed a handle somewhere and want to
|
|
49
49
|
* retrieve the store with it.
|
|
50
|
-
* @param {
|
|
50
|
+
* @param {object} [handle]
|
|
51
51
|
* @returns {Store | undefined}
|
|
52
52
|
* @override
|
|
53
53
|
*/
|
|
@@ -87,7 +87,7 @@ class DatadogStorage extends AsyncLocalStorage {
|
|
|
87
87
|
|
|
88
88
|
/**
|
|
89
89
|
* This is the map from handles to real stores, used in the class above.
|
|
90
|
-
* @type {WeakMap<WeakKey, Store>}
|
|
90
|
+
* @type {WeakMap<WeakKey, Store|undefined>}
|
|
91
91
|
*/
|
|
92
92
|
const stores = new WeakMap()
|
|
93
93
|
|
|
@@ -101,7 +101,7 @@ const storages = Object.create(null)
|
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
103
|
*
|
|
104
|
-
* @param
|
|
104
|
+
* @param {string} namespace The namespace to use
|
|
105
105
|
* @returns {DatadogStorage}
|
|
106
106
|
*/
|
|
107
107
|
function storage (namespace) {
|
|
@@ -65,7 +65,11 @@ function getSource (url, { format }) {
|
|
|
65
65
|
/**
|
|
66
66
|
* Generates the pieces of code for the proxy module before the path
|
|
67
67
|
*
|
|
68
|
-
* @param {
|
|
68
|
+
* @param {object} moduleData
|
|
69
|
+
* @param {string} moduleData.path
|
|
70
|
+
* @param {boolean} moduleData.internal
|
|
71
|
+
* @param {object} moduleData.context
|
|
72
|
+
* @param {boolean} moduleData.excludeDefault
|
|
69
73
|
* @returns {Promise<Map>}
|
|
70
74
|
*/
|
|
71
75
|
async function processModule ({ path, internal, context, excludeDefault }) {
|
|
@@ -34,10 +34,11 @@ function wrapRequest (send) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function wrapDeserialize (deserialize, channelSuffix) {
|
|
37
|
+
function wrapDeserialize (deserialize, channelSuffix, responseIndex = 0) {
|
|
38
38
|
const headersCh = channel(`apm:aws:response:deserialize:${channelSuffix}`)
|
|
39
39
|
|
|
40
|
-
return function (
|
|
40
|
+
return function () {
|
|
41
|
+
const response = arguments[responseIndex]
|
|
41
42
|
if (headersCh.hasSubscribers) {
|
|
42
43
|
headersCh.publish({ headers: response.headers })
|
|
43
44
|
}
|
|
@@ -66,6 +67,12 @@ function wrapSmithySend (send) {
|
|
|
66
67
|
|
|
67
68
|
if (typeof command.deserialize === 'function') {
|
|
68
69
|
shimmer.wrap(command, 'deserialize', deserialize => wrapDeserialize(deserialize, channelSuffix))
|
|
70
|
+
} else if (this.config?.protocol?.deserializeResponse) {
|
|
71
|
+
shimmer.wrap(
|
|
72
|
+
this.config.protocol,
|
|
73
|
+
'deserializeResponse',
|
|
74
|
+
deserializeResponse => wrapDeserialize(deserializeResponse, channelSuffix, 2)
|
|
75
|
+
)
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
const ctx = {
|
|
@@ -8,57 +8,64 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
8
8
|
const dc = require('dc-polyfill')
|
|
9
9
|
|
|
10
10
|
const producerCh = dc.tracingChannel('apm:azure-service-bus:send')
|
|
11
|
+
const isItDefault = new WeakSet()
|
|
11
12
|
|
|
12
|
-
addHook({ name: '@azure/service-bus', versions: ['>=7.9.2']
|
|
13
|
+
addHook({ name: '@azure/service-bus', versions: ['>=7.9.2'] }, (obj) => {
|
|
13
14
|
const ServiceBusClient = obj.ServiceBusClient
|
|
14
|
-
let didItShim = false
|
|
15
15
|
shimmer.wrap(ServiceBusClient.prototype, 'createSender',
|
|
16
16
|
createSender => function (queueOrTopicName) {
|
|
17
17
|
const sender = createSender.apply(this, arguments)
|
|
18
|
-
if (didItShim) return sender
|
|
19
18
|
const senderPrototype = sender.constructor.prototype
|
|
20
19
|
const senderSenderPrototype = sender._sender.constructor.prototype
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
|
|
21
|
+
if (!isItDefault.has(senderPrototype)) {
|
|
22
|
+
isItDefault.add(senderPrototype)
|
|
23
|
+
|
|
24
|
+
shimmer.wrap(senderPrototype, 'scheduleMessages', scheduleMessages =>
|
|
25
|
+
function (msg, scheduledEnqueueTimeUtc) {
|
|
26
|
+
const functionName = scheduleMessages.name
|
|
27
|
+
const config = this._context.config
|
|
28
|
+
const entityPath = this._entityPath
|
|
29
|
+
return producerCh.tracePromise(
|
|
30
|
+
scheduleMessages,
|
|
31
|
+
{ config, entityPath, functionName, msg, scheduledEnqueueTimeUtc },
|
|
32
|
+
this, ...arguments
|
|
33
|
+
)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
shimmer.wrap(senderPrototype, 'createMessageBatch', createMessageBatch => async function () {
|
|
37
|
+
const batch = await createMessageBatch.apply(this, arguments)
|
|
38
|
+
shimmer.wrap(batch, 'tryAddMessage', tryAddMessage => function (msg) {
|
|
39
|
+
const functionName = tryAddMessage.name
|
|
40
|
+
const config = this._context.config
|
|
41
|
+
return producerCh.tracePromise(
|
|
42
|
+
tryAddMessage, { config, functionName, batch, msg }, this, ...arguments)
|
|
43
|
+
})
|
|
44
|
+
return batch
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!isItDefault.has(senderSenderPrototype)) {
|
|
49
|
+
isItDefault.add(senderSenderPrototype)
|
|
50
|
+
|
|
51
|
+
shimmer.wrap(senderSenderPrototype, 'send', send => function (msg) {
|
|
52
|
+
const functionName = send.name
|
|
24
53
|
const config = this._context.config
|
|
25
|
-
const entityPath = this.
|
|
54
|
+
const entityPath = this.entityPath
|
|
26
55
|
return producerCh.tracePromise(
|
|
27
|
-
|
|
28
|
-
{ config, entityPath, functionName, msg, scheduledEnqueueTimeUtc },
|
|
29
|
-
this, ...arguments
|
|
56
|
+
send, { config, entityPath, functionName, msg }, this, ...arguments
|
|
30
57
|
)
|
|
31
58
|
})
|
|
32
59
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
shimmer.wrap(batch.constructor.prototype, 'tryAddMessage', tryAddMessage => function (msg) {
|
|
36
|
-
const functionName = tryAddMessage.name
|
|
60
|
+
shimmer.wrap(senderSenderPrototype, 'sendBatch', sendBatch => function (msg) {
|
|
61
|
+
const functionName = sendBatch.name
|
|
37
62
|
const config = this._context.config
|
|
63
|
+
const entityPath = this.entityPath
|
|
38
64
|
return producerCh.tracePromise(
|
|
39
|
-
|
|
65
|
+
sendBatch, { config, entityPath, functionName, msg }, this, ...arguments
|
|
66
|
+
)
|
|
40
67
|
})
|
|
41
|
-
|
|
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
|
-
)
|
|
60
|
-
})
|
|
61
|
-
didItShim = true
|
|
68
|
+
}
|
|
62
69
|
return sender
|
|
63
70
|
})
|
|
64
71
|
return obj
|
|
@@ -8,6 +8,7 @@ const ritm = require('../../../dd-trace/src/ritm')
|
|
|
8
8
|
* In practice, `modules` is always an array with a single entry.
|
|
9
9
|
*
|
|
10
10
|
* @param {string[]} modules list of modules to hook into
|
|
11
|
+
* @param {object} hookOptions hook options
|
|
11
12
|
* @param {Function} onrequire callback to be executed upon encountering module
|
|
12
13
|
*/
|
|
13
14
|
function Hook (modules, hookOptions, onrequire) {
|
|
@@ -28,7 +28,8 @@ exports.tracingChannel = function (name) {
|
|
|
28
28
|
* @param {string[]} args.versions array of semver range strings
|
|
29
29
|
* @param {string} [args.file='index.js'] path to file within package to instrument
|
|
30
30
|
* @param {string} [args.filePattern] pattern to match files within package to instrument
|
|
31
|
-
* @param
|
|
31
|
+
* @param {boolean} [args.patchDefault] whether to patch the default export
|
|
32
|
+
* @param {(moduleExports: unknown, version: string) => unknown} hook
|
|
32
33
|
*/
|
|
33
34
|
exports.addHook = function addHook ({ name, versions, file, filePattern, patchDefault }, hook) {
|
|
34
35
|
if (typeof name === 'string') {
|
|
@@ -1110,7 +1110,7 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
1110
1110
|
* Child processes do not each request ITR configuration, so the jest's parent process
|
|
1111
1111
|
* needs to pass them the configuration. This is done via _ddTestCodeCoverageEnabled, which
|
|
1112
1112
|
* controls whether coverage is reported.
|
|
1113
|
-
|
|
1113
|
+
*/
|
|
1114
1114
|
if (environment.testEnvironmentOptions?._ddTestCodeCoverageEnabled) {
|
|
1115
1115
|
const root = environment.repositoryRoot || environment.rootDir
|
|
1116
1116
|
|
|
@@ -481,6 +481,15 @@ function dispatcherRunWrapper (run) {
|
|
|
481
481
|
|
|
482
482
|
function dispatcherRunWrapperNew (run) {
|
|
483
483
|
return function (testGroups) {
|
|
484
|
+
// Filter out disabled tests from testGroups before they get scheduled
|
|
485
|
+
if (isTestManagementTestsEnabled) {
|
|
486
|
+
testGroups.forEach(group => {
|
|
487
|
+
group.tests = group.tests.filter(test => !test._ddIsDisabled)
|
|
488
|
+
})
|
|
489
|
+
// Remove empty groups
|
|
490
|
+
testGroups = testGroups.filter(group => group.tests.length > 0)
|
|
491
|
+
}
|
|
492
|
+
|
|
484
493
|
if (!this._allTests) {
|
|
485
494
|
// Removed in https://github.com/microsoft/playwright/commit/1e52c37b254a441cccf332520f60225a5acc14c7
|
|
486
495
|
// Not available from >=1.44.0
|
|
@@ -893,6 +902,9 @@ addHook({
|
|
|
893
902
|
if (testProperties.disabled) {
|
|
894
903
|
test._ddIsDisabled = true
|
|
895
904
|
test.expectedStatus = 'skipped'
|
|
905
|
+
// setting test.expectedStatus to 'skipped' does not work for every case,
|
|
906
|
+
// so we need to filter out disabled tests in dispatcherRunWrapperNew,
|
|
907
|
+
// so they don't get to the workers
|
|
896
908
|
continue
|
|
897
909
|
}
|
|
898
910
|
if (testProperties.quarantined) {
|
|
@@ -1270,6 +1282,10 @@ function generateSummaryWrapper (generateSummary) {
|
|
|
1270
1282
|
const {
|
|
1271
1283
|
_requireFile: testSuiteAbsolutePath,
|
|
1272
1284
|
location: { line: testSourceLine },
|
|
1285
|
+
_ddIsNew: isNew,
|
|
1286
|
+
_ddIsDisabled: isDisabled,
|
|
1287
|
+
_ddIsModified: isModified,
|
|
1288
|
+
_ddIsQuarantined: isQuarantined
|
|
1273
1289
|
} = test
|
|
1274
1290
|
const browserName = getBrowserNameFromProjects(sessionProjects, test)
|
|
1275
1291
|
|
|
@@ -1278,6 +1294,10 @@ function generateSummaryWrapper (generateSummary) {
|
|
|
1278
1294
|
testSuiteAbsolutePath,
|
|
1279
1295
|
testSourceLine,
|
|
1280
1296
|
browserName,
|
|
1297
|
+
isNew,
|
|
1298
|
+
isDisabled,
|
|
1299
|
+
isModified,
|
|
1300
|
+
isQuarantined
|
|
1281
1301
|
})
|
|
1282
1302
|
}
|
|
1283
1303
|
}
|
|
@@ -27,8 +27,9 @@ const PROVIDER = {
|
|
|
27
27
|
* Coerce the chunks into a single response body.
|
|
28
28
|
*
|
|
29
29
|
* @param {Array<{ chunk: { bytes: Buffer } }>} chunks
|
|
30
|
-
* @param {string}
|
|
31
|
-
* @
|
|
30
|
+
* @param {string} modelProvider
|
|
31
|
+
* @param {string} modelName
|
|
32
|
+
* @returns {Generation | Record<never, never>}
|
|
32
33
|
*/
|
|
33
34
|
function extractTextAndResponseReasonFromStream (chunks, modelProvider, modelName) {
|
|
34
35
|
const modelProviderUpper = modelProvider.toUpperCase()
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
4
4
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
5
|
+
const spanContexts = new WeakMap()
|
|
5
6
|
|
|
6
7
|
class AzureServiceBusProducerPlugin extends ProducerPlugin {
|
|
7
8
|
static get id () { return 'azure-service-bus' }
|
|
@@ -36,7 +37,12 @@ class AzureServiceBusProducerPlugin extends ProducerPlugin {
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
if (batchLinksAreEnabled()) {
|
|
39
|
-
ctx.batch
|
|
40
|
+
const spanContext = spanContexts.get(ctx.batch)
|
|
41
|
+
if (spanContext) {
|
|
42
|
+
spanContext.push(span.context())
|
|
43
|
+
} else {
|
|
44
|
+
spanContexts.set(ctx.batch, [span.context()])
|
|
45
|
+
}
|
|
40
46
|
injectTraceContext(this.tracer, span, ctx.msg)
|
|
41
47
|
}
|
|
42
48
|
}
|
|
@@ -47,9 +53,12 @@ class AzureServiceBusProducerPlugin extends ProducerPlugin {
|
|
|
47
53
|
if (isBatch) {
|
|
48
54
|
span.setTag('messaging.batch.message_count', messages.count)
|
|
49
55
|
if (batchLinksAreEnabled()) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
const contexts = spanContexts.get(messages)
|
|
57
|
+
if (contexts) {
|
|
58
|
+
for (const spanContext of contexts) {
|
|
59
|
+
span.addLink(spanContext)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
53
62
|
}
|
|
54
63
|
} else if (Array.isArray(messages)) {
|
|
55
64
|
span.setTag('messaging.batch.message_count', messages.length)
|
|
@@ -64,7 +73,7 @@ class AzureServiceBusProducerPlugin extends ProducerPlugin {
|
|
|
64
73
|
}
|
|
65
74
|
|
|
66
75
|
asyncEnd (ctx) {
|
|
67
|
-
super.finish()
|
|
76
|
+
super.finish(ctx)
|
|
68
77
|
}
|
|
69
78
|
}
|
|
70
79
|
|
|
@@ -62,6 +62,7 @@ function getJestTestName (test, shouldStripSeed = false) {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const globalDocblockRegExp = /^\s*(\/\*\*?(.|\r?\n)*?\*\/)/
|
|
65
|
+
const MAX_COMMENTS_CHECKED = 10
|
|
65
66
|
|
|
66
67
|
function isMarkedAsUnskippable (test) {
|
|
67
68
|
let testSource
|
|
@@ -86,7 +87,7 @@ function isMarkedAsUnskippable (test) {
|
|
|
86
87
|
docblocks = parse(comment)
|
|
87
88
|
} catch {
|
|
88
89
|
// Skip unparsable comment and continue scanning
|
|
89
|
-
if (commentsChecked++ >=
|
|
90
|
+
if (commentsChecked++ >= MAX_COMMENTS_CHECKED) {
|
|
90
91
|
return false
|
|
91
92
|
}
|
|
92
93
|
continue
|
|
@@ -103,7 +104,7 @@ function isMarkedAsUnskippable (test) {
|
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
if (commentsChecked++ >=
|
|
107
|
+
if (commentsChecked++ >= MAX_COMMENTS_CHECKED) {
|
|
107
108
|
return false
|
|
108
109
|
}
|
|
109
110
|
|
|
@@ -28,7 +28,8 @@ class KafkajsConsumerPlugin extends ConsumerPlugin {
|
|
|
28
28
|
* @property {string} topic
|
|
29
29
|
* @property {number} partition
|
|
30
30
|
* @property {number} offset
|
|
31
|
-
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
32
33
|
* @typedef {object} CommitEventItem
|
|
33
34
|
* @property {string} groupId
|
|
34
35
|
* @property {string} topic
|
|
@@ -25,6 +25,8 @@ class KafkajsProducerPlugin extends ProducerPlugin {
|
|
|
25
25
|
* @property {string} topic
|
|
26
26
|
* @property {number} partition
|
|
27
27
|
* @property {number} offset
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
28
30
|
*
|
|
29
31
|
* @typedef {object} ProducerResponseItem
|
|
30
32
|
* @property {string} topic
|
|
@@ -49,7 +51,7 @@ class KafkajsProducerPlugin extends ProducerPlugin {
|
|
|
49
51
|
|
|
50
52
|
/**
|
|
51
53
|
*
|
|
52
|
-
* @param {ProducerResponseItem[]}
|
|
54
|
+
* @param {{ result: ProducerResponseItem[] }} ctx
|
|
53
55
|
* @returns {void}
|
|
54
56
|
*/
|
|
55
57
|
commit (ctx) {
|
|
@@ -111,7 +111,7 @@ function constructChatCompletionResponseFromStreamedChunks (chunks, n) {
|
|
|
111
111
|
* Constructs the entire response from a stream of OpenAI responses chunks.
|
|
112
112
|
* The responses API uses event-based streaming with delta chunks.
|
|
113
113
|
* @param {Array<Record<string, any>>} chunks
|
|
114
|
-
* @returns {Record<string, any
|
|
114
|
+
* @returns {Record<string, any>|undefined}
|
|
115
115
|
*/
|
|
116
116
|
function constructResponseResponseFromStreamedChunks (chunks) {
|
|
117
117
|
// The responses API streams events with different types:
|
|
@@ -91,7 +91,7 @@ function wrapFunction (original, wrapper) {
|
|
|
91
91
|
* @param {Record<string | symbol, unknown> | Function | undefined} target - The target
|
|
92
92
|
* object.
|
|
93
93
|
* @param {string | symbol} name - The property key of the method to wrap.
|
|
94
|
-
* @param {(original: Function) => (...args) => any} wrapper - The wrapper function.
|
|
94
|
+
* @param {(original: Function) => (...args: unknown[]) => any} wrapper - The wrapper function.
|
|
95
95
|
* @param {{ replaceGetter?: boolean }} [options] - If `replaceGetter` is set to
|
|
96
96
|
* true, the getter is accessed and the getter is replaced with one that just
|
|
97
97
|
* returns the earlier retrieved value. Use with care! This may only be done in
|
|
@@ -214,7 +214,7 @@ function wrap (target, name, wrapper, options) {
|
|
|
214
214
|
* Record<string | symbol, unknown> |
|
|
215
215
|
* Function} targets - The target objects.
|
|
216
216
|
* @param {Array<string | symbol> | string | symbol} names - The property keys of the methods to wrap.
|
|
217
|
-
* @param {(original: Function) => (...args) => any} wrapper - The wrapper function.
|
|
217
|
+
* @param {(original: Function) => (...args: unknown[]) => any} wrapper - The wrapper function.
|
|
218
218
|
*/
|
|
219
219
|
function massWrap (targets, names, wrapper) {
|
|
220
220
|
targets = toArray(targets)
|
|
@@ -138,10 +138,11 @@ class AIGuard extends NoopAIGuard {
|
|
|
138
138
|
span.setTag(AI_GUARD_TOOL_NAME_TAG_KEY, name)
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
+
const metaStruct = {
|
|
142
|
+
messages: this.#truncate(messages)
|
|
143
|
+
}
|
|
141
144
|
span.meta_struct = {
|
|
142
|
-
[AI_GUARD_META_STRUCT_KEY]:
|
|
143
|
-
messages: this.#truncate(messages)
|
|
144
|
-
}
|
|
145
|
+
[AI_GUARD_META_STRUCT_KEY]: metaStruct
|
|
145
146
|
}
|
|
146
147
|
let response
|
|
147
148
|
try {
|
|
@@ -166,7 +167,7 @@ class AIGuard extends NoopAIGuard {
|
|
|
166
167
|
`AI Guard service call failed, status ${response.status}`,
|
|
167
168
|
{ errors: response.body?.errors })
|
|
168
169
|
}
|
|
169
|
-
let action, reason, blockingEnabled
|
|
170
|
+
let action, reason, tags, blockingEnabled
|
|
170
171
|
try {
|
|
171
172
|
const attr = response.body.data.attributes
|
|
172
173
|
if (!attr.action) {
|
|
@@ -174,6 +175,7 @@ class AIGuard extends NoopAIGuard {
|
|
|
174
175
|
}
|
|
175
176
|
action = attr.action
|
|
176
177
|
reason = attr.reason
|
|
178
|
+
tags = attr.tags
|
|
177
179
|
blockingEnabled = attr.is_blocking_enabled ?? false
|
|
178
180
|
} catch (e) {
|
|
179
181
|
appsecMetrics.count(AI_GUARD_TELEMETRY_REQUESTS, { error: true }).inc(1)
|
|
@@ -182,7 +184,12 @@ class AIGuard extends NoopAIGuard {
|
|
|
182
184
|
const shouldBlock = block && blockingEnabled && action !== ALLOW
|
|
183
185
|
appsecMetrics.count(AI_GUARD_TELEMETRY_REQUESTS, { action, error: false, block: shouldBlock }).inc(1)
|
|
184
186
|
span.setTag(AI_GUARD_ACTION_TAG_KEY, action)
|
|
185
|
-
|
|
187
|
+
if (reason) {
|
|
188
|
+
span.setTag(AI_GUARD_REASON_TAG_KEY, reason)
|
|
189
|
+
}
|
|
190
|
+
if (tags?.length > 0) {
|
|
191
|
+
metaStruct.attack_categories = tags
|
|
192
|
+
}
|
|
186
193
|
if (shouldBlock) {
|
|
187
194
|
span.setTag(AI_GUARD_BLOCKED_TAG_KEY, 'true')
|
|
188
195
|
throw new AIGuardAbortError(reason)
|
|
@@ -3,11 +3,18 @@
|
|
|
3
3
|
const { storage } = require('../../datadog-core')
|
|
4
4
|
const baggageStorage = storage('baggage')
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @param {string} key
|
|
8
|
+
* @param {string} value
|
|
9
|
+
*/
|
|
6
10
|
function setBaggageItem (key, value) {
|
|
7
11
|
storage('baggage').enterWith({ ...baggageStorage.getStore(), [key]: value })
|
|
8
12
|
return storage('baggage').getStore()
|
|
9
13
|
}
|
|
10
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} key
|
|
17
|
+
*/
|
|
11
18
|
function getBaggageItem (key) {
|
|
12
19
|
return storage('baggage').getStore()?.[key]
|
|
13
20
|
}
|
|
@@ -16,6 +23,10 @@ function getAllBaggageItems () {
|
|
|
16
23
|
return storage('baggage').getStore() ?? {}
|
|
17
24
|
}
|
|
18
25
|
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} keyToRemove
|
|
28
|
+
* @returns {Record<string, unknown>}
|
|
29
|
+
*/
|
|
19
30
|
function removeBaggageItem (keyToRemove) {
|
|
20
31
|
const { [keyToRemove]: _, ...newBaggage } = storage('baggage').getStore()
|
|
21
32
|
storage('baggage').enterWith(newBaggage)
|
|
@@ -245,7 +245,7 @@ function generateAndUploadPackFiles ({
|
|
|
245
245
|
|
|
246
246
|
/**
|
|
247
247
|
* This function uploads git metadata to CI Visibility's backend.
|
|
248
|
-
*/
|
|
248
|
+
*/
|
|
249
249
|
function sendGitMetadata (url, { isEvpProxy, evpProxyPrefix }, configRepositoryUrl, callback) {
|
|
250
250
|
if (!isGitAvailable()) {
|
|
251
251
|
return callback(new Error('Git is not available'))
|
|
@@ -77,6 +77,7 @@ module.exports = {
|
|
|
77
77
|
'experimental.enableGetRumData': false,
|
|
78
78
|
'experimental.exporter': undefined,
|
|
79
79
|
'experimental.flaggingProvider.enabled': false,
|
|
80
|
+
'experimental.flaggingProvider.initializationTimeoutMs': 30_000,
|
|
80
81
|
flushInterval: 2000,
|
|
81
82
|
flushMinSpans: 1000,
|
|
82
83
|
gitMetadataEnabled: true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { truncateSpan, normalizeSpan } = require('./tags-processors')
|
|
4
|
-
const {
|
|
4
|
+
const { MsgpackChunk, MsgpackEncoder } = require('../msgpack')
|
|
5
5
|
const log = require('../log')
|
|
6
6
|
const { isTrue } = require('../util')
|
|
7
7
|
const { memoize } = require('../log/utils')
|
|
@@ -27,8 +27,8 @@ class AgentEncoder {
|
|
|
27
27
|
constructor (writer, limit = SOFT_LIMIT) {
|
|
28
28
|
this._msgpack = new MsgpackEncoder()
|
|
29
29
|
this._limit = limit
|
|
30
|
-
this._traceBytes = new
|
|
31
|
-
this._stringBytes = new
|
|
30
|
+
this._traceBytes = new MsgpackChunk()
|
|
31
|
+
this._stringBytes = new MsgpackChunk()
|
|
32
32
|
this._writer = writer
|
|
33
33
|
this._reset()
|
|
34
34
|
this._debugEncoding = isTrue(getEnvironmentVariable('DD_TRACE_ENCODING_DEBUG'))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const { AgentEncoder } = require('./0.4')
|
|
3
|
-
const {
|
|
3
|
+
const { MsgpackChunk } = require('../msgpack')
|
|
4
4
|
|
|
5
5
|
const {
|
|
6
6
|
distributionMetric,
|
|
@@ -15,7 +15,7 @@ const COVERAGE_KEYS_LENGTH = 2
|
|
|
15
15
|
class CoverageCIVisibilityEncoder extends AgentEncoder {
|
|
16
16
|
constructor () {
|
|
17
17
|
super(...arguments)
|
|
18
|
-
this._coverageBytes = new
|
|
18
|
+
this._coverageBytes = new MsgpackChunk()
|
|
19
19
|
this.form = new FormData()
|
|
20
20
|
this._coveragesCount = 0
|
|
21
21
|
this.reset()
|