dd-trace 5.110.0 → 5.112.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 -2
- package/README.md +13 -8
- package/ci/init.js +21 -2
- package/ci/vitest-no-worker-init-setup.mjs +430 -0
- package/ext/tags.js +2 -0
- package/index.d.ts +34 -1
- package/initialize.mjs +5 -6
- package/loader-hook.mjs +76 -55
- package/package.json +37 -34
- package/packages/datadog-instrumentations/src/ai.js +45 -0
- package/packages/datadog-instrumentations/src/apollo-server.js +5 -13
- package/packages/datadog-instrumentations/src/child_process.js +3 -3
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +587 -0
- package/packages/datadog-instrumentations/src/cucumber.js +102 -43
- package/packages/datadog-instrumentations/src/cypress-config.js +11 -3
- package/packages/datadog-instrumentations/src/fastify.js +27 -8
- package/packages/datadog-instrumentations/src/fs.js +8 -6
- package/packages/datadog-instrumentations/src/graphql.js +26 -495
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +7 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +6 -6
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/claude-agent-sdk.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 +2 -0
- package/packages/datadog-instrumentations/src/jest.js +713 -63
- package/packages/datadog-instrumentations/src/mocha/main.js +24 -3
- package/packages/datadog-instrumentations/src/mocha/utils.js +128 -22
- package/packages/datadog-instrumentations/src/mocha/worker.js +13 -0
- package/packages/datadog-instrumentations/src/mongodb.js +74 -0
- package/packages/datadog-instrumentations/src/mongoose.js +13 -2
- package/packages/datadog-instrumentations/src/playwright.js +13 -9
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +1297 -0
- package/packages/datadog-instrumentations/src/vitest-main.js +1594 -0
- package/packages/datadog-instrumentations/src/vitest-util.js +254 -0
- package/packages/datadog-instrumentations/src/vitest-worker.js +823 -0
- package/packages/datadog-instrumentations/src/vitest.js +11 -1855
- package/packages/datadog-plugin-ai/src/index.js +1 -1
- package/packages/datadog-plugin-ai/src/tracing.js +66 -3
- package/packages/datadog-plugin-ai/src/utils.js +17 -4
- 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 +19 -10
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +1 -0
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +47 -11
- package/packages/datadog-plugin-child_process/src/index.js +13 -2
- package/packages/datadog-plugin-claude-agent-sdk/src/index.js +31 -0
- package/packages/datadog-plugin-claude-agent-sdk/src/tracing.js +107 -0
- package/packages/datadog-plugin-claude-agent-sdk/src/util.js +15 -0
- package/packages/datadog-plugin-cucumber/src/index.js +15 -24
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +360 -14
- package/packages/datadog-plugin-cypress/src/index.js +47 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +1 -0
- 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 +639 -12
- package/packages/datadog-plugin-graphql/src/index.js +37 -9
- package/packages/datadog-plugin-graphql/src/parse.js +24 -4
- package/packages/datadog-plugin-graphql/src/utils.js +9 -2
- package/packages/datadog-plugin-graphql/src/validate.js +17 -6
- package/packages/datadog-plugin-http/src/index.js +6 -8
- package/packages/datadog-plugin-jest/src/index.js +31 -15
- package/packages/datadog-plugin-mocha/src/index.js +40 -15
- package/packages/datadog-plugin-mongodb-core/src/bulk-write.js +43 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +8 -443
- package/packages/datadog-plugin-mongodb-core/src/query.js +452 -0
- package/packages/datadog-plugin-openai/src/services.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +4 -3
- package/packages/datadog-plugin-vitest/src/index.js +120 -72
- package/packages/datadog-shimmer/src/shimmer.js +37 -16
- package/packages/dd-trace/src/aiguard/index.js +9 -14
- package/packages/dd-trace/src/aiguard/integrations/index.js +34 -0
- package/packages/dd-trace/src/aiguard/integrations/openai.js +47 -33
- package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +42 -28
- package/packages/dd-trace/src/aiguard/sdk.js +2 -2
- package/packages/dd-trace/src/appsec/api_security/sampler.js +3 -3
- 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 +14 -11
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +23 -23
- 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 +10 -1
- package/packages/dd-trace/src/appsec/lambda.js +135 -0
- package/packages/dd-trace/src/appsec/reporter.js +49 -10
- package/packages/dd-trace/src/appsec/telemetry/index.js +1 -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/dynamic-instrumentation/index.js +26 -1
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +115 -24
- 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 +5 -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 +6 -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 +130 -20
- 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/upload-coverage-report.js +3 -3
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +156 -0
- 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 +3 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +71 -57
- package/packages/dd-trace/src/config/helper.js +1 -0
- package/packages/dd-trace/src/config/index.js +35 -22
- package/packages/dd-trace/src/config/major-overrides.js +4 -2
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +127 -56
- package/packages/dd-trace/src/constants.js +7 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +2 -2
- package/packages/dd-trace/src/datastreams/processor.js +11 -3
- 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/llmobs/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +403 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +8 -395
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +27 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +363 -0
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -4
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +270 -0
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/utils.js +10 -0
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +3 -3
- package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +3 -3
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +54 -5
- 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/otlp/otlp_http_exporter_base.js +38 -39
- package/packages/dd-trace/src/opentelemetry/span.js +5 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +4 -0
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
- package/packages/dd-trace/src/opentracing/tracer.js +6 -1
- package/packages/dd-trace/src/plugin_manager.js +23 -7
- package/packages/dd-trace/src/plugins/ci_plugin.js +159 -10
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/util/llm.js +6 -1
- package/packages/dd-trace/src/plugins/util/test.js +15 -9
- package/packages/dd-trace/src/profiling/exporter_cli.js +2 -2
- package/packages/dd-trace/src/profiling/exporters/agent.js +28 -3
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +1 -1
- package/packages/dd-trace/src/proxy.js +8 -8
- package/packages/dd-trace/src/span_processor.js +5 -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 +8 -8
- package/packages/dd-trace/src/telemetry/session-propagation.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +9 -9
- package/vendor/dist/@datadog/sketches-js/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
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const pick = require('../../datadog-core/src/utils/src/pick')
|
|
4
|
+
const { DD_MAJOR } = require('../../../version')
|
|
4
5
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
5
6
|
const log = require('../../dd-trace/src/log')
|
|
6
7
|
const GraphQLExecutePlugin = require('./execute')
|
|
7
8
|
const GraphQLParsePlugin = require('./parse')
|
|
8
9
|
const GraphQLValidatePlugin = require('./validate')
|
|
9
|
-
const GraphQLResolvePlugin = require('./resolve')
|
|
10
10
|
|
|
11
11
|
class GraphQLPlugin extends CompositePlugin {
|
|
12
12
|
static id = 'graphql'
|
|
@@ -15,7 +15,9 @@ class GraphQLPlugin extends CompositePlugin {
|
|
|
15
15
|
execute: GraphQLExecutePlugin,
|
|
16
16
|
parse: GraphQLParsePlugin,
|
|
17
17
|
validate: GraphQLValidatePlugin,
|
|
18
|
-
resolve:
|
|
18
|
+
// resolve plugin is absorbed into execute: per-field data is recorded
|
|
19
|
+
// synchronously in wrapResolve, and all graphql.resolve spans are
|
|
20
|
+
// materialized at execute end.
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
|
|
@@ -28,13 +30,25 @@ class GraphQLPlugin extends CompositePlugin {
|
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
// config validator helpers
|
|
33
|
+
//
|
|
34
|
+
// `collapse`, `depth`, `variables`, and `errorExtensions` arrive pre-merged on
|
|
35
|
+
// `config`: plugin_manager seeds the `DD_TRACE_GRAPHQL_*` env values (already
|
|
36
|
+
// parsed to their declared type) as the base and a programmatic
|
|
37
|
+
// `tracer.use('graphql', …)` value overrides them. So these helpers only shape
|
|
38
|
+
// the merged value — coerce, validate, and turn `variables` into a filter — and
|
|
39
|
+
// never read the environment themselves.
|
|
31
40
|
|
|
32
41
|
function validateConfig (config) {
|
|
42
|
+
const collapse = config.collapse === undefined || !!config.collapse
|
|
33
43
|
return {
|
|
34
44
|
...config,
|
|
35
45
|
depth: getDepth(config),
|
|
36
46
|
variables: getVariablesFilter(config),
|
|
37
|
-
collapse
|
|
47
|
+
collapse,
|
|
48
|
+
// v5 counted collapsed list indices toward `depth`, so the same query reached a
|
|
49
|
+
// different depth depending on `collapse`. v6 counts selection-set depth only.
|
|
50
|
+
countListIndices: DD_MAJOR < 6 && collapse,
|
|
51
|
+
errorExtensions: getErrorExtensions(config),
|
|
38
52
|
hooks: getHooks(config),
|
|
39
53
|
}
|
|
40
54
|
}
|
|
@@ -52,21 +66,35 @@ function getVariablesFilter (config) {
|
|
|
52
66
|
if (typeof config.variables === 'function') {
|
|
53
67
|
return config.variables
|
|
54
68
|
} else if (Array.isArray(config.variables)) {
|
|
55
|
-
return variables => pick(variables, config.variables)
|
|
69
|
+
return config.variables.length > 0 ? variables => pick(variables, config.variables) : null
|
|
56
70
|
} else if (config.hasOwnProperty('variables')) {
|
|
57
71
|
log.error('Expected `variables` to be an array or function.')
|
|
58
72
|
}
|
|
59
73
|
return null
|
|
60
74
|
}
|
|
61
75
|
|
|
76
|
+
function getErrorExtensions (config) {
|
|
77
|
+
if (Array.isArray(config.errorExtensions)) {
|
|
78
|
+
return config.errorExtensions.length > 0 ? config.errorExtensions : undefined
|
|
79
|
+
} else if (config.hasOwnProperty('errorExtensions')) {
|
|
80
|
+
log.error('Expected `errorExtensions` to be an array.')
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
62
84
|
const noop = () => {}
|
|
85
|
+
const noopHooks = { execute: noop, parse: noop, validate: noop, resolve: undefined }
|
|
63
86
|
|
|
64
87
|
function getHooks ({ hooks }) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
88
|
+
if (!hooks) return noopHooks
|
|
89
|
+
return {
|
|
90
|
+
execute: hooks.execute ?? noop,
|
|
91
|
+
parse: hooks.parse ?? noop,
|
|
92
|
+
validate: hooks.validate ?? noop,
|
|
93
|
+
// No noop fallback: `resolve` runs per-field (hot path); the plugin
|
|
94
|
+
// gates with `if (this.config.hooks.resolve)` so the absent-hook case
|
|
95
|
+
// skips both the call and the payload-object allocation.
|
|
96
|
+
resolve: hooks.resolve,
|
|
97
|
+
}
|
|
70
98
|
}
|
|
71
99
|
|
|
72
100
|
module.exports = GraphQLPlugin
|
|
@@ -2,34 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
4
4
|
|
|
5
|
+
const documentSources = new WeakMap()
|
|
6
|
+
|
|
5
7
|
class GraphQLParsePlugin extends TracingPlugin {
|
|
6
8
|
static id = 'graphql'
|
|
7
9
|
static operation = 'parser'
|
|
10
|
+
static prefix = 'tracing:orchestrion:graphql:apm:graphql:parser'
|
|
8
11
|
|
|
9
12
|
bindStart (ctx) {
|
|
13
|
+
const source = ctx.arguments?.[0]
|
|
14
|
+
|
|
10
15
|
this.startSpan('graphql.parse', {
|
|
11
16
|
service: this.config.service,
|
|
12
17
|
type: 'graphql',
|
|
13
18
|
meta: {},
|
|
14
19
|
}, ctx)
|
|
15
20
|
|
|
21
|
+
ctx.ddSource = source
|
|
22
|
+
|
|
16
23
|
return ctx.currentStore
|
|
17
24
|
}
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
const
|
|
26
|
+
end (ctx) {
|
|
27
|
+
const source = ctx.ddSource
|
|
28
|
+
const document = ctx.result
|
|
21
29
|
const span = ctx?.currentStore?.span || this.activeSpan
|
|
22
30
|
|
|
23
|
-
|
|
31
|
+
let docSource
|
|
32
|
+
if (document) {
|
|
33
|
+
if (source) {
|
|
34
|
+
docSource = source.body || source
|
|
35
|
+
documentSources.set(document, docSource)
|
|
36
|
+
} else {
|
|
37
|
+
docSource = documentSources.get(document)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (this.config.source && docSource) {
|
|
24
42
|
span.setTag('graphql.source', docSource)
|
|
25
43
|
}
|
|
26
44
|
|
|
27
45
|
this.config.hooks.parse(span, source, document)
|
|
28
46
|
|
|
29
|
-
|
|
47
|
+
span.finish()
|
|
30
48
|
|
|
31
49
|
return ctx.parentStore
|
|
32
50
|
}
|
|
33
51
|
}
|
|
34
52
|
|
|
53
|
+
GraphQLParsePlugin.documentSources = documentSources
|
|
54
|
+
|
|
35
55
|
module.exports = GraphQLParsePlugin
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @param {{ errorExtensions?: string[] }} config Resolved plugin config; `errorExtensions` lists the
|
|
5
|
+
* GraphQL error `extensions` keys to copy onto the span event.
|
|
6
|
+
* @param {import('../../dd-trace/src/opentracing/span')} span
|
|
7
|
+
* @param {{ name?: string, message?: string, stack?: string, locations?: Array<{ line: number, column: number }>,
|
|
8
|
+
* path?: Array<string|number>, extensions?: Record<string, unknown> }} exc
|
|
9
|
+
*/
|
|
3
10
|
function extractErrorIntoSpanEvent (config, span, exc) {
|
|
4
11
|
const attributes = {}
|
|
5
12
|
|
|
@@ -29,8 +36,8 @@ function extractErrorIntoSpanEvent (config, span, exc) {
|
|
|
29
36
|
attributes.message = exc.message
|
|
30
37
|
}
|
|
31
38
|
|
|
32
|
-
if (config.
|
|
33
|
-
for (const ext of config.
|
|
39
|
+
if (config.errorExtensions) {
|
|
40
|
+
for (const ext of config.errorExtensions) {
|
|
34
41
|
if (exc.extensions?.[ext]) {
|
|
35
42
|
const value = exc.extensions[ext]
|
|
36
43
|
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
4
|
+
const GraphQLParsePlugin = require('./parse')
|
|
4
5
|
const { extractErrorIntoSpanEvent } = require('./utils')
|
|
5
6
|
|
|
6
7
|
class GraphQLValidatePlugin extends TracingPlugin {
|
|
7
8
|
static id = 'graphql'
|
|
8
9
|
static operation = 'validate'
|
|
10
|
+
static prefix = 'tracing:orchestrion:graphql:apm:graphql:validate'
|
|
9
11
|
|
|
10
12
|
bindStart (ctx) {
|
|
11
|
-
|
|
13
|
+
// validate(schema, documentAST, rules, options, typeInfo)
|
|
14
|
+
const document = ctx.arguments?.[1]
|
|
15
|
+
const docSource = document ? GraphQLParsePlugin.documentSources.get(document) : undefined
|
|
12
16
|
const source = this.config.source && document && docSource
|
|
13
17
|
|
|
14
18
|
this.startSpan('graphql.validate', {
|
|
@@ -19,19 +23,26 @@ class GraphQLValidatePlugin extends TracingPlugin {
|
|
|
19
23
|
},
|
|
20
24
|
}, ctx)
|
|
21
25
|
|
|
26
|
+
ctx.ddDocument = document
|
|
27
|
+
|
|
22
28
|
return ctx.currentStore
|
|
23
29
|
}
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
const
|
|
31
|
+
end (ctx) {
|
|
32
|
+
const document = ctx.ddDocument
|
|
33
|
+
const errors = ctx.result
|
|
27
34
|
const span = ctx?.currentStore?.span || this.activeSpan
|
|
35
|
+
|
|
28
36
|
this.config.hooks.validate(span, document, errors)
|
|
29
|
-
|
|
37
|
+
|
|
38
|
+
if (errors?.length) {
|
|
39
|
+
span.setTag('error', errors[0])
|
|
30
40
|
for (const err of errors) {
|
|
31
|
-
extractErrorIntoSpanEvent(this.
|
|
41
|
+
extractErrorIntoSpanEvent(this.config, span, err)
|
|
32
42
|
}
|
|
33
43
|
}
|
|
34
|
-
|
|
44
|
+
|
|
45
|
+
span.finish()
|
|
35
46
|
|
|
36
47
|
return ctx.parentStore
|
|
37
48
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const PushSubscriptionPlugin = require('../../datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription')
|
|
4
3
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
5
4
|
const { enableGCPPubSubPushSubscription } = require('../../dd-trace/src/serverless')
|
|
6
5
|
const log = require('../../dd-trace/src/log')
|
|
@@ -17,14 +16,13 @@ class HttpPlugin extends CompositePlugin {
|
|
|
17
16
|
static get plugins () {
|
|
18
17
|
const plugins = {}
|
|
19
18
|
|
|
20
|
-
// Load push subscription plugin first (if enabled) for GCP Cloud Run
|
|
19
|
+
// Load the push subscription plugin first (if enabled) for GCP Cloud Run.
|
|
20
|
+
// The require stays inside the gate so the pubsub plugin graph is not pulled
|
|
21
|
+
// into every process that instruments http — only GCP Cloud Run reaches it.
|
|
21
22
|
if (enableGCPPubSubPushSubscription()) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} catch (e) {
|
|
26
|
-
log.debug('Failed to load GCP Pub/Sub Push Subscription plugin:', e)
|
|
27
|
-
}
|
|
23
|
+
plugins['pubsub-push-subscription'] =
|
|
24
|
+
require('../../datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription')
|
|
25
|
+
log.debug('Loaded GCP Pub/Sub Push Subscription plugin for HTTP requests')
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
plugins.server = HttpServerPlugin
|
|
@@ -61,15 +61,6 @@ const isJestWorker = !!getEnvironmentVariable('JEST_WORKER_ID')
|
|
|
61
61
|
// https://github.com/facebook/jest/blob/d6ad15b0f88a05816c2fe034dd6900d28315d570/packages/jest-worker/src/types.ts#L38
|
|
62
62
|
const CHILD_MESSAGE_END = 2
|
|
63
63
|
|
|
64
|
-
function withTimeout (promise, timeoutMs) {
|
|
65
|
-
return new Promise(resolve => {
|
|
66
|
-
realSetTimeout(resolve, timeoutMs)
|
|
67
|
-
|
|
68
|
-
// Also resolve if the original promise resolves
|
|
69
|
-
promise.then(resolve)
|
|
70
|
-
})
|
|
71
|
-
}
|
|
72
|
-
|
|
73
64
|
class JestPlugin extends CiPlugin {
|
|
74
65
|
static id = 'jest'
|
|
75
66
|
|
|
@@ -177,7 +168,7 @@ class JestPlugin extends CiPlugin {
|
|
|
177
168
|
|
|
178
169
|
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
179
170
|
provider: this.ciProviderName,
|
|
180
|
-
autoInjected: !!this._tracerConfig.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER,
|
|
171
|
+
autoInjected: !!this._tracerConfig.testOptimization.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER,
|
|
181
172
|
})
|
|
182
173
|
|
|
183
174
|
appClosingTelemetry()
|
|
@@ -451,6 +442,7 @@ class JestPlugin extends CiPlugin {
|
|
|
451
442
|
isAtrRetry,
|
|
452
443
|
finalStatus,
|
|
453
444
|
earlyFlakeAbortReason,
|
|
445
|
+
promises,
|
|
454
446
|
}) => {
|
|
455
447
|
span.setTag(TEST_STATUS, status)
|
|
456
448
|
if (finalStatus) {
|
|
@@ -481,12 +473,33 @@ class JestPlugin extends CiPlugin {
|
|
|
481
473
|
this.getTestTelemetryTags(span)
|
|
482
474
|
)
|
|
483
475
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
476
|
+
const finish = () => {
|
|
477
|
+
span.finish()
|
|
478
|
+
finishAllTraceSpans(span)
|
|
479
|
+
this.activeTestSpan = null
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (finalStatus) {
|
|
483
|
+
if (promises?.hitBreakpointPromise) {
|
|
484
|
+
finish()
|
|
485
|
+
this.cancelDiBreakpointHitWait()
|
|
486
|
+
return
|
|
487
|
+
}
|
|
488
|
+
if (promises && this.diBreakpointHitPromise) {
|
|
489
|
+
promises.hitBreakpointPromise = this.waitForPreparedDiBreakpointHit().then(finish)
|
|
490
|
+
return
|
|
491
|
+
}
|
|
492
|
+
finish()
|
|
493
|
+
this.cancelDiBreakpointHitWait()
|
|
494
|
+
return
|
|
495
|
+
}
|
|
496
|
+
finish()
|
|
497
|
+
if (status === 'fail' && promises?.hitBreakpointPromise) {
|
|
498
|
+
this.prepareDiBreakpointHitWait()
|
|
499
|
+
}
|
|
487
500
|
})
|
|
488
501
|
|
|
489
|
-
this.addSub('ci:jest:test:err', ({ span, error, shouldSetProbe, promises }) => {
|
|
502
|
+
this.addSub('ci:jest:test:err', ({ span, error, shouldSetProbe, shouldWaitForHitProbe, promises }) => {
|
|
490
503
|
if (error && span) {
|
|
491
504
|
span.setTag(TEST_STATUS, 'fail')
|
|
492
505
|
span.setTag('error', getFormattedError(error, this.repositoryRoot))
|
|
@@ -494,8 +507,11 @@ class JestPlugin extends CiPlugin {
|
|
|
494
507
|
const probeInformation = this.addDiProbe(error)
|
|
495
508
|
if (probeInformation) {
|
|
496
509
|
const { setProbePromise } = probeInformation
|
|
497
|
-
|
|
510
|
+
this.prepareDiBreakpointHitWait()
|
|
511
|
+
promises.isProbeReady = this.waitForDiOperation(setProbePromise)
|
|
498
512
|
}
|
|
513
|
+
} else if (shouldWaitForHitProbe && this.di) {
|
|
514
|
+
promises.hitBreakpointPromise = this.waitForDiBreakpointHits()
|
|
499
515
|
}
|
|
500
516
|
}
|
|
501
517
|
})
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
// Capture real Date.now at module load time, before any test can install fake timers.
|
|
4
|
-
const realDateNow = Date.now.bind(Date)
|
|
5
|
-
|
|
6
3
|
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
7
4
|
const { storage } = require('../../datadog-core')
|
|
8
5
|
|
|
@@ -52,8 +49,6 @@ const {
|
|
|
52
49
|
TELEMETRY_TEST_SESSION,
|
|
53
50
|
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
54
51
|
|
|
55
|
-
const BREAKPOINT_SET_GRACE_PERIOD_MS = 200
|
|
56
|
-
|
|
57
52
|
class MochaPlugin extends CiPlugin {
|
|
58
53
|
static id = 'mocha'
|
|
59
54
|
|
|
@@ -263,6 +258,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
263
258
|
span.finish()
|
|
264
259
|
finishAllTraceSpans(span)
|
|
265
260
|
this.activeTestSpan = null
|
|
261
|
+
this.cancelDiBreakpointHitWait()
|
|
266
262
|
if (this.di && this.libraryConfig?.isDiEnabled && this.runningTestProbe && isLastRetry) {
|
|
267
263
|
this.removeDiProbe(this.runningTestProbe)
|
|
268
264
|
this.runningTestProbe = null
|
|
@@ -307,8 +303,24 @@ class MochaPlugin extends CiPlugin {
|
|
|
307
303
|
return ctx.currentStore
|
|
308
304
|
})
|
|
309
305
|
|
|
310
|
-
this.addSub('ci:mocha:test:retry', ({
|
|
306
|
+
this.addSub('ci:mocha:test:retry', ({
|
|
307
|
+
span,
|
|
308
|
+
isFirstAttempt,
|
|
309
|
+
willBeRetried,
|
|
310
|
+
err,
|
|
311
|
+
test,
|
|
312
|
+
isAtrRetry,
|
|
313
|
+
promises,
|
|
314
|
+
}) => {
|
|
311
315
|
if (span) {
|
|
316
|
+
const finishSpan = () => {
|
|
317
|
+
span.finish()
|
|
318
|
+
finishAllTraceSpans(span)
|
|
319
|
+
if (this.activeTestSpan === span) {
|
|
320
|
+
this.activeTestSpan = null
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
312
324
|
span.setTag(TEST_STATUS, 'fail')
|
|
313
325
|
if (!isFirstAttempt) {
|
|
314
326
|
span.setTag(TEST_IS_RETRY, 'true')
|
|
@@ -330,21 +342,34 @@ class MochaPlugin extends CiPlugin {
|
|
|
330
342
|
if (isFirstAttempt && willBeRetried && this.di && this.libraryConfig?.isDiEnabled) {
|
|
331
343
|
const probeInformation = this.addDiProbe(err)
|
|
332
344
|
if (probeInformation) {
|
|
333
|
-
const { file, line, stackIndex } = probeInformation
|
|
345
|
+
const { file, line, stackIndex, setProbePromise } = probeInformation
|
|
334
346
|
this.runningTestProbe = { file, line }
|
|
335
347
|
this.testErrorStackIndex = stackIndex
|
|
336
348
|
test._ddShouldWaitForHitProbe = true
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
// However, Mocha doesn't have a mechanism for waiting asyncrounously here, so for now, we'll have to
|
|
341
|
-
// fall back to a fixed syncronous delay.
|
|
349
|
+
this.prepareDiBreakpointHitWait()
|
|
350
|
+
if (promises) {
|
|
351
|
+
promises.setProbePromise = this.waitForDiOperation(setProbePromise)
|
|
342
352
|
}
|
|
343
353
|
}
|
|
344
354
|
}
|
|
345
355
|
|
|
346
|
-
|
|
347
|
-
|
|
356
|
+
if (!isFirstAttempt &&
|
|
357
|
+
willBeRetried &&
|
|
358
|
+
this.di &&
|
|
359
|
+
this.libraryConfig?.isDiEnabled &&
|
|
360
|
+
this.runningTestProbe &&
|
|
361
|
+
promises) {
|
|
362
|
+
promises.finishTestPromise = this.waitForInFlightDiBreakpointHits().then(finishSpan, finishSpan)
|
|
363
|
+
return
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
finishSpan()
|
|
367
|
+
}
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
this.addSub('ci:mocha:test:di:wait', ({ promises }) => {
|
|
371
|
+
if (this.di) {
|
|
372
|
+
promises.hitBreakpointPromise = this.waitForDiBreakpointHits()
|
|
348
373
|
}
|
|
349
374
|
})
|
|
350
375
|
|
|
@@ -427,7 +452,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
427
452
|
finishAllTraceSpans(this.testSessionSpan)
|
|
428
453
|
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
429
454
|
provider: this.ciProviderName,
|
|
430
|
-
autoInjected: !!this._tracerConfig.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER,
|
|
455
|
+
autoInjected: !!this._tracerConfig.testOptimization.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER,
|
|
431
456
|
})
|
|
432
457
|
}
|
|
433
458
|
this.libraryConfig = null
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const MongodbCoreQueryPlugin = require('./query')
|
|
4
|
+
|
|
5
|
+
const MAX_RESOURCE_LENGTH = 10_000
|
|
6
|
+
|
|
7
|
+
class MongodbCoreBulkWritePlugin extends MongodbCoreQueryPlugin {
|
|
8
|
+
// bulkWrite is higher-level than the wire commands `query` traces, so it has its own operation
|
|
9
|
+
// and thus its own `apm:mongodb:bulkwrite:*` channels. It reuses the query plugin's `id`,
|
|
10
|
+
// `component`, and collection-stripping `getPeerService`, and inherits `finish`, `error`, and the
|
|
11
|
+
// finish-time parent-store restore from the tracing/outbound base classes.
|
|
12
|
+
static operation = 'bulkwrite'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Open the parent span for a `Collection#bulkWrite`. The per-type wire commands nest as
|
|
16
|
+
* children and carry the statements, host, and DBM comment, so this span only records
|
|
17
|
+
* the namespace and resource.
|
|
18
|
+
*
|
|
19
|
+
* @param {{ ns: string }} ctx
|
|
20
|
+
*/
|
|
21
|
+
bindStart (ctx) {
|
|
22
|
+
const { ns } = ctx
|
|
23
|
+
const serviceResult = this.serviceName({ pluginConfig: this.config })
|
|
24
|
+
|
|
25
|
+
this.startSpan(this.operationName(), {
|
|
26
|
+
service: serviceResult,
|
|
27
|
+
resource: truncate(`bulkWrite ${ns}`),
|
|
28
|
+
type: 'mongodb',
|
|
29
|
+
kind: 'client',
|
|
30
|
+
meta: {
|
|
31
|
+
'db.name': ns,
|
|
32
|
+
},
|
|
33
|
+
}, ctx)
|
|
34
|
+
|
|
35
|
+
return ctx.currentStore
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function truncate (input) {
|
|
40
|
+
return input.length > MAX_RESOURCE_LENGTH ? input.slice(0, MAX_RESOURCE_LENGTH) : input
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = MongodbCoreBulkWritePlugin
|