dd-trace 5.104.0 → 5.105.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 +90 -102
- package/index.d.ts +82 -3
- package/package.json +15 -15
- package/packages/datadog-core/src/storage.js +1 -1
- package/packages/datadog-instrumentations/src/aerospike.js +1 -1
- package/packages/datadog-instrumentations/src/ai.js +8 -7
- package/packages/datadog-instrumentations/src/aws-sdk.js +13 -0
- package/packages/datadog-instrumentations/src/azure-cosmos.js +7 -0
- package/packages/datadog-instrumentations/src/azure-functions.js +3 -0
- package/packages/datadog-instrumentations/src/cucumber.js +78 -5
- package/packages/datadog-instrumentations/src/dns.js +54 -18
- package/packages/datadog-instrumentations/src/fastify.js +142 -82
- package/packages/datadog-instrumentations/src/graphql.js +188 -62
- package/packages/datadog-instrumentations/src/helpers/ai-messages.js +322 -14
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/openai-ai-guard.js +269 -0
- package/packages/datadog-instrumentations/src/helpers/promise-instrumentor.js +42 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/azure-cosmos.js +50 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langgraph.js +4 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +85 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +37 -236
- package/packages/datadog-instrumentations/src/hono.js +54 -3
- package/packages/datadog-instrumentations/src/http/server.js +9 -4
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +163 -0
- package/packages/datadog-instrumentations/src/jest.js +360 -150
- package/packages/datadog-instrumentations/src/kafkajs.js +120 -16
- package/packages/datadog-instrumentations/src/mocha/main.js +128 -17
- package/packages/datadog-instrumentations/src/nats.js +182 -0
- package/packages/datadog-instrumentations/src/nyc.js +38 -1
- package/packages/datadog-instrumentations/src/openai.js +33 -18
- package/packages/datadog-instrumentations/src/oracledb.js +6 -1
- package/packages/datadog-instrumentations/src/pino.js +17 -5
- package/packages/datadog-instrumentations/src/playwright.js +515 -292
- package/packages/datadog-instrumentations/src/router.js +76 -32
- package/packages/datadog-instrumentations/src/stripe.js +1 -1
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-azure-cosmos/src/index.js +144 -0
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +1 -1
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +1 -1
- package/packages/datadog-plugin-bunyan/src/index.js +28 -0
- package/packages/datadog-plugin-cucumber/src/index.js +17 -3
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +199 -28
- package/packages/datadog-plugin-cypress/src/support.js +69 -1
- package/packages/datadog-plugin-dns/src/lookup.js +8 -6
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +2 -0
- package/packages/datadog-plugin-graphql/src/resolve.js +64 -67
- package/packages/datadog-plugin-http/src/server.js +40 -15
- package/packages/datadog-plugin-jest/src/index.js +11 -3
- package/packages/datadog-plugin-jest/src/util.js +15 -8
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -0
- package/packages/datadog-plugin-langgraph/src/stream.js +1 -1
- package/packages/datadog-plugin-mocha/src/index.js +19 -4
- package/packages/datadog-plugin-mongodb-core/src/index.js +281 -40
- package/packages/datadog-plugin-nats/src/consumer.js +43 -0
- package/packages/datadog-plugin-nats/src/index.js +20 -0
- package/packages/datadog-plugin-nats/src/producer.js +62 -0
- package/packages/datadog-plugin-nats/src/util.js +33 -0
- package/packages/datadog-plugin-next/src/index.js +5 -3
- package/packages/datadog-plugin-openai/src/tracing.js +15 -2
- package/packages/datadog-plugin-oracledb/src/index.js +13 -2
- package/packages/datadog-plugin-pino/src/index.js +42 -0
- package/packages/datadog-plugin-playwright/src/index.js +4 -4
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-rhea/src/producer.js +1 -1
- package/packages/datadog-plugin-router/src/index.js +33 -44
- package/packages/datadog-plugin-selenium/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +5 -13
- package/packages/datadog-plugin-winston/src/index.js +30 -0
- package/packages/datadog-shimmer/src/shimmer.js +33 -40
- package/packages/dd-trace/src/aiguard/index.js +1 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +5 -6
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/utils.js +1 -1
- package/packages/dd-trace/src/appsec/user_tracking.js +5 -4
- package/packages/dd-trace/src/baggage.js +7 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +25 -13
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +70 -6
- package/packages/dd-trace/src/config/generated-config-types.d.ts +6 -2
- package/packages/dd-trace/src/config/supported-configurations.json +27 -8
- package/packages/dd-trace/src/datastreams/writer.js +2 -4
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +5 -8
- package/packages/dd-trace/src/encode/0.4.js +124 -108
- package/packages/dd-trace/src/encode/0.5.js +114 -26
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +31 -23
- package/packages/dd-trace/src/encode/agentless-json.js +4 -2
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +32 -13
- package/packages/dd-trace/src/encode/span-stats.js +16 -16
- package/packages/dd-trace/src/encode/tags-processors.js +16 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +9 -7
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +0 -16
- package/packages/dd-trace/src/llmobs/span_processor.js +3 -3
- package/packages/dd-trace/src/llmobs/tagger.js +9 -1
- package/packages/dd-trace/src/llmobs/telemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/util.js +66 -3
- package/packages/dd-trace/src/log/index.js +1 -1
- package/packages/dd-trace/src/msgpack/chunk.js +394 -10
- package/packages/dd-trace/src/msgpack/index.js +96 -2
- package/packages/dd-trace/src/openfeature/encoding.js +70 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +20 -0
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +143 -0
- package/packages/dd-trace/src/openfeature/span-enrichment.js +149 -0
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +4 -3
- package/packages/dd-trace/src/opentelemetry/span.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/log.js +18 -7
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +62 -67
- package/packages/dd-trace/src/opentracing/span.js +59 -19
- package/packages/dd-trace/src/opentracing/span_context.js +49 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +20 -20
- package/packages/dd-trace/src/plugins/database.js +7 -6
- package/packages/dd-trace/src/plugins/index.js +4 -0
- package/packages/dd-trace/src/plugins/log_injection.js +56 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -48
- package/packages/dd-trace/src/plugins/outbound.js +1 -1
- package/packages/dd-trace/src/plugins/plugin.js +15 -17
- package/packages/dd-trace/src/plugins/tracing.js +43 -5
- package/packages/dd-trace/src/plugins/util/test.js +236 -13
- package/packages/dd-trace/src/plugins/util/web.js +79 -65
- package/packages/dd-trace/src/priority_sampler.js +2 -2
- package/packages/dd-trace/src/profiling/profiler.js +2 -2
- package/packages/dd-trace/src/profiling/profilers/wall.js +10 -4
- package/packages/dd-trace/src/sampling_rule.js +7 -7
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +10 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
- package/packages/dd-trace/src/service-naming/source-resolver.js +46 -0
- package/packages/dd-trace/src/span_format.js +190 -58
- package/packages/dd-trace/src/spanleak.js +1 -1
- package/packages/dd-trace/src/standalone/index.js +3 -3
- package/packages/dd-trace/src/tagger.js +0 -2
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +70 -39
- package/vendor/dist/@datadog/sketches-js/LICENSE +10 -36
- 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/packages/dd-trace/src/msgpack/encoder.js +0 -308
- package/packages/dd-trace/src/plugins/structured_log_plugin.js +0 -9
|
@@ -3,59 +3,61 @@
|
|
|
3
3
|
const dc = require('dc-polyfill')
|
|
4
4
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
5
5
|
|
|
6
|
-
const collapsedPathSym = Symbol('collapsedPaths')
|
|
7
|
-
|
|
8
6
|
class GraphQLResolvePlugin extends TracingPlugin {
|
|
9
7
|
static id = 'graphql'
|
|
10
8
|
static operation = 'resolve'
|
|
11
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @param {{
|
|
12
|
+
* rootCtx: {
|
|
13
|
+
* source?: string,
|
|
14
|
+
* collapse: boolean,
|
|
15
|
+
* collapsedFields?: Map<string, { ctx: object }>,
|
|
16
|
+
* },
|
|
17
|
+
* args: Record<string, unknown>,
|
|
18
|
+
* path: { prev: object | undefined, key: string | number },
|
|
19
|
+
* pathString: string,
|
|
20
|
+
* fieldName: string,
|
|
21
|
+
* returnType: { name: string },
|
|
22
|
+
* fieldNode: { loc?: { start: number, end: number }, arguments?: object[], directives?: object[] } | undefined,
|
|
23
|
+
* variableValues: Record<string, unknown> | undefined,
|
|
24
|
+
* }} fieldCtx
|
|
25
|
+
*/
|
|
12
26
|
start (fieldCtx) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// we need to get the parent span to the field if it exists for correct span parenting
|
|
16
|
-
// of nested fields
|
|
17
|
-
const parentField = getParentField(rootCtx, pathString)
|
|
18
|
-
const childOf = parentField?.ctx?.currentStore?.span
|
|
27
|
+
if (!shouldInstrument(this.config, fieldCtx.path)) return
|
|
19
28
|
|
|
20
|
-
|
|
29
|
+
const { rootCtx, args, path, pathString, fieldName, returnType, fieldNode, variableValues } = fieldCtx
|
|
21
30
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
// Siblings 2..N of a collapsed list share the first sibling's span, so
|
|
32
|
+
// skip span creation here. updateField still fires on the shared ctx and
|
|
33
|
+
// advances the shared span's finishTime.
|
|
34
|
+
if (rootCtx.collapse && rootCtx.collapsedFields?.has(pathString)) return
|
|
26
35
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (!rootCtx[collapsedPathSym]) {
|
|
31
|
-
rootCtx[collapsedPathSym] = Object.create(null)
|
|
32
|
-
} else if (rootCtx[collapsedPathSym][computedPathString]) {
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
rootCtx[collapsedPathSym][computedPathString] = true
|
|
37
|
-
}
|
|
36
|
+
const parentField = getParentField(rootCtx, path)
|
|
37
|
+
const childOf = parentField?.ctx?.currentStore?.span
|
|
38
38
|
|
|
39
39
|
const document = rootCtx.source
|
|
40
|
-
const fieldNode = info.fieldNodes[0]
|
|
41
40
|
const loc = this.config.source && document && fieldNode && fieldNode.loc
|
|
42
41
|
const source = loc && document.slice(loc.start, loc.end)
|
|
43
42
|
|
|
43
|
+
let namedReturnType = returnType
|
|
44
|
+
while (namedReturnType.ofType) namedReturnType = namedReturnType.ofType
|
|
45
|
+
|
|
44
46
|
const span = this.startSpan('graphql.resolve', {
|
|
45
47
|
service: this.config.service,
|
|
46
|
-
resource: `${
|
|
48
|
+
resource: `${fieldName}:${returnType}`,
|
|
47
49
|
childOf,
|
|
48
50
|
type: 'graphql',
|
|
49
51
|
meta: {
|
|
50
|
-
'graphql.field.name':
|
|
51
|
-
'graphql.field.path':
|
|
52
|
-
'graphql.field.type':
|
|
52
|
+
'graphql.field.name': fieldName,
|
|
53
|
+
'graphql.field.path': pathString,
|
|
54
|
+
'graphql.field.type': namedReturnType.name,
|
|
53
55
|
'graphql.source': source,
|
|
54
56
|
},
|
|
55
57
|
}, fieldCtx)
|
|
56
58
|
|
|
57
59
|
if (fieldNode && this.config.variables && fieldNode.arguments) {
|
|
58
|
-
const variables = this.config.variables(
|
|
60
|
+
const variables = this.config.variables(variableValues)
|
|
59
61
|
|
|
60
62
|
for (const arg of fieldNode.arguments) {
|
|
61
63
|
if (arg.value?.name && arg.value.kind === 'Variable' && variables[arg.value.name.value]) {
|
|
@@ -66,7 +68,7 @@ class GraphQLResolvePlugin extends TracingPlugin {
|
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
if (this.resolverStartCh.hasSubscribers) {
|
|
69
|
-
this.resolverStartCh.publish({ ctx: rootCtx, resolverInfo: getResolverInfo(
|
|
71
|
+
this.resolverStartCh.publish({ ctx: rootCtx, resolverInfo: getResolverInfo(fieldNode, fieldName, args) })
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
return fieldCtx.currentStore
|
|
@@ -76,11 +78,11 @@ class GraphQLResolvePlugin extends TracingPlugin {
|
|
|
76
78
|
super(...args)
|
|
77
79
|
|
|
78
80
|
this.addTraceSub('updateField', (ctx) => {
|
|
79
|
-
|
|
81
|
+
// start short-circuited on the depth gate, so there is no span to advance.
|
|
82
|
+
if (ctx.currentStore === undefined) return
|
|
80
83
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const span = ctx?.currentStore?.span || this.activeSpan
|
|
84
|
+
const { field, error } = ctx
|
|
85
|
+
const span = ctx.currentStore.span
|
|
84
86
|
field.finishTime = span._getTime ? span._getTime() : 0
|
|
85
87
|
field.error = field.error || error
|
|
86
88
|
})
|
|
@@ -105,38 +107,38 @@ class GraphQLResolvePlugin extends TracingPlugin {
|
|
|
105
107
|
|
|
106
108
|
// helpers
|
|
107
109
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
/**
|
|
111
|
+
* @param {{ depth: number, collapse: boolean }} config
|
|
112
|
+
* @param {{ prev: object | undefined, key: string | number }} path
|
|
113
|
+
*/
|
|
114
|
+
function shouldInstrument (config, path) {
|
|
115
|
+
const depth = config.depth
|
|
116
|
+
if (depth < 0) return true
|
|
110
117
|
|
|
111
|
-
let
|
|
118
|
+
let count = 0
|
|
112
119
|
if (config.collapse) {
|
|
113
|
-
|
|
120
|
+
for (let curr = path; curr; curr = curr.prev) count += 1
|
|
114
121
|
} else {
|
|
115
|
-
for (
|
|
116
|
-
if (typeof
|
|
122
|
+
for (let curr = path; curr; curr = curr.prev) {
|
|
123
|
+
if (typeof curr.key === 'string') count += 1
|
|
117
124
|
}
|
|
118
125
|
}
|
|
119
|
-
|
|
120
|
-
return config.depth >= depth
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function buildCollapsedPathString (pathAsArray) {
|
|
124
|
-
let result = ''
|
|
125
|
-
for (const segment of pathAsArray) {
|
|
126
|
-
if (result.length > 0) result += '.'
|
|
127
|
-
result += typeof segment === 'number' ? '*' : segment
|
|
128
|
-
}
|
|
129
|
-
return result
|
|
126
|
+
return depth >= count
|
|
130
127
|
}
|
|
131
128
|
|
|
132
|
-
|
|
129
|
+
/**
|
|
130
|
+
* @param {object | undefined} fieldNode
|
|
131
|
+
* @param {string} fieldName
|
|
132
|
+
* @param {Record<string, unknown> | undefined} args
|
|
133
|
+
*/
|
|
134
|
+
function getResolverInfo (fieldNode, fieldName, args) {
|
|
133
135
|
let resolverVars
|
|
134
136
|
|
|
135
137
|
if (args && Object.keys(args).length > 0) {
|
|
136
138
|
resolverVars = { ...args }
|
|
137
139
|
}
|
|
138
140
|
|
|
139
|
-
const directives =
|
|
141
|
+
const directives = fieldNode?.directives
|
|
140
142
|
if (Array.isArray(directives)) {
|
|
141
143
|
for (const directive of directives) {
|
|
142
144
|
if (directive.arguments.length === 0) continue
|
|
@@ -151,23 +153,18 @@ function getResolverInfo (info, args) {
|
|
|
151
153
|
}
|
|
152
154
|
}
|
|
153
155
|
|
|
154
|
-
return resolverVars === undefined ? null : { [
|
|
156
|
+
return resolverVars === undefined ? null : { [fieldName]: resolverVars }
|
|
155
157
|
}
|
|
156
158
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
current = current.slice(0, lastJoin)
|
|
165
|
-
const field = parentCtx.fields[current]
|
|
166
|
-
|
|
159
|
+
/**
|
|
160
|
+
* @param {{ fields: Map<object, { error: unknown, ctx: object }> }} rootCtx
|
|
161
|
+
* @param {{ prev: object | undefined }} path
|
|
162
|
+
*/
|
|
163
|
+
function getParentField (rootCtx, path) {
|
|
164
|
+
for (let curr = path.prev; curr; curr = curr.prev) {
|
|
165
|
+
const field = rootCtx.fields.get(curr)
|
|
167
166
|
if (field) return field
|
|
168
167
|
}
|
|
169
|
-
|
|
170
|
-
return null
|
|
171
168
|
}
|
|
172
169
|
|
|
173
170
|
module.exports = GraphQLResolvePlugin
|
|
@@ -14,30 +14,35 @@ class HttpServerPlugin extends ServerPlugin {
|
|
|
14
14
|
|
|
15
15
|
static prefix = 'apm:http:server:request'
|
|
16
16
|
|
|
17
|
+
/** @type {string | undefined} */
|
|
18
|
+
#operationName
|
|
19
|
+
|
|
20
|
+
/** @type {object | undefined} */
|
|
21
|
+
#startConfig
|
|
22
|
+
|
|
23
|
+
/** @type {string | undefined} */
|
|
24
|
+
#serviceSource
|
|
25
|
+
|
|
17
26
|
constructor (...args) {
|
|
18
27
|
super(...args)
|
|
19
28
|
this.addTraceSub('exit', message => this.exit(message))
|
|
20
29
|
}
|
|
21
30
|
|
|
22
|
-
start (
|
|
31
|
+
start (ctx) {
|
|
32
|
+
const { req, res } = ctx
|
|
23
33
|
let store = legacyStorage.getStore()
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
? 'opt.plugin'
|
|
28
|
-
: (service === this.tracer._service ? undefined : schemaServiceSource)
|
|
34
|
+
if (this.#startConfig === undefined) {
|
|
35
|
+
this.#refreshStartCache()
|
|
36
|
+
}
|
|
29
37
|
const span = web.startSpan(
|
|
30
38
|
this.tracer,
|
|
31
|
-
|
|
32
|
-
...this.config,
|
|
33
|
-
service,
|
|
34
|
-
},
|
|
39
|
+
this.#startConfig,
|
|
35
40
|
req,
|
|
36
41
|
res,
|
|
37
|
-
this
|
|
42
|
+
this.#operationName
|
|
38
43
|
)
|
|
39
|
-
if (serviceSource !== undefined) {
|
|
40
|
-
span.setTag(SVC_SRC_KEY, serviceSource)
|
|
44
|
+
if (this.#serviceSource !== undefined) {
|
|
45
|
+
span.setTag(SVC_SRC_KEY, this.#serviceSource)
|
|
41
46
|
}
|
|
42
47
|
span.setTag(COMPONENT, this.constructor.id)
|
|
43
48
|
span._integrationName = this.constructor.id
|
|
@@ -60,7 +65,10 @@ class HttpServerPlugin extends ServerPlugin {
|
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
if (appsecActive) {
|
|
63
|
-
|
|
68
|
+
// Reuse the ctx allocated by the HTTP server instrumentation rather
|
|
69
|
+
// than a fresh `{ req, res, abortController }` per request; the AppSec
|
|
70
|
+
// subscriber only reads from the message.
|
|
71
|
+
incomingHttpRequestStart.publish(ctx)
|
|
64
72
|
}
|
|
65
73
|
}
|
|
66
74
|
|
|
@@ -93,7 +101,24 @@ class HttpServerPlugin extends ServerPlugin {
|
|
|
93
101
|
}
|
|
94
102
|
|
|
95
103
|
configure (config) {
|
|
96
|
-
|
|
104
|
+
const result = super.configure(web.normalizeConfig(config))
|
|
105
|
+
// Invalidate the start-cache; the next `start` refills it. Resolving
|
|
106
|
+
// service / operation eagerly here would pin nomenclature lookups to
|
|
107
|
+
// the order plugins and tracer initialise.
|
|
108
|
+
this.#startConfig = undefined
|
|
109
|
+
return result
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#refreshStartCache () {
|
|
113
|
+
const { name: schemaServiceName, source: schemaServiceSource } = this.serviceName()
|
|
114
|
+
const tracerService = this.tracer._service
|
|
115
|
+
const configService = this.config.service
|
|
116
|
+
const service = configService || schemaServiceName
|
|
117
|
+
this.#serviceSource = (configService && service !== tracerService)
|
|
118
|
+
? 'opt.plugin'
|
|
119
|
+
: (service === tracerService ? undefined : schemaServiceSource)
|
|
120
|
+
this.#operationName = this.operationName()
|
|
121
|
+
this.#startConfig = { ...this.config, service }
|
|
97
122
|
}
|
|
98
123
|
}
|
|
99
124
|
|
|
@@ -16,7 +16,6 @@ const {
|
|
|
16
16
|
getTestSuiteCommonTags,
|
|
17
17
|
addIntelligentTestRunnerSpanTags,
|
|
18
18
|
TEST_PARAMETERS,
|
|
19
|
-
TEST_COMMAND,
|
|
20
19
|
TEST_FRAMEWORK_VERSION,
|
|
21
20
|
TEST_SOURCE_START,
|
|
22
21
|
TEST_ITR_UNSKIPPABLE,
|
|
@@ -115,7 +114,9 @@ class JestPlugin extends CiPlugin {
|
|
|
115
114
|
isSuitesSkipped,
|
|
116
115
|
isSuitesSkippingEnabled,
|
|
117
116
|
isCodeCoverageEnabled,
|
|
117
|
+
isCoverageReportUploadEnabled,
|
|
118
118
|
testCodeCoverageLinesTotal,
|
|
119
|
+
testSessionCoverageFiles,
|
|
119
120
|
numSkippedSuites,
|
|
120
121
|
hasUnskippableSuites,
|
|
121
122
|
hasForcedToRunSuites,
|
|
@@ -149,6 +150,13 @@ class JestPlugin extends CiPlugin {
|
|
|
149
150
|
}
|
|
150
151
|
)
|
|
151
152
|
|
|
153
|
+
if (testSessionCoverageFiles?.length && isCoverageReportUploadEnabled) {
|
|
154
|
+
this.tracer._exporter.exportCoverage({
|
|
155
|
+
sessionId: this.testSessionSpan.context()._traceId,
|
|
156
|
+
files: testSessionCoverageFiles,
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
152
160
|
if (isEarlyFlakeDetectionEnabled) {
|
|
153
161
|
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_ENABLED, 'true')
|
|
154
162
|
}
|
|
@@ -194,7 +202,7 @@ class JestPlugin extends CiPlugin {
|
|
|
194
202
|
for (const config of configs) {
|
|
195
203
|
config._ddTestSessionId = this.testSessionSpan.context().toTraceId()
|
|
196
204
|
config._ddTestModuleId = this.testModuleSpan.context().toSpanId()
|
|
197
|
-
config._ddTestCommand = this.
|
|
205
|
+
config._ddTestCommand = this.command
|
|
198
206
|
config._ddRequestErrorTags = this.getSessionRequestErrorTags()
|
|
199
207
|
config._ddItrCorrelationId = this.itrCorrelationId
|
|
200
208
|
config._ddIsEarlyFlakeDetectionEnabled = !!this.libraryConfig?.isEarlyFlakeDetectionEnabled
|
|
@@ -596,7 +604,7 @@ class JestPlugin extends CiPlugin {
|
|
|
596
604
|
extraTags[TEST_HAS_DYNAMIC_NAME] = 'true'
|
|
597
605
|
}
|
|
598
606
|
const testSuiteSpan = this.testSuiteSpanPerTestSuiteAbsolutePath.get(testSuiteAbsolutePath) || this.testSuiteSpan
|
|
599
|
-
const skippingEnabled = testSuiteSpan?.context()
|
|
607
|
+
const skippingEnabled = testSuiteSpan?.context()?.getTag?.(TEST_ITR_SKIPPING_ENABLED)
|
|
600
608
|
if (skippingEnabled !== undefined) {
|
|
601
609
|
extraTags[TEST_ITR_SKIPPING_ENABLED] = skippingEnabled
|
|
602
610
|
}
|
|
@@ -41,11 +41,16 @@ function getFormattedJestTestParameters (testParameters) {
|
|
|
41
41
|
return formattedParameters
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
//
|
|
45
|
-
//
|
|
44
|
+
// @fast-check/jest appends a random seed to the reported test name. A test name that keeps changing
|
|
45
|
+
// breaks some Test Optimization features, so normalize this narrow suffix regardless of import style.
|
|
46
46
|
const SEED_SUFFIX_RE = /\s*\(with seed=-?\d+\)\s*$/i
|
|
47
|
+
|
|
48
|
+
function removeSeedSuffixFromTestName (testName) {
|
|
49
|
+
return testName.replace(SEED_SUFFIX_RE, '')
|
|
50
|
+
}
|
|
51
|
+
|
|
47
52
|
// https://github.com/facebook/jest/blob/3e38157ad5f23fb7d24669d24fae8ded06a7ab75/packages/jest-circus/src/utils.ts#L396
|
|
48
|
-
function
|
|
53
|
+
function getRawJestTestName (test) {
|
|
49
54
|
const titles = []
|
|
50
55
|
let parent = test
|
|
51
56
|
do {
|
|
@@ -54,11 +59,11 @@ function getJestTestName (test, shouldStripSeed = false) {
|
|
|
54
59
|
|
|
55
60
|
titles.shift() // remove TOP_DESCRIBE_BLOCK_NAME
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return
|
|
62
|
+
return titles.join(' ')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function getJestTestName (test) {
|
|
66
|
+
return removeSeedSuffixFromTestName(getRawJestTestName(test))
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
const globalDocblockRegExp = /^\s*(\/\*\*?(.|\r?\n)*?\*\/)/
|
|
@@ -170,6 +175,8 @@ module.exports = {
|
|
|
170
175
|
SEED_SUFFIX_RE,
|
|
171
176
|
getFormattedJestTestParameters,
|
|
172
177
|
getJestTestName,
|
|
178
|
+
getRawJestTestName,
|
|
173
179
|
getJestSuitesToRun,
|
|
174
180
|
isMarkedAsUnskippable,
|
|
181
|
+
removeSeedSuffixFromTestName,
|
|
175
182
|
}
|
|
@@ -101,6 +101,9 @@ class KafkajsProducerPlugin extends ProducerPlugin {
|
|
|
101
101
|
// response, only the starting offset.
|
|
102
102
|
const offsets = []
|
|
103
103
|
for (const entry of result) {
|
|
104
|
+
// sendBatch hands the same multi-topic response to every per-topic
|
|
105
|
+
// ctx; the span only owns its own topic's entries.
|
|
106
|
+
if (entry.topicName !== ctx.topic) continue
|
|
104
107
|
const offsetAsLong = entry.offset ?? entry.baseOffset
|
|
105
108
|
if (entry.partition === undefined || offsetAsLong === undefined) continue
|
|
106
109
|
// Kafka offsets are 64-bit; coercing to Number loses precision past
|
|
@@ -20,7 +20,7 @@ class PregelStreamPlugin extends TracingPlugin {
|
|
|
20
20
|
}
|
|
21
21
|
class NextStreamPlugin extends TracingPlugin {
|
|
22
22
|
static id = 'langgraph_stream_next'
|
|
23
|
-
static prefix = 'tracing:orchestrion:@langchain/langgraph:
|
|
23
|
+
static prefix = 'tracing:orchestrion:@langchain/langgraph:Pregel_stream:next'
|
|
24
24
|
|
|
25
25
|
bindStart (ctx) {
|
|
26
26
|
return ctx.currentStore
|
|
@@ -11,6 +11,7 @@ const {
|
|
|
11
11
|
TEST_PARAMETERS,
|
|
12
12
|
finishAllTraceSpans,
|
|
13
13
|
getTestSuitePath,
|
|
14
|
+
getRelativeCoverageFiles,
|
|
14
15
|
getTestParametersString,
|
|
15
16
|
getTestSuiteCommonTags,
|
|
16
17
|
addIntelligentTestRunnerSpanTags,
|
|
@@ -73,8 +74,10 @@ class MochaPlugin extends CiPlugin {
|
|
|
73
74
|
this.telemetry.count(TELEMETRY_CODE_COVERAGE_EMPTY)
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
const relativeCoverageFiles = [
|
|
77
|
-
|
|
77
|
+
const relativeCoverageFiles = [
|
|
78
|
+
...getRelativeCoverageFiles(coverageFiles, this.repositoryRoot || this.sourceRoot),
|
|
79
|
+
getTestSuitePath(suiteFile, this.repositoryRoot || this.sourceRoot),
|
|
80
|
+
]
|
|
78
81
|
|
|
79
82
|
const { _traceId, _spanId } = testSuiteSpan.context()
|
|
80
83
|
|
|
@@ -152,7 +155,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
152
155
|
this.addSub('ci:mocha:test-suite:finish', ({ testSuiteSpan, status }) => {
|
|
153
156
|
if (testSuiteSpan) {
|
|
154
157
|
// the test status of the suite may have been set in ci:mocha:test-suite:error already
|
|
155
|
-
if (!testSuiteSpan.context().
|
|
158
|
+
if (!testSuiteSpan.context().getTag(TEST_STATUS)) {
|
|
156
159
|
testSuiteSpan.setTag(TEST_STATUS, status)
|
|
157
160
|
}
|
|
158
161
|
testSuiteSpan.finish()
|
|
@@ -352,6 +355,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
352
355
|
status,
|
|
353
356
|
isSuitesSkipped,
|
|
354
357
|
testCodeCoverageLinesTotal,
|
|
358
|
+
testSessionCoverageFiles,
|
|
355
359
|
numSkippedSuites,
|
|
356
360
|
hasForcedToRunSuites,
|
|
357
361
|
hasUnskippableSuites,
|
|
@@ -362,7 +366,11 @@ class MochaPlugin extends CiPlugin {
|
|
|
362
366
|
isParallel,
|
|
363
367
|
}) => {
|
|
364
368
|
if (this.testSessionSpan) {
|
|
365
|
-
const {
|
|
369
|
+
const {
|
|
370
|
+
isSuitesSkippingEnabled,
|
|
371
|
+
isCodeCoverageEnabled,
|
|
372
|
+
isCoverageReportUploadEnabled,
|
|
373
|
+
} = this.libraryConfig || {}
|
|
366
374
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
367
375
|
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
368
376
|
|
|
@@ -394,6 +402,13 @@ class MochaPlugin extends CiPlugin {
|
|
|
394
402
|
}
|
|
395
403
|
)
|
|
396
404
|
|
|
405
|
+
if (testSessionCoverageFiles?.length && isCoverageReportUploadEnabled) {
|
|
406
|
+
this.tracer._exporter.exportCoverage({
|
|
407
|
+
sessionId: this.testSessionSpan.context()._traceId,
|
|
408
|
+
files: testSessionCoverageFiles,
|
|
409
|
+
})
|
|
410
|
+
}
|
|
411
|
+
|
|
397
412
|
if (isEarlyFlakeDetectionEnabled) {
|
|
398
413
|
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_ENABLED, 'true')
|
|
399
414
|
}
|