dd-trace 5.109.0 → 5.111.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/README.md +13 -8
- package/ci/init.js +25 -5
- package/ci/vitest-no-worker-init-setup.mjs +430 -0
- package/ext/tags.js +2 -0
- package/index.d.ts +79 -24
- package/initialize.mjs +5 -6
- package/loader-hook.mjs +154 -47
- package/package.json +20 -16
- package/packages/datadog-esbuild/index.js +26 -0
- package/packages/datadog-esbuild/src/utils.js +46 -3
- package/packages/datadog-instrumentations/src/connect.js +4 -3
- package/packages/datadog-instrumentations/src/fastify.js +4 -12
- package/packages/datadog-instrumentations/src/fs.js +8 -6
- package/packages/datadog-instrumentations/src/graphql.js +26 -484
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +81 -8
- package/packages/datadog-instrumentations/src/helpers/instrument.js +27 -2
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +65 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +6 -4
- package/packages/datadog-instrumentations/src/helpers/require-optional-peer.js +17 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql.js +201 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +18 -2
- package/packages/datadog-instrumentations/src/koa.js +3 -2
- package/packages/datadog-instrumentations/src/mariadb.js +4 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +14 -2
- package/packages/datadog-instrumentations/src/next.js +10 -10
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +7 -6
- package/packages/datadog-instrumentations/src/playwright.js +1 -1
- package/packages/datadog-instrumentations/src/restify.js +4 -3
- package/packages/datadog-instrumentations/src/router.js +18 -5
- package/packages/datadog-instrumentations/src/selenium.js +1 -2
- package/packages/datadog-instrumentations/src/tedious.js +28 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +1293 -0
- package/packages/datadog-instrumentations/src/vitest-main.js +1567 -0
- package/packages/datadog-instrumentations/src/vitest-util.js +249 -0
- package/packages/datadog-instrumentations/src/vitest-worker.js +753 -0
- package/packages/datadog-instrumentations/src/vitest.js +11 -1598
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/client.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +18 -10
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +47 -11
- package/packages/datadog-plugin-aws-sdk/src/base.js +13 -9
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +43 -6
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +83 -91
- package/packages/datadog-plugin-cucumber/src/index.js +1 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +19 -5
- package/packages/datadog-plugin-cypress/src/support.js +45 -1
- package/packages/datadog-plugin-express/src/code_origin.js +1 -1
- package/packages/datadog-plugin-fastify/src/code_origin.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +627 -11
- package/packages/datadog-plugin-graphql/src/index.js +20 -8
- package/packages/datadog-plugin-graphql/src/parse.js +24 -4
- package/packages/datadog-plugin-graphql/src/validate.js +16 -5
- package/packages/datadog-plugin-http/src/client.js +8 -3
- package/packages/datadog-plugin-http/src/index.js +6 -8
- package/packages/datadog-plugin-http2/src/client.js +5 -2
- package/packages/datadog-plugin-jest/src/index.js +1 -1
- package/packages/datadog-plugin-mocha/src/index.js +1 -1
- package/packages/datadog-plugin-mysql/src/index.js +7 -2
- package/packages/datadog-plugin-openai/src/services.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +2 -2
- package/packages/datadog-plugin-undici/src/index.js +5 -2
- package/packages/datadog-plugin-vitest/src/index.js +76 -64
- package/packages/datadog-shimmer/src/shimmer.js +37 -16
- package/packages/datadog-webpack/index.js +17 -1
- package/packages/datadog-webpack/src/optional-peer-loader.js +17 -0
- package/packages/dd-trace/src/aiguard/sdk.js +15 -3
- package/packages/dd-trace/src/appsec/api_security/index.js +55 -0
- package/packages/dd-trace/src/appsec/api_security/sampler.js +147 -0
- package/packages/dd-trace/src/appsec/channels.js +3 -1
- package/packages/dd-trace/src/appsec/downstream_requests.js +4 -4
- package/packages/dd-trace/src/appsec/graphql.js +5 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +26 -19
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/index.js +2 -1
- package/packages/dd-trace/src/appsec/index.js +20 -7
- package/packages/dd-trace/src/appsec/lambda.js +135 -0
- package/packages/dd-trace/src/appsec/reporter.js +50 -10
- package/packages/dd-trace/src/appsec/telemetry/api_security.js +34 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +27 -1
- package/packages/dd-trace/src/appsec/waf/index.js +16 -4
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +4 -4
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +21 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +55 -13
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +17 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +47 -26
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +2 -2
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +64 -53
- package/packages/dd-trace/src/ci-visibility/requests/request.js +1 -17
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +3 -3
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +23 -5
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +128 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +287 -0
- package/packages/dd-trace/src/config/defaults.js +25 -5
- package/packages/dd-trace/src/config/generated-config-types.d.ts +596 -58
- package/packages/dd-trace/src/config/helper.js +134 -33
- package/packages/dd-trace/src/config/index.js +39 -23
- package/packages/dd-trace/src/config/major-overrides.js +4 -2
- package/packages/dd-trace/src/config/parsers.js +19 -1
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +109 -57
- package/packages/dd-trace/src/constants.js +7 -0
- package/packages/dd-trace/src/datastreams/processor.js +11 -3
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +47 -35
- package/packages/dd-trace/src/debugger/devtools_client/index.js +31 -66
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +83 -0
- package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -0
- package/packages/dd-trace/src/debugger/index.js +5 -0
- package/packages/dd-trace/src/debugger/probe_sampler.js +112 -0
- package/packages/dd-trace/src/debugger/probe_sampler_constants.js +19 -0
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +77 -26
- package/packages/dd-trace/src/exporters/agent/index.js +1 -1
- package/packages/dd-trace/src/exporters/agentless/writer.js +4 -4
- package/packages/dd-trace/src/exporters/common/request.js +1 -20
- package/packages/dd-trace/src/exporters/common/url.js +34 -0
- package/packages/dd-trace/src/exporters/span-stats/writer.js +1 -3
- package/packages/dd-trace/src/guardrails/index.js +8 -5
- package/packages/dd-trace/src/index.js +6 -4
- package/packages/dd-trace/src/llmobs/constants/tags.js +6 -0
- package/packages/dd-trace/src/llmobs/index.js +17 -6
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -4
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +3 -3
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +5 -1
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +8 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +5 -1
- package/packages/dd-trace/src/llmobs/tagger.js +58 -3
- package/packages/dd-trace/src/llmobs/telemetry.js +1 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/log/index.js +18 -20
- package/packages/dd-trace/src/openfeature/flagging_provider.js +2 -7
- package/packages/dd-trace/src/opentelemetry/bridge-span-base.js +5 -4
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +54 -5
- package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +2 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +40 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +169 -0
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +4 -3
- package/packages/dd-trace/src/opentelemetry/metrics/time.js +19 -0
- package/packages/dd-trace/src/opentelemetry/otlp/common.proto +2 -2
- package/packages/dd-trace/src/opentelemetry/otlp/logs.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/logs_service.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/metrics.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/metrics_service.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +44 -38
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +29 -13
- package/packages/dd-trace/src/opentelemetry/span.js +14 -3
- package/packages/dd-trace/src/opentelemetry/span_context.js +1 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +6 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +3 -2
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +26 -13
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +3 -3
- package/packages/dd-trace/src/opentracing/span_context.js +17 -0
- package/packages/dd-trace/src/opentracing/tracer.js +6 -1
- package/packages/dd-trace/src/plugin_manager.js +14 -8
- package/packages/dd-trace/src/plugins/ci_plugin.js +21 -4
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +276 -0
- package/packages/dd-trace/src/plugins/util/llm.js +6 -1
- package/packages/dd-trace/src/plugins/util/test.js +91 -9
- package/packages/dd-trace/src/plugins/util/url.js +68 -1
- package/packages/dd-trace/src/plugins/util/web.js +19 -36
- package/packages/dd-trace/src/priority_sampler.js +1 -13
- package/packages/dd-trace/src/profiling/config.js +129 -198
- package/packages/dd-trace/src/profiling/constants.js +4 -7
- package/packages/dd-trace/src/profiling/exporter_cli.js +10 -10
- package/packages/dd-trace/src/profiling/exporters/agent.js +23 -16
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +45 -14
- package/packages/dd-trace/src/profiling/exporters/file.js +16 -5
- package/packages/dd-trace/src/profiling/oom.js +71 -0
- package/packages/dd-trace/src/profiling/profiler.js +35 -23
- package/packages/dd-trace/src/profiling/profilers/events.js +14 -7
- package/packages/dd-trace/src/profiling/profilers/space.js +27 -18
- package/packages/dd-trace/src/profiling/profilers/wall.js +35 -25
- package/packages/dd-trace/src/proxy.js +8 -8
- package/packages/dd-trace/src/ritm.js +4 -2
- package/packages/dd-trace/src/serverless.js +1 -2
- package/packages/dd-trace/src/service-naming/schemas/util.js +36 -5
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +5 -3
- package/packages/dd-trace/src/span_format.js +2 -1
- package/packages/dd-trace/src/span_processor.js +11 -6
- package/packages/dd-trace/src/span_stats.js +96 -78
- package/packages/dd-trace/src/startup-log.js +2 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +6 -4
- package/packages/dd-trace/src/telemetry/index.js +2 -2
- package/packages/dd-trace/src/telemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/telemetry/send-data.js +20 -18
- package/packages/dd-trace/src/telemetry/session-propagation.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +9 -9
- package/packages/dd-trace/src/tracer.js +15 -1
- package/packages/dd-trace/src/util.js +14 -0
- package/register.js +58 -1
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +1 -1
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/pprof-format/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/shell-quote/index.js +1 -1
- package/packages/datadog-plugin-graphql/src/resolve.js +0 -170
- package/packages/dd-trace/src/appsec/api_security_sampler.js +0 -117
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const path = require('node:path')
|
|
4
|
+
|
|
5
|
+
// Build-time half of the optional-peer mechanism shared by the webpack and esbuild plugins.
|
|
6
|
+
//
|
|
7
|
+
// Runtime files load an optional peer through `requireOptionalPeer('name')` (see
|
|
8
|
+
// `require-optional-peer.js`), which bundlers cannot follow, so a build that does not opt into
|
|
9
|
+
// the feature never pulls in the peer's (possibly optional) dependency chain (#8635). When the
|
|
10
|
+
// peer is installed at build time the user has opted in, so the plugins rewrite the call into a
|
|
11
|
+
// literal `require('name')` and let the bundler inline the peer, which keeps it working after
|
|
12
|
+
// the bundle is relocated to a tree without the peer on disk (#8980). Peers that are absent at
|
|
13
|
+
// build time stay opaque, so the rewrite is a no-op and the #8635 guarantee holds.
|
|
14
|
+
|
|
15
|
+
// Files that load an optional peer this way, as suffixes of the resolved module path. The same
|
|
16
|
+
// suffix matches the repo layout and `node_modules/dd-trace`. Add a file here to extend the
|
|
17
|
+
// mechanism to a new optional peer; no plugin change is needed.
|
|
18
|
+
const OPTIONAL_PEER_FILES = [
|
|
19
|
+
'packages/dd-trace/src/openfeature/flagging_provider.js',
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
// Captures the peer name from `requireOptionalPeer('name')` / `requireOptionalPeer("name")`.
|
|
23
|
+
const OPTIONAL_PEER_LOAD = /requireOptionalPeer\((['"])(.+?)\1\)/g
|
|
24
|
+
|
|
25
|
+
// esbuild's `onLoad` needs a path filter; match the basenames so the callback only fires for
|
|
26
|
+
// the candidate files, then `matchesOptionalPeerFile` confirms the full suffix on a normalized
|
|
27
|
+
// path (basenames carry no separators, so the filter is OS-agnostic).
|
|
28
|
+
const OPTIONAL_PEER_FILTER = new RegExp(
|
|
29
|
+
`(?:${OPTIONAL_PEER_FILES.map((file) => path.basename(file).replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)).join('|')})$`
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {string} normalizedResource - Resolved module path with forward slashes
|
|
34
|
+
* @returns {boolean} Whether the module is one of the optional-peer loader files
|
|
35
|
+
*/
|
|
36
|
+
function matchesOptionalPeerFile (normalizedResource) {
|
|
37
|
+
return OPTIONAL_PEER_FILES.some((suffix) => normalizedResource.endsWith(suffix))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Rewrites each `requireOptionalPeer('name')` whose peer resolves from `fromDir` into a literal
|
|
42
|
+
* `require('name')` so the bundler inlines it. Peers that do not resolve stay opaque, so a build
|
|
43
|
+
* without the peer keeps the #8635 guarantee.
|
|
44
|
+
*
|
|
45
|
+
* @param {string} source - Source of an optional-peer loader file
|
|
46
|
+
* @param {string} fromDir - Directory to resolve the optional peers from
|
|
47
|
+
* @returns {string} Source with installed optional peers turned into literal requires
|
|
48
|
+
*/
|
|
49
|
+
function rewriteOptionalPeerLoads (source, fromDir) {
|
|
50
|
+
return source.replaceAll(OPTIONAL_PEER_LOAD, (match, _quote, request) => {
|
|
51
|
+
try {
|
|
52
|
+
require.resolve(request, { paths: [fromDir] })
|
|
53
|
+
} catch {
|
|
54
|
+
return match
|
|
55
|
+
}
|
|
56
|
+
return `require('${request}')`
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
OPTIONAL_PEER_FILES,
|
|
62
|
+
OPTIONAL_PEER_FILTER,
|
|
63
|
+
matchesOptionalPeerFile,
|
|
64
|
+
rewriteOptionalPeerLoads,
|
|
65
|
+
}
|
|
@@ -13,8 +13,9 @@ const Hook = require('./hook')
|
|
|
13
13
|
const { isRelativeRequire } = require('./shared-utils')
|
|
14
14
|
const rewriter = require('./rewriter')
|
|
15
15
|
|
|
16
|
-
const DD_TRACE_DISABLED_INSTRUMENTATIONS =
|
|
17
|
-
|
|
16
|
+
const DD_TRACE_DISABLED_INSTRUMENTATIONS =
|
|
17
|
+
getValueFromEnvSources('DD_TRACE_DISABLED_INSTRUMENTATIONS')
|
|
18
|
+
const DD_TRACE_DEBUG = getValueFromEnvSources('DD_TRACE_DEBUG')
|
|
18
19
|
|
|
19
20
|
const hooks = require('./hooks')
|
|
20
21
|
const instrumentations = require('./instrumentations')
|
|
@@ -36,8 +37,9 @@ if (!disabledInstrumentations.has('process')) {
|
|
|
36
37
|
require('../process')
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
const debugEnabled = DD_TRACE_DEBUG
|
|
41
|
+
checkRequireCache.checkForRequiredModules()
|
|
42
|
+
if (debugEnabled) {
|
|
41
43
|
setImmediate(checkRequireCache.checkForPotentialConflicts)
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// Loads an optional peer through a require bundlers cannot follow: the package name is an
|
|
4
|
+
// argument, not a `require('literal')`, so a build that does not install the peer never pulls
|
|
5
|
+
// in its (possibly optional) dependency chain (#8635). When the peer is installed at build
|
|
6
|
+
// time, the webpack and esbuild plugins rewrite `requireOptionalPeer('name')` into a literal
|
|
7
|
+
// `require('name')` so the peer is bundled and survives the bundle being relocated without it
|
|
8
|
+
// on disk (#8980). See `optional-peer-bundler.js` for the build-time half.
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {string} request - Module specifier of the optional peer
|
|
12
|
+
*/
|
|
13
|
+
module.exports = function requireOptionalPeer (request) {
|
|
14
|
+
// eslint-disable-next-line camelcase, no-undef
|
|
15
|
+
const runtimeRequire = typeof __non_webpack_require__ === 'function' ? __non_webpack_require__ : require
|
|
16
|
+
return runtimeRequire(request)
|
|
17
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = [
|
|
4
|
+
{
|
|
5
|
+
module: {
|
|
6
|
+
name: 'graphql',
|
|
7
|
+
versionRange: '>=0.10',
|
|
8
|
+
filePath: 'execution/execute.js',
|
|
9
|
+
},
|
|
10
|
+
functionQuery: {
|
|
11
|
+
functionName: 'execute',
|
|
12
|
+
kind: 'Sync',
|
|
13
|
+
},
|
|
14
|
+
channelName: 'apm:graphql:execute',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
module: {
|
|
18
|
+
name: 'graphql',
|
|
19
|
+
versionRange: '>=0.10',
|
|
20
|
+
filePath: 'execution/execute.mjs',
|
|
21
|
+
},
|
|
22
|
+
functionQuery: {
|
|
23
|
+
functionName: 'execute',
|
|
24
|
+
kind: 'Sync',
|
|
25
|
+
},
|
|
26
|
+
channelName: 'apm:graphql:execute',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
module: {
|
|
30
|
+
name: 'graphql',
|
|
31
|
+
versionRange: '>=0.10',
|
|
32
|
+
filePath: 'language/parser.js',
|
|
33
|
+
},
|
|
34
|
+
functionQuery: {
|
|
35
|
+
functionName: 'parse',
|
|
36
|
+
kind: 'Sync',
|
|
37
|
+
},
|
|
38
|
+
channelName: 'apm:graphql:parser',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
module: {
|
|
42
|
+
name: 'graphql',
|
|
43
|
+
versionRange: '>=0.10',
|
|
44
|
+
filePath: 'language/parser.mjs',
|
|
45
|
+
},
|
|
46
|
+
functionQuery: {
|
|
47
|
+
functionName: 'parse',
|
|
48
|
+
kind: 'Sync',
|
|
49
|
+
},
|
|
50
|
+
channelName: 'apm:graphql:parser',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
module: {
|
|
54
|
+
name: 'graphql',
|
|
55
|
+
versionRange: '>=0.10',
|
|
56
|
+
filePath: 'validation/validate.js',
|
|
57
|
+
},
|
|
58
|
+
functionQuery: {
|
|
59
|
+
functionName: 'validate',
|
|
60
|
+
kind: 'Sync',
|
|
61
|
+
},
|
|
62
|
+
channelName: 'apm:graphql:validate',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
module: {
|
|
66
|
+
name: 'graphql',
|
|
67
|
+
versionRange: '>=0.10',
|
|
68
|
+
filePath: 'validation/validate.mjs',
|
|
69
|
+
},
|
|
70
|
+
functionQuery: {
|
|
71
|
+
functionName: 'validate',
|
|
72
|
+
kind: 'Sync',
|
|
73
|
+
},
|
|
74
|
+
channelName: 'apm:graphql:validate',
|
|
75
|
+
},
|
|
76
|
+
// executeField / resolveField intentionally NOT instrumented here. Resolve spans
|
|
77
|
+
// are produced by wrapping user resolvers + the default field resolver at execute
|
|
78
|
+
// time (see packages/datadog-plugin-graphql/src/execute.js). That gives a zero-cost
|
|
79
|
+
// fast path when no subscribers are active, which per-field orchestrion hooks
|
|
80
|
+
// cannot offer (the publish is baked into graphql's compiled code).
|
|
81
|
+
{
|
|
82
|
+
module: {
|
|
83
|
+
name: '@graphql-tools/executor',
|
|
84
|
+
versionRange: '>=0.0.14',
|
|
85
|
+
filePath: 'cjs/execution/execute.js',
|
|
86
|
+
},
|
|
87
|
+
functionQuery: {
|
|
88
|
+
functionName: 'execute',
|
|
89
|
+
kind: 'Sync',
|
|
90
|
+
},
|
|
91
|
+
channelName: 'apm:graphql:execute',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
module: {
|
|
95
|
+
name: '@graphql-tools/executor',
|
|
96
|
+
versionRange: '>=0.0.14',
|
|
97
|
+
filePath: 'esm/execution/execute.js',
|
|
98
|
+
},
|
|
99
|
+
functionQuery: {
|
|
100
|
+
functionName: 'execute',
|
|
101
|
+
kind: 'Sync',
|
|
102
|
+
},
|
|
103
|
+
channelName: 'apm:graphql:execute',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
module: {
|
|
107
|
+
name: '@graphql-tools/executor',
|
|
108
|
+
versionRange: '>=0.0.14',
|
|
109
|
+
filePath: 'cjs/execution/normalizedExecutor.js',
|
|
110
|
+
},
|
|
111
|
+
functionQuery: {
|
|
112
|
+
functionName: 'normalizedExecutor',
|
|
113
|
+
kind: 'Sync',
|
|
114
|
+
},
|
|
115
|
+
channelName: 'apm:graphql:execute',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
module: {
|
|
119
|
+
name: '@graphql-tools/executor',
|
|
120
|
+
versionRange: '>=0.0.14',
|
|
121
|
+
filePath: 'esm/execution/normalizedExecutor.js',
|
|
122
|
+
},
|
|
123
|
+
functionQuery: {
|
|
124
|
+
functionName: 'normalizedExecutor',
|
|
125
|
+
kind: 'Sync',
|
|
126
|
+
},
|
|
127
|
+
channelName: 'apm:graphql:execute',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
module: {
|
|
131
|
+
name: 'graphql',
|
|
132
|
+
versionRange: '>=0.10',
|
|
133
|
+
filePath: 'language/printer.js',
|
|
134
|
+
},
|
|
135
|
+
functionQuery: {
|
|
136
|
+
functionName: '__module_export__',
|
|
137
|
+
kind: 'Sync',
|
|
138
|
+
},
|
|
139
|
+
channelName: 'dd:graphql:printer:load',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
module: {
|
|
143
|
+
name: 'graphql',
|
|
144
|
+
versionRange: '>=0.10',
|
|
145
|
+
filePath: 'language/printer.mjs',
|
|
146
|
+
},
|
|
147
|
+
functionQuery: {
|
|
148
|
+
functionName: '__module_export__',
|
|
149
|
+
kind: 'Sync',
|
|
150
|
+
},
|
|
151
|
+
channelName: 'dd:graphql:printer:load',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
module: {
|
|
155
|
+
name: 'graphql',
|
|
156
|
+
versionRange: '>=0.10',
|
|
157
|
+
filePath: 'language/visitor.js',
|
|
158
|
+
},
|
|
159
|
+
functionQuery: {
|
|
160
|
+
functionName: '__module_export__',
|
|
161
|
+
kind: 'Sync',
|
|
162
|
+
},
|
|
163
|
+
channelName: 'dd:graphql:visitor:load',
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
module: {
|
|
167
|
+
name: 'graphql',
|
|
168
|
+
versionRange: '>=0.10',
|
|
169
|
+
filePath: 'language/visitor.mjs',
|
|
170
|
+
},
|
|
171
|
+
functionQuery: {
|
|
172
|
+
functionName: '__module_export__',
|
|
173
|
+
kind: 'Sync',
|
|
174
|
+
},
|
|
175
|
+
channelName: 'dd:graphql:visitor:load',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
module: {
|
|
179
|
+
name: 'graphql',
|
|
180
|
+
versionRange: '>=0.10',
|
|
181
|
+
filePath: 'utilities/index.js',
|
|
182
|
+
},
|
|
183
|
+
functionQuery: {
|
|
184
|
+
functionName: '__module_export__',
|
|
185
|
+
kind: 'Sync',
|
|
186
|
+
},
|
|
187
|
+
channelName: 'dd:graphql:utilities:load',
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
module: {
|
|
191
|
+
name: 'graphql',
|
|
192
|
+
versionRange: '>=0.10',
|
|
193
|
+
filePath: 'utilities/index.mjs',
|
|
194
|
+
},
|
|
195
|
+
functionQuery: {
|
|
196
|
+
functionName: '__module_export__',
|
|
197
|
+
kind: 'Sync',
|
|
198
|
+
},
|
|
199
|
+
channelName: 'dd:graphql:utilities:load',
|
|
200
|
+
},
|
|
201
|
+
]
|
|
@@ -3,9 +3,25 @@ import { rewrite } from './index.js'
|
|
|
3
3
|
async function load (url, context, nextLoad) {
|
|
4
4
|
const result = await nextLoad(url, context)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
return rewriteResult(result, url, context)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function loadSync (url, context, nextLoad) {
|
|
10
|
+
const result = nextLoad(url, context)
|
|
11
|
+
|
|
12
|
+
return rewriteResult(result, url, context)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function rewriteResult (result, url, context) {
|
|
16
|
+
const format = result.format || context.format
|
|
17
|
+
|
|
18
|
+
// CommonJS source is rewritten by Module._compile. Rewriting it here too
|
|
19
|
+
// double-instruments CommonJS entrypoints loaded through sync hooks.
|
|
20
|
+
if (format === 'commonjs') return result
|
|
21
|
+
|
|
22
|
+
result.source = rewrite(result.source, url, format)
|
|
7
23
|
|
|
8
24
|
return result
|
|
9
25
|
}
|
|
10
26
|
|
|
11
|
-
export { load }
|
|
27
|
+
export { load, loadSync }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
|
-
const { addHook, channel } = require('./helpers/instrument')
|
|
4
|
+
const { addHook, channel, createErrorPublisher } = require('./helpers/instrument')
|
|
5
5
|
|
|
6
6
|
const enterChannel = channel('apm:koa:middleware:enter')
|
|
7
7
|
const exitChannel = channel('apm:koa:middleware:exit')
|
|
@@ -10,6 +10,7 @@ const nextChannel = channel('apm:koa:middleware:next')
|
|
|
10
10
|
const finishChannel = channel('apm:koa:middleware:finish')
|
|
11
11
|
const handleChannel = channel('apm:koa:request:handle')
|
|
12
12
|
const routeChannel = channel('apm:koa:request:route')
|
|
13
|
+
const publishError = createErrorPublisher(errorChannel)
|
|
13
14
|
|
|
14
15
|
const originals = new WeakMap()
|
|
15
16
|
|
|
@@ -132,7 +133,7 @@ function fulfill (ctx, error) {
|
|
|
132
133
|
const route = ctx.routePath
|
|
133
134
|
|
|
134
135
|
if (error) {
|
|
135
|
-
|
|
136
|
+
publishError({ req, error })
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
// TODO: make sure that the parent class cannot override this in `enter`
|
|
@@ -160,14 +160,16 @@ addHook({ name, file: 'lib/cmd/execute.js', versions: ['>=3'] }, (Execute) => {
|
|
|
160
160
|
return wrapCommand(Execute)
|
|
161
161
|
})
|
|
162
162
|
|
|
163
|
-
//
|
|
163
|
+
// mariadb 3.4.1 refactored the pool: getConnection switched from promises to
|
|
164
|
+
// callbacks and _createConnection was renamed to _createPoolConnection.
|
|
164
165
|
addHook({ name, file: 'lib/pool.js', versions: ['>=3.4.1'] }, (Pool) => {
|
|
165
166
|
shimmer.wrap(Pool.prototype, 'getConnection', wrapPoolGetConnectionMethod)
|
|
167
|
+
shimmer.wrap(Pool.prototype, '_createPoolConnection', wrapPoolMethod)
|
|
166
168
|
|
|
167
169
|
return Pool
|
|
168
170
|
})
|
|
169
171
|
|
|
170
|
-
addHook({ name, file: 'lib/pool.js', versions: ['>=3'] }, (Pool) => {
|
|
172
|
+
addHook({ name, file: 'lib/pool.js', versions: ['>=3 <3.4.1'] }, (Pool) => {
|
|
171
173
|
shimmer.wrap(Pool.prototype, '_createConnection', wrapPoolMethod)
|
|
172
174
|
|
|
173
175
|
return Pool
|
|
@@ -1093,9 +1093,9 @@ addHook({
|
|
|
1093
1093
|
shimmer.wrap(BufferedWorkerPool.prototype, 'run', run => async function (testSuiteAbsolutePath, workerArgs) {
|
|
1094
1094
|
if (!testFinishCh.hasSubscribers ||
|
|
1095
1095
|
(!config.isKnownTestsEnabled &&
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1096
|
+
!config.isTestManagementTestsEnabled &&
|
|
1097
|
+
!config.isImpactedTestsEnabled &&
|
|
1098
|
+
!config.isFlakyTestRetriesEnabled)) {
|
|
1099
1099
|
return run.apply(this, arguments)
|
|
1100
1100
|
}
|
|
1101
1101
|
|
|
@@ -6,6 +6,12 @@ const { wrapThen } = require('./helpers/promise')
|
|
|
6
6
|
|
|
7
7
|
const startCh = channel('datadog:mongoose:model:filter:start')
|
|
8
8
|
const finishCh = channel('datadog:mongoose:model:filter:finish')
|
|
9
|
+
// Bound around the deferred query execution. A subscriber returns the store that
|
|
10
|
+
// stays active for the whole async scope that reaches the mongodb driver, so the
|
|
11
|
+
// nested driver query can see the parent's analysis marker without it leaking
|
|
12
|
+
// past the query. `runStores` enters the store only for that scope and restores
|
|
13
|
+
// the parent on its own.
|
|
14
|
+
const execCh = channel('datadog:mongoose:model:filter:exec')
|
|
9
15
|
// this channel is for wrapping the callback of exec methods and handling store context
|
|
10
16
|
const execStartCh = channel('apm:mongoose:exec:start')
|
|
11
17
|
const execFinishCh = channel('apm:mongoose:exec:finish')
|
|
@@ -103,7 +109,13 @@ addHook({
|
|
|
103
109
|
return startCh.runStores(ctx, () => {
|
|
104
110
|
wrapCallbackIfExist(args, ctx)
|
|
105
111
|
|
|
106
|
-
|
|
112
|
+
// A callback query executes synchronously inside `method.apply`, so the
|
|
113
|
+
// exec scope (and the deferred driver call it spawns) must be entered
|
|
114
|
+
// here. A promise query defers execution to a later `exec`/`then`, which
|
|
115
|
+
// is bound separately below.
|
|
116
|
+
const res = callbackWrapped
|
|
117
|
+
? execCh.runStores(ctx, () => method.apply(this, args))
|
|
118
|
+
: method.apply(this, args)
|
|
107
119
|
|
|
108
120
|
// if it is not callback, wrap exec method and its then
|
|
109
121
|
if (!callbackWrapped) {
|
|
@@ -113,7 +125,7 @@ addHook({
|
|
|
113
125
|
wrapCallbackIfExist(args, ctx)
|
|
114
126
|
}
|
|
115
127
|
|
|
116
|
-
const execResult = originalExec.apply(this, args)
|
|
128
|
+
const execResult = execCh.runStores(ctx, () => originalExec.apply(this, args))
|
|
117
129
|
|
|
118
130
|
if (callbackWrapped || typeof execResult?.then !== 'function') {
|
|
119
131
|
return execResult
|
|
@@ -141,19 +141,19 @@ function instrument (req, res, handler, error) {
|
|
|
141
141
|
requests.add(req)
|
|
142
142
|
|
|
143
143
|
const ctx = { req, res }
|
|
144
|
-
// Parse query parameters from request URL
|
|
145
144
|
if (queryParsedChannel.hasSubscribers && req.url) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
145
|
+
const queryIndex = req.url.indexOf('?')
|
|
146
|
+
if (queryIndex !== -1) {
|
|
147
|
+
const searchParams = new URLSearchParams(req.url.slice(queryIndex + 1))
|
|
148
|
+
const query = {}
|
|
149
|
+
for (const key of searchParams.keys()) {
|
|
150
|
+
if (!query[key]) {
|
|
151
|
+
query[key] = searchParams.getAll(key)
|
|
152
|
+
}
|
|
153
153
|
}
|
|
154
|
-
}
|
|
155
154
|
|
|
156
|
-
|
|
155
|
+
queryParsedChannel.publish({ query })
|
|
156
|
+
}
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
return startChannel.runStores(ctx, () => {
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
4
|
const tracer = require('../../dd-trace')
|
|
5
5
|
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
6
|
-
const { isFalse, isTrue } = require('../../dd-trace/src/util')
|
|
7
6
|
const { addHook } = require('./helpers/instrument')
|
|
8
7
|
|
|
9
8
|
if (isOtelSdkEnabled()) {
|
|
@@ -21,9 +20,11 @@ if (isOtelSdkEnabled()) {
|
|
|
21
20
|
|
|
22
21
|
function isOtelSdkEnabled () {
|
|
23
22
|
// Datadog explicit opt-out wins over every OTel signal; check it first.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
|
|
23
|
+
// skipDefault: an unset option must stay undefined so the OTel signal still decides — the
|
|
24
|
+
// registered defaults (false / true) would otherwise force-disable before that check.
|
|
25
|
+
const ddTraceOtelEnabled = getValueFromEnvSources('DD_TRACE_OTEL_ENABLED', true)
|
|
26
|
+
if (ddTraceOtelEnabled === false) return false
|
|
27
|
+
const otelSdkDisabled = getValueFromEnvSources('OTEL_SDK_DISABLED', true)
|
|
28
|
+
if (otelSdkDisabled) return false
|
|
29
|
+
return ddTraceOtelEnabled || otelSdkDisabled === false
|
|
29
30
|
}
|
|
@@ -59,7 +59,7 @@ const testSuiteToTestStatuses = new Map()
|
|
|
59
59
|
const testSuiteToErrors = new Map()
|
|
60
60
|
const testsToTestStatuses = new Map()
|
|
61
61
|
|
|
62
|
-
const RUM_FLUSH_WAIT_TIME =
|
|
62
|
+
const RUM_FLUSH_WAIT_TIME = getValueFromEnvSources('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')
|
|
63
63
|
const DD_PROPERTIES_TIMEOUT = 5000
|
|
64
64
|
|
|
65
65
|
let applyRepeatEachIndex = null
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
|
-
const { addHook, channel } = require('./helpers/instrument')
|
|
4
|
+
const { addHook, channel, createErrorPublisher } = require('./helpers/instrument')
|
|
5
5
|
const handlers = ['use', 'pre']
|
|
6
6
|
const methods = ['del', 'get', 'head', 'opts', 'post', 'put', 'patch']
|
|
7
7
|
|
|
@@ -11,6 +11,7 @@ const enterChannel = channel('apm:restify:middleware:enter')
|
|
|
11
11
|
const exitChannel = channel('apm:restify:middleware:exit')
|
|
12
12
|
const finishChannel = channel('apm:restify:middleware:finish')
|
|
13
13
|
const nextChannel = channel('apm:restify:middleware:next')
|
|
14
|
+
const publishError = createErrorPublisher(errorChannel)
|
|
14
15
|
|
|
15
16
|
function wrapSetupRequest (setupRequest) {
|
|
16
17
|
return function (req, res) {
|
|
@@ -53,7 +54,7 @@ function wrapFn (fn) {
|
|
|
53
54
|
finishChannel.publish({ req })
|
|
54
55
|
return result
|
|
55
56
|
}).catch(function (error) {
|
|
56
|
-
|
|
57
|
+
publishError({ req, error })
|
|
57
58
|
nextChannel.publish({ req })
|
|
58
59
|
finishChannel.publish({ req })
|
|
59
60
|
throw error
|
|
@@ -61,7 +62,7 @@ function wrapFn (fn) {
|
|
|
61
62
|
}
|
|
62
63
|
return result
|
|
63
64
|
} catch (error) {
|
|
64
|
-
|
|
65
|
+
publishError({ req, error })
|
|
65
66
|
nextChannel.publish({ req })
|
|
66
67
|
finishChannel.publish({ req })
|
|
67
68
|
throw error
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const METHODS = [...require('http').METHODS.map(v => v.toLowerCase()), 'all']
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
|
-
const { addHook, channel } = require('./helpers/instrument')
|
|
5
|
+
const { addHook, channel, createErrorPublisher } = require('./helpers/instrument')
|
|
6
6
|
const { getCompileToRegexp } = require('./path-to-regexp')
|
|
7
7
|
|
|
8
8
|
const {
|
|
@@ -40,6 +40,8 @@ function createWrapRouterMethod (name, compile) {
|
|
|
40
40
|
const errorChannel = channel(`apm:${name}:middleware:error`)
|
|
41
41
|
const nextChannel = channel(`apm:${name}:middleware:next`)
|
|
42
42
|
const routeAddedChannel = channel(`apm:${name}:route:added`)
|
|
43
|
+
// Bound per name so express and a bare router keep independent guards.
|
|
44
|
+
const publishError = createErrorPublisher(errorChannel)
|
|
43
45
|
|
|
44
46
|
function wrapLayerHandle (layer, original, matchers) {
|
|
45
47
|
// Resolve `name` once at wrap time: cached on the original for any code
|
|
@@ -65,9 +67,20 @@ function createWrapRouterMethod (name, compile) {
|
|
|
65
67
|
// `Layer.handleError`. Specialising lets the per-call body use named
|
|
66
68
|
// parameters and `.call`, avoiding the rest-spread Array allocation that
|
|
67
69
|
// the unified shape forced on every middleware invocation.
|
|
68
|
-
|
|
70
|
+
const wrapped = original.length === 4
|
|
69
71
|
? shimmer.wrapFunction(original, errorHandlerLayerWrap(layer, name, captureRoute, needMultiMatch, matchers))
|
|
70
72
|
: shimmer.wrapFunction(original, requestHandlerLayerWrap(layer, name, captureRoute, needMultiMatch, matchers))
|
|
73
|
+
|
|
74
|
+
// Workaround for loopback's phase-based middleware sorting. Its
|
|
75
|
+
// `_findLayerByHandler` maps a layer back to the user handler by scanning
|
|
76
|
+
// the layer handle's enumerable properties for the original function.
|
|
77
|
+
// Replacing `layer.handle` with this wrapper hides that handler, so without
|
|
78
|
+
// the back-reference loopback cannot tag the layer with its phase and
|
|
79
|
+
// `app.middleware(phase, ...)` handlers run in insertion order instead of
|
|
80
|
+
// phase order. The property name is part of that contract; keep it stable.
|
|
81
|
+
wrapped._datadog_orig = original
|
|
82
|
+
|
|
83
|
+
return wrapped
|
|
71
84
|
}
|
|
72
85
|
|
|
73
86
|
function requestHandlerLayerWrap (layer, name, captureRoute, needMultiMatch, matchers) {
|
|
@@ -91,7 +104,7 @@ function createWrapRouterMethod (name, compile) {
|
|
|
91
104
|
try {
|
|
92
105
|
return original.call(this, req, res, wrappedNext)
|
|
93
106
|
} catch (error) {
|
|
94
|
-
|
|
107
|
+
publishError({ req, error })
|
|
95
108
|
nextChannel.publish({ req })
|
|
96
109
|
finishChannel.publish({ req })
|
|
97
110
|
|
|
@@ -123,7 +136,7 @@ function createWrapRouterMethod (name, compile) {
|
|
|
123
136
|
try {
|
|
124
137
|
return original.call(this, error, req, res, wrappedNext)
|
|
125
138
|
} catch (caught) {
|
|
126
|
-
|
|
139
|
+
publishError({ req, error: caught })
|
|
127
140
|
nextChannel.publish({ req })
|
|
128
141
|
finishChannel.publish({ req })
|
|
129
142
|
|
|
@@ -161,7 +174,7 @@ function createWrapRouterMethod (name, compile) {
|
|
|
161
174
|
// router continuation so wrapCallback skips its name/length rewrite.
|
|
162
175
|
return shimmer.wrapCallback(originalNext, original => function next (error) {
|
|
163
176
|
if (error && error !== 'route' && error !== 'router') {
|
|
164
|
-
|
|
177
|
+
publishError({ req, error })
|
|
165
178
|
}
|
|
166
179
|
|
|
167
180
|
nextChannel.publish({ req })
|
|
@@ -19,8 +19,7 @@ if (window.DD_RUM && window.DD_RUM.stopSession) {
|
|
|
19
19
|
`
|
|
20
20
|
const IS_RUM_ACTIVE_SCRIPT = 'return !!window.DD_RUM'
|
|
21
21
|
|
|
22
|
-
const DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS =
|
|
23
|
-
Number(getValueFromEnvSources('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')) || 500
|
|
22
|
+
const DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS = getValueFromEnvSources('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')
|
|
24
23
|
const DD_CIVISIBILITY_TEST_EXECUTION_ID_COOKIE_NAME = 'datadog-ci-visibility-test-execution-id'
|
|
25
24
|
|
|
26
25
|
// TODO: can we increase the supported version range?
|
|
@@ -4,12 +4,40 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
4
4
|
const {
|
|
5
5
|
channel,
|
|
6
6
|
addHook,
|
|
7
|
+
AsyncResource,
|
|
7
8
|
} = require('./helpers/instrument')
|
|
8
9
|
|
|
10
|
+
// Listeners added to the BulkLoad row stream (`bulkLoad.getRowStream()`) by the caller would
|
|
11
|
+
// otherwise run in whatever async context emits the stream event, losing the span that was active
|
|
12
|
+
// when the listener was registered. Bind each registered listener to its registration context so
|
|
13
|
+
// `'finish'`/`'error'`/`'data'` handlers run in the caller's span, as they did before the tracer
|
|
14
|
+
// moved to AsyncLocalStorage. tedious' own internal listeners are attached before `getRowStream`
|
|
15
|
+
// returns, so only caller listeners are bound.
|
|
16
|
+
const ROW_STREAM_LISTENER_METHODS = ['addListener', 'on', 'once', 'prependListener', 'prependOnceListener']
|
|
17
|
+
|
|
18
|
+
function bindRowStreamListeners (rowStream) {
|
|
19
|
+
for (const method of ROW_STREAM_LISTENER_METHODS) {
|
|
20
|
+
shimmer.wrap(rowStream, method, register => function (eventName, listener) {
|
|
21
|
+
if (typeof listener !== 'function') {
|
|
22
|
+
return register.apply(this, arguments)
|
|
23
|
+
}
|
|
24
|
+
return register.call(this, eventName, AsyncResource.bind(listener))
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
return rowStream
|
|
28
|
+
}
|
|
29
|
+
|
|
9
30
|
addHook({ name: 'tedious', versions: ['>=1.0.0'] }, tedious => {
|
|
10
31
|
const startCh = channel('apm:tedious:request:start')
|
|
11
32
|
const finishCh = channel('apm:tedious:request:finish')
|
|
12
33
|
const errorCh = channel('apm:tedious:request:error')
|
|
34
|
+
|
|
35
|
+
if (typeof tedious.BulkLoad?.prototype?.getRowStream === 'function') {
|
|
36
|
+
shimmer.wrap(tedious.BulkLoad.prototype, 'getRowStream', getRowStream => function () {
|
|
37
|
+
return bindRowStreamListeners(getRowStream.apply(this, arguments))
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
13
41
|
shimmer.wrap(tedious.Connection.prototype, 'makeRequest', makeRequest => function (request) {
|
|
14
42
|
if (!startCh.hasSubscribers) {
|
|
15
43
|
return makeRequest.apply(this, arguments)
|