dd-trace 5.98.0 → 5.99.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 +0 -1
- package/ext/tags.js +1 -0
- package/index.d.ts +9 -1
- package/package.json +48 -46
- package/packages/datadog-instrumentations/src/crypto.js +45 -0
- package/packages/datadog-instrumentations/src/cypress-config.js +122 -16
- package/packages/datadog-instrumentations/src/dns.js +24 -56
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +74 -0
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +4 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +10 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/modelcontextprotocol-sdk.js +59 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +11 -2
- package/packages/datadog-instrumentations/src/modelcontextprotocol-sdk.js +7 -0
- package/packages/datadog-instrumentations/src/pino.js +4 -28
- package/packages/datadog-instrumentations/src/playwright-browser-scripts.js +27 -0
- package/packages/datadog-instrumentations/src/playwright.js +5 -17
- package/packages/datadog-instrumentations/src/stripe.js +38 -24
- package/packages/datadog-instrumentations/src/vitest.js +32 -4
- package/packages/datadog-instrumentations/src/zlib.js +29 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -2
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +8 -15
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +4 -9
- package/packages/datadog-plugin-cucumber/src/index.js +2 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +5 -5
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +48 -1
- package/packages/datadog-plugin-http/src/server.js +11 -11
- package/packages/datadog-plugin-jest/src/index.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +1 -2
- package/packages/datadog-plugin-modelcontextprotocol-sdk/src/index.js +24 -0
- package/packages/datadog-plugin-modelcontextprotocol-sdk/src/tracing.js +55 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +1 -6
- package/packages/datadog-plugin-playwright/src/index.js +2 -3
- package/packages/datadog-plugin-vitest/src/index.js +14 -6
- package/packages/datadog-plugin-ws/src/close.js +2 -0
- package/packages/datadog-plugin-ws/src/producer.js +2 -0
- package/packages/datadog-plugin-ws/src/receiver.js +1 -0
- package/packages/dd-trace/src/aiguard/channels.js +8 -0
- package/packages/dd-trace/src/aiguard/index.js +7 -3
- package/packages/dd-trace/src/aiguard/sdk.js +44 -0
- package/packages/dd-trace/src/aiguard/tags.js +1 -0
- package/packages/dd-trace/src/appsec/graphql.js +6 -6
- package/packages/dd-trace/src/appsec/index.js +9 -11
- package/packages/dd-trace/src/appsec/rasp/command_injection.js +4 -5
- package/packages/dd-trace/src/appsec/rasp/lfi.js +8 -4
- package/packages/dd-trace/src/appsec/rasp/sql_injection.js +5 -10
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +5 -6
- package/packages/dd-trace/src/appsec/recommended.json +2438 -13
- package/packages/dd-trace/src/appsec/reporter.js +6 -5
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +4 -8
- package/packages/dd-trace/src/appsec/store.js +50 -0
- package/packages/dd-trace/src/appsec/waf/index.js +3 -5
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -4
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -5
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +3 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +6 -6
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +2 -2
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
- package/packages/dd-trace/src/config/config-types.d.ts +0 -4
- package/packages/dd-trace/src/config/defaults.js +10 -10
- package/packages/dd-trace/src/config/generated-config-types.d.ts +13 -12
- package/packages/dd-trace/src/config/index.js +25 -35
- package/packages/dd-trace/src/config/parsers.js +26 -9
- package/packages/dd-trace/src/config/supported-configurations.json +32 -36
- package/packages/dd-trace/src/debugger/config.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +25 -5
- package/packages/dd-trace/src/encode/0.4.js +4 -5
- package/packages/dd-trace/src/exporters/agent/index.js +0 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -2
- package/packages/dd-trace/src/exporters/agentless/writer.js +3 -3
- package/packages/dd-trace/src/exporters/common/util.js +2 -2
- package/packages/dd-trace/src/id.js +2 -0
- package/packages/dd-trace/src/index.js +2 -5
- package/packages/dd-trace/src/lambda/handler.js +1 -3
- package/packages/dd-trace/src/llmobs/plugins/{anthropic.js → anthropic/index.js} +5 -63
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +106 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +3 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +2 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +0 -49
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +2 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/messages.js +76 -0
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -26
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/index.js +68 -0
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +57 -0
- package/packages/dd-trace/src/llmobs/sdk.js +2 -2
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +103 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -0
- package/packages/dd-trace/src/opentelemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +3 -2
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +3 -2
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +19 -66
- package/packages/dd-trace/src/opentelemetry/trace/index.js +11 -16
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +11 -3
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +51 -41
- package/packages/dd-trace/src/opentelemetry/tracer.js +9 -11
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -10
- package/packages/dd-trace/src/opentracing/span.js +1 -1
- package/packages/dd-trace/src/opentracing/tracer.js +12 -5
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/test.js +126 -5
- package/packages/dd-trace/src/plugins/util/url.js +2 -1
- package/packages/dd-trace/src/profiling/profilers/event_plugins/crypto.js +32 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/zlib.js +19 -0
- package/packages/dd-trace/src/profiling/profilers/events.js +35 -0
- package/packages/dd-trace/src/proxy.js +2 -8
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
- package/packages/dd-trace/src/span_processor.js +1 -2
- package/packages/dd-trace/src/tagger.js +2 -2
- package/packages/dd-trace/src/telemetry/send-data.js +5 -7
- package/packages/dd-trace/src/tracer.js +2 -2
- package/vendor/dist/ignore/LICENSE +0 -21
- package/vendor/dist/ignore/index.js +0 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../../datadog-shimmer')
|
|
4
|
+
const { channel } = require('./instrument')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create a shimmer-compatible instrumentor for callback-style APIs whose work is offloaded to the
|
|
8
|
+
* libuv worker thread pool (e.g. zlib.gzip, crypto.pbkdf2, dns.lookup). Builds a set of three
|
|
9
|
+
* diagnostic channels at the given prefix (`<prefix>:start`, `:finish`, `:error`) and returns a
|
|
10
|
+
* factory that produces shimmer wrappers driven by a caller-supplied `buildContext` function.
|
|
11
|
+
*
|
|
12
|
+
* The returned wrapper:
|
|
13
|
+
* - calls through unmodified when there are no subscribers or the last argument is not a callback;
|
|
14
|
+
* - invokes `buildContext(thisArg, args)` to construct the context object; a return of `undefined`
|
|
15
|
+
* also causes a bypass, letting callers enforce additional guards (e.g. minimum argument count);
|
|
16
|
+
* - publishes `:start` via `runStores`, wraps the callback to publish `:error` (on truthy error),
|
|
17
|
+
* optionally set `ctx.result` to the callback's first non-error argument, and publish `:finish`
|
|
18
|
+
* via `runStores`; publishes `:error` if the original call throws synchronously.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} prefix
|
|
21
|
+
* @param {object} [options]
|
|
22
|
+
* @param {boolean} [options.captureResult=false] set `ctx.result` to the callback's first
|
|
23
|
+
* non-error argument before publishing `:finish`. Plugins that tag spans from the call's
|
|
24
|
+
* return value (e.g. the DNS lookup plugin) rely on this.
|
|
25
|
+
* @returns {(buildContext: (thisArg: unknown, args: IArguments) => object | undefined) =>
|
|
26
|
+
* (fn: Function) => Function}
|
|
27
|
+
*/
|
|
28
|
+
function createCallbackInstrumentor (prefix, { captureResult = false } = {}) {
|
|
29
|
+
const startCh = channel(prefix + ':start')
|
|
30
|
+
const finishCh = channel(prefix + ':finish')
|
|
31
|
+
const errorCh = channel(prefix + ':error')
|
|
32
|
+
|
|
33
|
+
return function instrument (buildContext) {
|
|
34
|
+
return function wrap (fn) {
|
|
35
|
+
return function () {
|
|
36
|
+
const lastIndex = arguments.length - 1
|
|
37
|
+
const cb = arguments[lastIndex]
|
|
38
|
+
if (!startCh.hasSubscribers || typeof cb !== 'function') {
|
|
39
|
+
return fn.apply(this, arguments)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const ctx = buildContext(this, arguments)
|
|
43
|
+
if (ctx === undefined) {
|
|
44
|
+
return fn.apply(this, arguments)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return startCh.runStores(ctx, () => {
|
|
48
|
+
arguments[lastIndex] = shimmer.wrapFunction(cb, cb => function (error, ...rest) {
|
|
49
|
+
if (error) {
|
|
50
|
+
ctx.error = error
|
|
51
|
+
errorCh.publish(ctx)
|
|
52
|
+
}
|
|
53
|
+
if (captureResult) {
|
|
54
|
+
ctx.result = rest[0]
|
|
55
|
+
}
|
|
56
|
+
return finishCh.runStores(ctx, cb, this, error, ...rest)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
return fn.apply(this, arguments)
|
|
61
|
+
} catch (error) {
|
|
62
|
+
void error.stack // trigger getting the stack at the original throwing point
|
|
63
|
+
ctx.error = error
|
|
64
|
+
errorCh.publish(ctx)
|
|
65
|
+
|
|
66
|
+
throw error
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = { createCallbackInstrumentor }
|
|
@@ -97,7 +97,10 @@ module.exports.checkForPotentialConflicts = function () {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
module.exports.flushStartupLogs = function (log) {
|
|
100
|
+
// Some callers pass `./log/writer` (simple pass-through) while others pass the main `./log`
|
|
101
|
+
// module (which supports lazy delegate functions). Invoke closures here so both work.
|
|
100
102
|
while (warnings.length) {
|
|
101
|
-
|
|
103
|
+
const entry = warnings.shift()
|
|
104
|
+
log.warn(typeof entry === 'function' ? entry() : entry)
|
|
102
105
|
}
|
|
103
106
|
}
|
|
@@ -12,11 +12,13 @@ module.exports = {
|
|
|
12
12
|
net: () => require('../net'),
|
|
13
13
|
url: () => require('../url'),
|
|
14
14
|
vm: () => require('../vm'),
|
|
15
|
+
zlib: () => require('../zlib'),
|
|
15
16
|
// Non Node.js modules
|
|
16
17
|
'@anthropic-ai/sdk': { esmFirst: true, fn: () => require('../anthropic') },
|
|
17
18
|
'@apollo/server': () => require('../apollo-server'),
|
|
18
19
|
'@apollo/gateway': () => require('../apollo'),
|
|
19
20
|
'@langchain/langgraph': { esmFirst: true, fn: () => require('../langgraph') },
|
|
21
|
+
'@modelcontextprotocol/sdk': () => require('../modelcontextprotocol-sdk'),
|
|
20
22
|
'apollo-server-core': () => require('../apollo-server-core'),
|
|
21
23
|
'@aws-sdk/smithy-client': () => require('../aws-sdk'),
|
|
22
24
|
'@azure/event-hubs': () => require('../azure-event-hubs'),
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* This file is meant to be only thin wrappers over core
|
|
5
|
+
* parsing/traversing/generating functionality with the goal to eventually move
|
|
6
|
+
* them out of the project. No other code should be added to this file such as
|
|
7
|
+
* helpers etc, and the API should be kept exactly as an external API would be
|
|
8
|
+
* expected to be.
|
|
9
|
+
*/
|
|
10
|
+
|
|
3
11
|
const log = require('../../../../dd-trace/src/log')
|
|
4
12
|
|
|
5
13
|
// eslint-disable-next-line camelcase, no-undef
|
|
@@ -24,14 +32,13 @@ const compiler = {
|
|
|
24
32
|
} catch (e) {
|
|
25
33
|
log.error(e)
|
|
26
34
|
|
|
27
|
-
// Fallback for when OXC is not available.
|
|
28
35
|
const meriyah = require('../../../../../vendor/dist/meriyah')
|
|
29
36
|
|
|
30
|
-
compiler.parse = (sourceText, { range,
|
|
37
|
+
compiler.parse = (sourceText, { range, isModule } = {}) => {
|
|
31
38
|
return meriyah.parse(sourceText.toString(), {
|
|
32
39
|
loc: range,
|
|
33
40
|
ranges: range,
|
|
34
|
-
module:
|
|
41
|
+
module: isModule,
|
|
35
42
|
})
|
|
36
43
|
}
|
|
37
44
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// NOTE: Protocol.request (dist/esm|cjs/shared/protocol.js) is intentionally not instrumented here.
|
|
4
|
+
// It will be used for distributed tracing header injection when server-side coverage is added.
|
|
5
|
+
|
|
6
|
+
module.exports = [
|
|
7
|
+
{
|
|
8
|
+
module: {
|
|
9
|
+
name: '@modelcontextprotocol/sdk',
|
|
10
|
+
versionRange: '>=1.27.1',
|
|
11
|
+
filePath: 'dist/esm/client/index.js',
|
|
12
|
+
},
|
|
13
|
+
functionQuery: {
|
|
14
|
+
methodName: 'callTool',
|
|
15
|
+
className: 'Client',
|
|
16
|
+
kind: 'Async',
|
|
17
|
+
},
|
|
18
|
+
channelName: 'Client_callTool',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
module: {
|
|
22
|
+
name: '@modelcontextprotocol/sdk',
|
|
23
|
+
versionRange: '>=1.27.1',
|
|
24
|
+
filePath: 'dist/cjs/client/index.js',
|
|
25
|
+
},
|
|
26
|
+
functionQuery: {
|
|
27
|
+
methodName: 'callTool',
|
|
28
|
+
className: 'Client',
|
|
29
|
+
kind: 'Async',
|
|
30
|
+
},
|
|
31
|
+
channelName: 'Client_callTool',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
module: {
|
|
35
|
+
name: '@modelcontextprotocol/sdk',
|
|
36
|
+
versionRange: '>=1.27.1',
|
|
37
|
+
filePath: 'dist/esm/client/index.js',
|
|
38
|
+
},
|
|
39
|
+
functionQuery: {
|
|
40
|
+
methodName: 'listTools',
|
|
41
|
+
className: 'Client',
|
|
42
|
+
kind: 'Async',
|
|
43
|
+
},
|
|
44
|
+
channelName: 'Client_listTools',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
module: {
|
|
48
|
+
name: '@modelcontextprotocol/sdk',
|
|
49
|
+
versionRange: '>=1.27.1',
|
|
50
|
+
filePath: 'dist/cjs/client/index.js',
|
|
51
|
+
},
|
|
52
|
+
functionQuery: {
|
|
53
|
+
methodName: 'listTools',
|
|
54
|
+
className: 'Client',
|
|
55
|
+
kind: 'Async',
|
|
56
|
+
},
|
|
57
|
+
channelName: 'Client_listTools',
|
|
58
|
+
},
|
|
59
|
+
]
|
|
@@ -14,11 +14,13 @@ const transforms = module.exports = {
|
|
|
14
14
|
if (node.body.some(tracingChannelPredicate)) return
|
|
15
15
|
|
|
16
16
|
const index = node.body.findIndex(child => child.directive === 'use strict')
|
|
17
|
-
const code = sourceType
|
|
17
|
+
const code = isModuleSourceType(sourceType)
|
|
18
18
|
? `import { tracingChannel as tr_ch_apm_tracingChannel } from "${dcModule}"`
|
|
19
19
|
: `const {tracingChannel: tr_ch_apm_tracingChannel} = require("${dcModule}")`
|
|
20
20
|
|
|
21
|
-
node.body.splice(index + 1, 0, parse(code, {
|
|
21
|
+
node.body.splice(index + 1, 0, parse(code, {
|
|
22
|
+
isModule: isModuleSourceType(sourceType),
|
|
23
|
+
}).body[0])
|
|
22
24
|
},
|
|
23
25
|
|
|
24
26
|
tracingChannelDeclaration (state, node) {
|
|
@@ -51,6 +53,13 @@ function traceAny (state, node, _parent, ancestry) {
|
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @param {string} sourceType
|
|
58
|
+
*/
|
|
59
|
+
function isModuleSourceType (sourceType) {
|
|
60
|
+
return sourceType === 'module' || sourceType === 'esm'
|
|
61
|
+
}
|
|
62
|
+
|
|
54
63
|
function traceFunction (state, node, program) {
|
|
55
64
|
transforms.tracingChannelDeclaration(state, program)
|
|
56
65
|
|
|
@@ -34,22 +34,6 @@ function wrapAsJson (asJson) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function wrapMixin (mixin) {
|
|
38
|
-
const ch = channel('apm:pino:log')
|
|
39
|
-
return function mixinWithTrace () {
|
|
40
|
-
let obj = {}
|
|
41
|
-
|
|
42
|
-
if (mixin) {
|
|
43
|
-
obj = mixin.apply(this, arguments)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const payload = { message: obj }
|
|
47
|
-
ch.publish(payload)
|
|
48
|
-
|
|
49
|
-
return payload.message
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
37
|
function wrapPrettifyObject (prettifyObject) {
|
|
54
38
|
const ch = channel('apm:pino:log')
|
|
55
39
|
return function prettifyObjectWithTrace (input) {
|
|
@@ -81,26 +65,18 @@ addHook({ name: 'pino', versions: ['2 - 3', '4'], patchDefault: true }, (pino) =
|
|
|
81
65
|
return wrapped
|
|
82
66
|
})
|
|
83
67
|
|
|
84
|
-
addHook({ name: 'pino', versions: ['>=5 <
|
|
68
|
+
addHook({ name: 'pino', versions: ['>=5 <6.8.0'], patchDefault: true }, (pino) => {
|
|
85
69
|
const asJsonSym = ((pino.default || pino)?.symbols.asJsonSym) || 'asJson'
|
|
86
70
|
|
|
87
|
-
const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(asJsonSym, wrapAsJson, pino))
|
|
88
|
-
|
|
89
|
-
return wrapped
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
addHook({ name: 'pino', versions: ['>=5.14.0 <6.8.0'] }, (pino) => {
|
|
93
|
-
const mixinSym = (pino.default || pino).symbols.mixinSym
|
|
94
|
-
|
|
95
|
-
const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, pino.default || pino))
|
|
71
|
+
const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(asJsonSym, wrapAsJson, pino.default || pino))
|
|
96
72
|
|
|
97
73
|
return wrapped
|
|
98
74
|
})
|
|
99
75
|
|
|
100
76
|
addHook({ name: 'pino', versions: ['>=6.8.0'], patchDefault: false }, (pino) => {
|
|
101
|
-
const
|
|
77
|
+
const asJsonSym = pino.symbols.asJsonSym
|
|
102
78
|
|
|
103
|
-
const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(
|
|
79
|
+
const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(asJsonSym, wrapAsJson, pino))
|
|
104
80
|
wrapped.pino = wrapped
|
|
105
81
|
wrapped.default = wrapped
|
|
106
82
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// Serialized into chromium via Playwright's `page.evaluate`. Excluded from coverage by filename.
|
|
4
|
+
// Rename only if you update that glob too.
|
|
5
|
+
|
|
6
|
+
/** @returns {{ isRumInstrumented: boolean, isRumActive: boolean, rumSamplingRate: number | null }} */
|
|
7
|
+
function detectRum () {
|
|
8
|
+
const isRumInstrumented = !!window.DD_RUM
|
|
9
|
+
const isRumActive = window.DD_RUM && window.DD_RUM.getInternalContext
|
|
10
|
+
? !!window.DD_RUM.getInternalContext()
|
|
11
|
+
: false
|
|
12
|
+
const rumSamplingRate = window.DD_RUM && window.DD_RUM.getInitConfiguration
|
|
13
|
+
? window.DD_RUM.getInitConfiguration().sessionSampleRate
|
|
14
|
+
: null
|
|
15
|
+
return { isRumInstrumented, isRumActive, rumSamplingRate }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** @returns {boolean} */
|
|
19
|
+
function stopRumSession () {
|
|
20
|
+
if (window.DD_RUM && window.DD_RUM.stopSession) {
|
|
21
|
+
window.DD_RUM.stopSession()
|
|
22
|
+
return true
|
|
23
|
+
}
|
|
24
|
+
return false
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = { detectRum, stopRumSession }
|
|
@@ -52,6 +52,9 @@ let applyRepeatEachIndex = null
|
|
|
52
52
|
|
|
53
53
|
let startedSuites = []
|
|
54
54
|
|
|
55
|
+
// Browser-side callbacks live in a coverage-excluded file so coverage counters can't reach chromium.
|
|
56
|
+
const { detectRum, stopRumSession } = require('./playwright-browser-scripts')
|
|
57
|
+
|
|
55
58
|
const STATUS_TO_TEST_STATUS = {
|
|
56
59
|
passed: 'pass',
|
|
57
60
|
failed: 'fail',
|
|
@@ -1117,16 +1120,7 @@ addHook({
|
|
|
1117
1120
|
|
|
1118
1121
|
try {
|
|
1119
1122
|
if (page) {
|
|
1120
|
-
const { isRumInstrumented, isRumActive, rumSamplingRate } = await page.evaluate(
|
|
1121
|
-
const isRumInstrumented = !!window.DD_RUM
|
|
1122
|
-
const isRumActive = window.DD_RUM && window.DD_RUM.getInternalContext
|
|
1123
|
-
? !!window.DD_RUM.getInternalContext()
|
|
1124
|
-
: false
|
|
1125
|
-
const rumSamplingRate = window.DD_RUM && window.DD_RUM.getInitConfiguration
|
|
1126
|
-
? window.DD_RUM.getInitConfiguration().sessionSampleRate
|
|
1127
|
-
: null
|
|
1128
|
-
return { isRumInstrumented, isRumActive, rumSamplingRate }
|
|
1129
|
-
})
|
|
1123
|
+
const { isRumInstrumented, isRumActive, rumSamplingRate } = await page.evaluate(detectRum)
|
|
1130
1124
|
if (isRumInstrumented && rumSamplingRate < 100 && !isRumActive) {
|
|
1131
1125
|
log.debug("RUM was detected on the page, but it isn't active because the sampling rate is below 100%")
|
|
1132
1126
|
}
|
|
@@ -1209,13 +1203,7 @@ addHook({
|
|
|
1209
1203
|
fn: async function ({ page }) {
|
|
1210
1204
|
try {
|
|
1211
1205
|
if (page) {
|
|
1212
|
-
const isRumActive = await page.evaluate(
|
|
1213
|
-
if (window.DD_RUM && window.DD_RUM.stopSession) {
|
|
1214
|
-
window.DD_RUM.stopSession()
|
|
1215
|
-
return true
|
|
1216
|
-
}
|
|
1217
|
-
return false
|
|
1218
|
-
})
|
|
1206
|
+
const isRumActive = await page.evaluate(stopRumSession)
|
|
1219
1207
|
|
|
1220
1208
|
if (isRumActive) {
|
|
1221
1209
|
// Give some time RUM to flush data, similar to what we do in selenium
|
|
@@ -58,35 +58,49 @@ function wrapConstructEventAsync (constructEventAsync) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
function
|
|
61
|
+
function instrumentStripeInstance (stripe) {
|
|
62
|
+
if (typeof stripe.checkout?.sessions?.create === 'function') {
|
|
63
|
+
shimmer.wrap(stripe.checkout.sessions, 'create', wrapSessionCreate)
|
|
64
|
+
}
|
|
65
|
+
if (typeof stripe.paymentIntents?.create === 'function') {
|
|
66
|
+
shimmer.wrap(stripe.paymentIntents, 'create', wrapPaymentIntentCreate)
|
|
67
|
+
}
|
|
68
|
+
if (typeof stripe.webhooks?.constructEvent === 'function') {
|
|
69
|
+
shimmer.wrap(stripe.webhooks, 'constructEvent', wrapConstructEvent)
|
|
70
|
+
}
|
|
71
|
+
if (typeof stripe.webhooks?.constructEventAsync === 'function') {
|
|
72
|
+
shimmer.wrap(stripe.webhooks, 'constructEventAsync', wrapConstructEventAsync)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// stripe <22: the constructor mutates this (when invoked with 'new') and
|
|
77
|
+
// returns nothing; without 'new' it delegates to 'new Stripe(...)' and returns
|
|
78
|
+
// that result. We need to instrument whichever object actually got populated
|
|
79
|
+
function wrapLegacyStripe (Stripe) {
|
|
62
80
|
return function wrappedStripe () {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (typeof stripe.checkout?.sessions?.create === 'function') {
|
|
71
|
-
shimmer.wrap(stripe.checkout.sessions, 'create', wrapSessionCreate)
|
|
72
|
-
}
|
|
73
|
-
if (typeof stripe.paymentIntents?.create === 'function') {
|
|
74
|
-
shimmer.wrap(stripe.paymentIntents, 'create', wrapPaymentIntentCreate)
|
|
75
|
-
}
|
|
76
|
-
if (typeof stripe.webhooks?.constructEvent === 'function') {
|
|
77
|
-
shimmer.wrap(stripe.webhooks, 'constructEvent', wrapConstructEvent)
|
|
78
|
-
}
|
|
79
|
-
if (typeof stripe.webhooks?.constructEventAsync === 'function') {
|
|
80
|
-
shimmer.wrap(stripe.webhooks, 'constructEventAsync', wrapConstructEventAsync)
|
|
81
|
-
}
|
|
81
|
+
const result = Stripe.apply(this, arguments)
|
|
82
|
+
const stripe = this instanceof Stripe ? this : result
|
|
83
|
+
instrumentStripeInstance(stripe)
|
|
84
|
+
return stripe
|
|
85
|
+
}
|
|
86
|
+
}
|
|
82
87
|
|
|
88
|
+
// stripe >=22: the constructor is a factory that always returns a fresh Stripe
|
|
89
|
+
// instance regardless of 'new', so we just instrument and forward the result
|
|
90
|
+
function wrapStripe (Stripe) {
|
|
91
|
+
return function wrappedStripe () {
|
|
92
|
+
const stripe = Stripe.apply(this, arguments)
|
|
93
|
+
instrumentStripeInstance(stripe)
|
|
83
94
|
return stripe
|
|
84
95
|
}
|
|
85
96
|
}
|
|
86
97
|
|
|
87
98
|
addHook({
|
|
88
99
|
name: 'stripe',
|
|
89
|
-
versions: ['9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '>=20.0.0'],
|
|
90
|
-
}, Stripe =>
|
|
91
|
-
|
|
92
|
-
|
|
100
|
+
versions: ['9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '>=20.0.0 <22'],
|
|
101
|
+
}, Stripe => shimmer.wrapFunction(Stripe, wrapLegacyStripe))
|
|
102
|
+
|
|
103
|
+
addHook({
|
|
104
|
+
name: 'stripe',
|
|
105
|
+
versions: ['>=22'],
|
|
106
|
+
}, Stripe => shimmer.wrapFunction(Stripe, wrapStripe))
|
|
@@ -866,6 +866,9 @@ function wrapVitestTestRunner (VitestTestRunner) {
|
|
|
866
866
|
} else {
|
|
867
867
|
testPassCh.publish({ task, ...ctx.currentStore })
|
|
868
868
|
}
|
|
869
|
+
if (shouldFlipStatus) {
|
|
870
|
+
task.result.state = 'pass'
|
|
871
|
+
}
|
|
869
872
|
}
|
|
870
873
|
|
|
871
874
|
const isRetryReasonAtr = numAttempt > 0 &&
|
|
@@ -1174,7 +1177,12 @@ addHook({
|
|
|
1174
1177
|
})
|
|
1175
1178
|
} else if (state === 'pass' && !isSwitchedStatus) {
|
|
1176
1179
|
if (testCtx) {
|
|
1177
|
-
testPassCh.publish({
|
|
1180
|
+
testPassCh.publish({
|
|
1181
|
+
task,
|
|
1182
|
+
finalStatus:
|
|
1183
|
+
disabledTasks.has(task) || quarantinedTasks.has(task) ? 'skip' : 'pass',
|
|
1184
|
+
...testCtx.currentStore,
|
|
1185
|
+
})
|
|
1178
1186
|
}
|
|
1179
1187
|
} else if (state === 'fail' || isSwitchedStatus) {
|
|
1180
1188
|
let testError
|
|
@@ -1197,7 +1205,9 @@ addHook({
|
|
|
1197
1205
|
|
|
1198
1206
|
// Check if all EFD retries failed
|
|
1199
1207
|
const providedContext = getProvidedContext()
|
|
1200
|
-
|
|
1208
|
+
const isEfdRetry =
|
|
1209
|
+
providedContext.isEarlyFlakeDetectionEnabled && (newTasks.has(task) || modifiedTasks.has(task))
|
|
1210
|
+
if (isEfdRetry) {
|
|
1201
1211
|
const statuses = taskToStatuses.get(task)
|
|
1202
1212
|
// statuses only includes repetitions (not the initial run), so we check against numRepeats (not +1)
|
|
1203
1213
|
if (statuses && statuses.length === providedContext.numRepeats &&
|
|
@@ -1207,8 +1217,9 @@ addHook({
|
|
|
1207
1217
|
}
|
|
1208
1218
|
|
|
1209
1219
|
// ATR: set hasFailedAllRetries when all auto test retries were exhausted and every attempt failed
|
|
1210
|
-
|
|
1211
|
-
!newTasks.has(task) && !modifiedTasks.has(task)
|
|
1220
|
+
const isAtrRetry = providedContext.isFlakyTestRetriesEnabled && !attemptToFixTasks.has(task) &&
|
|
1221
|
+
!newTasks.has(task) && !modifiedTasks.has(task)
|
|
1222
|
+
if (isAtrRetry) {
|
|
1212
1223
|
const maxRetries = providedContext.flakyTestRetriesCount ?? 0
|
|
1213
1224
|
if (maxRetries > 0 && task.result?.retryCount === maxRetries) {
|
|
1214
1225
|
hasFailedAllRetries = true
|
|
@@ -1218,11 +1229,28 @@ addHook({
|
|
|
1218
1229
|
if (testCtx) {
|
|
1219
1230
|
const isRetry = task.result?.retryCount > 0
|
|
1220
1231
|
// `duration` is the duration of all the retries, so it can't be used if there are retries
|
|
1232
|
+
|
|
1233
|
+
let finalStatus
|
|
1234
|
+
if (isSwitchedStatus) {
|
|
1235
|
+
if (disabledTasks.has(task) || quarantinedTasks.has(task)) {
|
|
1236
|
+
finalStatus = 'skip'
|
|
1237
|
+
} else if (isAtrRetry || isEfdRetry) {
|
|
1238
|
+
finalStatus = hasFailedAllRetries ? 'fail' : 'pass'
|
|
1239
|
+
} else if (attemptToFixTasks.has(task)) {
|
|
1240
|
+
finalStatus = attemptToFixFailed ? 'fail' : 'pass'
|
|
1241
|
+
} else {
|
|
1242
|
+
finalStatus = undefined
|
|
1243
|
+
}
|
|
1244
|
+
} else {
|
|
1245
|
+
finalStatus = 'fail'
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1221
1248
|
testErrorCh.publish({
|
|
1222
1249
|
duration: isRetry ? undefined : duration,
|
|
1223
1250
|
error: testError,
|
|
1224
1251
|
hasFailedAllRetries,
|
|
1225
1252
|
attemptToFixFailed,
|
|
1253
|
+
finalStatus,
|
|
1226
1254
|
...testCtx.currentStore,
|
|
1227
1255
|
})
|
|
1228
1256
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../datadog-shimmer')
|
|
4
|
+
const { addHook } = require('./helpers/instrument')
|
|
5
|
+
const { createCallbackInstrumentor } = require('./helpers/callback-instrumentor')
|
|
6
|
+
|
|
7
|
+
const asyncMethods = [
|
|
8
|
+
'brotliCompress',
|
|
9
|
+
'brotliDecompress',
|
|
10
|
+
'deflate',
|
|
11
|
+
'deflateRaw',
|
|
12
|
+
'gunzip',
|
|
13
|
+
'gzip',
|
|
14
|
+
'inflate',
|
|
15
|
+
'inflateRaw',
|
|
16
|
+
'unzip',
|
|
17
|
+
'zstdCompress', // Node 22.15+ / 23.8+ / 24+
|
|
18
|
+
'zstdDecompress', // Node 22.15+ / 23.8+ / 24+
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
addHook({ name: 'zlib' }, zlib => {
|
|
22
|
+
const instrument = createCallbackInstrumentor('apm:zlib:operation')
|
|
23
|
+
for (const method of asyncMethods) {
|
|
24
|
+
if (typeof zlib[method] === 'function') {
|
|
25
|
+
shimmer.wrap(zlib, method, instrument(() => ({ operation: method })))
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return zlib
|
|
29
|
+
})
|
|
@@ -197,8 +197,7 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
197
197
|
|
|
198
198
|
isEnabled (request) {
|
|
199
199
|
const serviceId = this.serviceIdentifier.toUpperCase()
|
|
200
|
-
|
|
201
|
-
return envVarValue ? isTrue(envVarValue) : true
|
|
200
|
+
return this._tracerConfig[`DD_TRACE_AWS_SDK_${serviceId}_ENABLED`] ?? true
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
addResponseTags (span, response) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
4
3
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
5
4
|
|
|
6
5
|
const spanContexts = new WeakMap()
|
|
@@ -11,8 +10,9 @@ class AzureEventHubsProducerPlugin extends ProducerPlugin {
|
|
|
11
10
|
static get prefix () { return 'tracing:apm:azure-event-hubs:send' }
|
|
12
11
|
|
|
13
12
|
bindStart (ctx) {
|
|
13
|
+
const batchLinksEnabled = this._tracerConfig.DD_TRACE_AZURE_EVENTHUBS_BATCH_LINKS_ENABLED
|
|
14
14
|
// we do not want to make these spans when batch linking is disabled.
|
|
15
|
-
if (!
|
|
15
|
+
if (!batchLinksEnabled && ctx.functionName === 'tryAdd') {
|
|
16
16
|
return ctx.currentStore
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -37,7 +37,7 @@ class AzureEventHubsProducerPlugin extends ProducerPlugin {
|
|
|
37
37
|
span.setTag('message.id', ctx.eventData.messageID)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
if (
|
|
40
|
+
if (batchLinksEnabled) {
|
|
41
41
|
const spanContext = spanContexts.get(ctx.batch)
|
|
42
42
|
if (spanContext) {
|
|
43
43
|
spanContext.push(span.context())
|
|
@@ -58,13 +58,11 @@ class AzureEventHubsProducerPlugin extends ProducerPlugin {
|
|
|
58
58
|
for (const event of eventData) {
|
|
59
59
|
injectTraceContext(this.tracer, span, event)
|
|
60
60
|
}
|
|
61
|
-
} else {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
span.addLink(spanContext)
|
|
67
|
-
}
|
|
61
|
+
} else if (batchLinksEnabled) {
|
|
62
|
+
const contexts = spanContexts.get(eventData)
|
|
63
|
+
if (contexts) {
|
|
64
|
+
for (const spanContext of contexts) {
|
|
65
|
+
span.addLink(spanContext)
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
68
|
}
|
|
@@ -88,9 +86,4 @@ function injectTraceContext (tracer, span, event) {
|
|
|
88
86
|
tracer.inject(span, 'text_map', event.properties)
|
|
89
87
|
}
|
|
90
88
|
|
|
91
|
-
function batchLinksAreEnabled () {
|
|
92
|
-
const eh = getValueFromEnvSources('DD_TRACE_AZURE_EVENTHUBS_BATCH_LINKS_ENABLED')
|
|
93
|
-
return eh !== 'false'
|
|
94
|
-
}
|
|
95
|
-
|
|
96
89
|
module.exports = AzureEventHubsProducerPlugin
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
4
3
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
5
4
|
const spanContexts = new WeakMap()
|
|
6
5
|
|
|
@@ -10,8 +9,9 @@ class AzureServiceBusProducerPlugin extends ProducerPlugin {
|
|
|
10
9
|
static get prefix () { return 'tracing:apm:azure-service-bus:send' }
|
|
11
10
|
|
|
12
11
|
bindStart (ctx) {
|
|
12
|
+
const batchLinksEnabled = this._tracerConfig.DD_TRACE_AZURE_SERVICEBUS_BATCH_LINKS_ENABLED
|
|
13
13
|
// we do not want to make these spans when batch linking is disabled.
|
|
14
|
-
if (!
|
|
14
|
+
if (!batchLinksEnabled && ctx.functionName === 'tryAddMessage') {
|
|
15
15
|
return ctx.currentStore
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -36,7 +36,7 @@ class AzureServiceBusProducerPlugin extends ProducerPlugin {
|
|
|
36
36
|
span.setTag('message.id', ctx.msg)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
if (
|
|
39
|
+
if (batchLinksEnabled) {
|
|
40
40
|
const spanContext = spanContexts.get(ctx.batch)
|
|
41
41
|
if (spanContext) {
|
|
42
42
|
spanContext.push(span.context())
|
|
@@ -52,7 +52,7 @@ class AzureServiceBusProducerPlugin extends ProducerPlugin {
|
|
|
52
52
|
const isBatch = messages.constructor?.name === 'ServiceBusMessageBatchImpl'
|
|
53
53
|
if (isBatch) {
|
|
54
54
|
span.setTag('messaging.batch.message_count', messages.count)
|
|
55
|
-
if (
|
|
55
|
+
if (batchLinksEnabled) {
|
|
56
56
|
const contexts = spanContexts.get(messages)
|
|
57
57
|
if (contexts) {
|
|
58
58
|
for (const spanContext of contexts) {
|
|
@@ -89,9 +89,4 @@ function injectTraceContext (tracer, span, msg) {
|
|
|
89
89
|
tracer.inject(span, 'text_map', msg.applicationProperties)
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
function batchLinksAreEnabled () {
|
|
93
|
-
const sb = getValueFromEnvSources('DD_TRACE_AZURE_SERVICEBUS_BATCH_LINKS_ENABLED')
|
|
94
|
-
return sb !== 'false'
|
|
95
|
-
}
|
|
96
|
-
|
|
97
92
|
module.exports = AzureServiceBusProducerPlugin
|