dd-trace 5.101.0 → 5.103.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/ext/exporters.js +1 -0
- package/package.json +20 -17
- package/packages/datadog-esbuild/src/utils.js +2 -2
- package/packages/datadog-instrumentations/src/aerospike.js +2 -2
- package/packages/datadog-instrumentations/src/ai.js +9 -9
- package/packages/datadog-instrumentations/src/amqplib.js +6 -7
- package/packages/datadog-instrumentations/src/anthropic.js +10 -10
- package/packages/datadog-instrumentations/src/apollo-server-core.js +3 -3
- package/packages/datadog-instrumentations/src/apollo-server.js +5 -5
- package/packages/datadog-instrumentations/src/avsc.js +6 -6
- package/packages/datadog-instrumentations/src/aws-sdk.js +151 -67
- package/packages/datadog-instrumentations/src/azure-durable-functions.js +8 -8
- package/packages/datadog-instrumentations/src/bluebird.js +2 -2
- package/packages/datadog-instrumentations/src/body-parser.js +2 -2
- package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
- package/packages/datadog-instrumentations/src/child_process.js +12 -12
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +41 -24
- package/packages/datadog-instrumentations/src/connect.js +7 -7
- package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
- package/packages/datadog-instrumentations/src/cookie.js +2 -2
- package/packages/datadog-instrumentations/src/couchbase.js +73 -238
- package/packages/datadog-instrumentations/src/crypto.js +4 -4
- package/packages/datadog-instrumentations/src/cucumber.js +78 -17
- package/packages/datadog-instrumentations/src/dns.js +0 -3
- package/packages/datadog-instrumentations/src/elasticsearch.js +8 -11
- package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
- package/packages/datadog-instrumentations/src/electron.js +240 -0
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +6 -6
- package/packages/datadog-instrumentations/src/express-session.js +4 -4
- package/packages/datadog-instrumentations/src/express.js +10 -11
- package/packages/datadog-instrumentations/src/fastify.js +2 -2
- package/packages/datadog-instrumentations/src/fetch.js +5 -5
- package/packages/datadog-instrumentations/src/fs.js +14 -14
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +5 -7
- package/packages/datadog-instrumentations/src/google-genai.js +4 -4
- package/packages/datadog-instrumentations/src/graphql.js +13 -12
- package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
- package/packages/datadog-instrumentations/src/hapi.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +9 -9
- package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/kafka.js +41 -0
- package/packages/datadog-instrumentations/src/helpers/promise.js +2 -2
- package/packages/datadog-instrumentations/src/hono.js +2 -2
- package/packages/datadog-instrumentations/src/http/client.js +6 -6
- package/packages/datadog-instrumentations/src/http/server.js +9 -9
- package/packages/datadog-instrumentations/src/ioredis.js +16 -12
- package/packages/datadog-instrumentations/src/jest.js +382 -81
- package/packages/datadog-instrumentations/src/kafkajs.js +165 -174
- package/packages/datadog-instrumentations/src/knex.js +17 -17
- package/packages/datadog-instrumentations/src/koa.js +12 -12
- package/packages/datadog-instrumentations/src/ldapjs.js +5 -5
- package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
- package/packages/datadog-instrumentations/src/limitd-client.js +4 -4
- package/packages/datadog-instrumentations/src/lodash.js +4 -4
- package/packages/datadog-instrumentations/src/mariadb.js +13 -13
- package/packages/datadog-instrumentations/src/memcached.js +2 -2
- package/packages/datadog-instrumentations/src/microgateway-core.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +3 -3
- package/packages/datadog-instrumentations/src/mocha/main.js +85 -11
- package/packages/datadog-instrumentations/src/mocha/utils.js +133 -16
- package/packages/datadog-instrumentations/src/mocha/worker.js +7 -5
- package/packages/datadog-instrumentations/src/mongodb-core.js +42 -30
- package/packages/datadog-instrumentations/src/mongodb.js +5 -5
- package/packages/datadog-instrumentations/src/mongoose.js +21 -21
- package/packages/datadog-instrumentations/src/mquery.js +5 -5
- package/packages/datadog-instrumentations/src/multer.js +4 -4
- package/packages/datadog-instrumentations/src/mysql.js +16 -16
- package/packages/datadog-instrumentations/src/mysql2.js +4 -4
- package/packages/datadog-instrumentations/src/net.js +14 -8
- package/packages/datadog-instrumentations/src/nyc.js +5 -5
- package/packages/datadog-instrumentations/src/openai.js +19 -19
- package/packages/datadog-instrumentations/src/oracledb.js +6 -6
- package/packages/datadog-instrumentations/src/passport-utils.js +5 -5
- package/packages/datadog-instrumentations/src/pg.js +39 -25
- package/packages/datadog-instrumentations/src/pino.js +6 -10
- package/packages/datadog-instrumentations/src/playwright.js +445 -68
- package/packages/datadog-instrumentations/src/protobufjs.js +16 -16
- package/packages/datadog-instrumentations/src/redis.js +20 -12
- package/packages/datadog-instrumentations/src/restify.js +2 -2
- package/packages/datadog-instrumentations/src/router.js +12 -12
- package/packages/datadog-instrumentations/src/stripe.js +12 -12
- package/packages/datadog-instrumentations/src/vitest.js +107 -26
- package/packages/datadog-instrumentations/src/winston.js +4 -4
- package/packages/datadog-instrumentations/src/ws.js +7 -7
- package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
- package/packages/datadog-plugin-aws-sdk/src/base.js +70 -28
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +20 -13
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +46 -36
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +34 -23
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +14 -15
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +74 -55
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +20 -18
- package/packages/datadog-plugin-aws-sdk/src/util.js +22 -0
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -6
- package/packages/datadog-plugin-couchbase/src/index.js +58 -52
- package/packages/datadog-plugin-cucumber/src/index.js +5 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +215 -26
- package/packages/datadog-plugin-cypress/src/support.js +13 -1
- package/packages/datadog-plugin-electron/src/index.js +17 -0
- package/packages/datadog-plugin-electron/src/ipc.js +143 -0
- package/packages/datadog-plugin-electron/src/net.js +82 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -5
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +3 -1
- package/packages/datadog-plugin-graphql/src/execute.js +6 -28
- package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
- package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
- package/packages/datadog-plugin-graphql/src/utils.js +29 -0
- package/packages/datadog-plugin-grpc/src/client.js +6 -7
- package/packages/datadog-plugin-grpc/src/util.js +57 -22
- package/packages/datadog-plugin-http/src/client.js +3 -7
- package/packages/datadog-plugin-jest/src/index.js +92 -50
- package/packages/datadog-plugin-jest/src/util.js +1 -2
- package/packages/datadog-plugin-mocha/src/index.js +5 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +36 -69
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/services.js +2 -1
- package/packages/datadog-plugin-openai/src/tracing.js +12 -23
- package/packages/datadog-plugin-pg/src/index.js +3 -3
- package/packages/datadog-plugin-playwright/src/index.js +5 -1
- package/packages/datadog-plugin-redis/src/index.js +18 -23
- package/packages/datadog-plugin-vitest/src/index.js +8 -1
- package/packages/datadog-shimmer/src/shimmer.js +7 -1
- package/packages/dd-trace/src/aiguard/index.js +3 -1
- package/packages/dd-trace/src/aiguard/sdk.js +36 -30
- package/packages/dd-trace/src/aiguard/tags.js +20 -11
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +81 -81
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +4 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +83 -48
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +21 -24
- package/packages/dd-trace/src/appsec/reporter.js +3 -1
- package/packages/dd-trace/src/appsec/rule_manager.js +4 -2
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +31 -16
- package/packages/dd-trace/src/azure_metadata.js +17 -6
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
- package/packages/dd-trace/src/config/defaults.js +3 -14
- package/packages/dd-trace/src/config/generated-config-types.d.ts +3 -1
- package/packages/dd-trace/src/config/git_properties.js +2 -2
- package/packages/dd-trace/src/config/helper.js +4 -0
- package/packages/dd-trace/src/config/index.js +2 -2
- package/packages/dd-trace/src/config/major-overrides.js +98 -0
- package/packages/dd-trace/src/config/parsers.js +7 -1
- package/packages/dd-trace/src/config/supported-configurations.json +51 -38
- package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
- package/packages/dd-trace/src/datastreams/index.js +2 -1
- package/packages/dd-trace/src/datastreams/manager.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
- package/packages/dd-trace/src/debugger/index.js +7 -7
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +748 -232
- package/packages/dd-trace/src/encode/0.5.js +47 -10
- package/packages/dd-trace/src/encode/agentless-json.js +1 -1
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
- package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/electron/index.js +49 -0
- package/packages/dd-trace/src/external-logger/src/index.js +2 -1
- package/packages/dd-trace/src/git_metadata.js +10 -8
- package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
- package/packages/dd-trace/src/lambda/index.js +62 -14
- package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
- package/packages/dd-trace/src/llmobs/index.js +13 -2
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -2
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +6 -3
- package/packages/dd-trace/src/llmobs/sdk.js +24 -26
- package/packages/dd-trace/src/llmobs/span_processor.js +25 -5
- package/packages/dd-trace/src/llmobs/util.js +1 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
- package/packages/dd-trace/src/msgpack/chunk.js +6 -3
- package/packages/dd-trace/src/openfeature/noop.js +40 -36
- package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
- package/packages/dd-trace/src/openfeature/writers/exposures.js +33 -52
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +2 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +1 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +0 -22
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -11
- package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +49 -4
- package/packages/dd-trace/src/plugins/database.js +54 -12
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/plugin.js +2 -4
- package/packages/dd-trace/src/plugins/util/ci.js +9 -9
- package/packages/dd-trace/src/plugins/util/git-cache.js +23 -23
- package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
- package/packages/dd-trace/src/plugins/util/test.js +56 -12
- package/packages/dd-trace/src/plugins/util/url.js +1 -3
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +18 -16
- package/packages/dd-trace/src/plugins/util/web.js +5 -7
- package/packages/dd-trace/src/priority_sampler.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -23
- package/packages/dd-trace/src/profiling/profilers/wall.js +5 -6
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
- package/packages/dd-trace/src/rate_limiter.js +1 -1
- package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
- package/packages/dd-trace/src/ritm.js +2 -1
- package/packages/dd-trace/src/runtime_metrics/index.js +2 -2
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
- package/packages/dd-trace/src/scope.js +3 -10
- package/packages/dd-trace/src/serverless.js +6 -6
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +27 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +24 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
- package/packages/dd-trace/src/span_stats.js +1 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
- package/packages/dd-trace/src/tracer.js +7 -7
- package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
|
@@ -44,6 +44,35 @@ function extractErrorIntoSpanEvent (config, span, exc) {
|
|
|
44
44
|
span.addEvent('dd.graphql.query.error', attributes, Date.now())
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
let tools
|
|
48
|
+
|
|
49
|
+
function getSignature (document, operationName, operationType, calculate) {
|
|
50
|
+
if (calculate !== false && tools !== false) {
|
|
51
|
+
try {
|
|
52
|
+
try {
|
|
53
|
+
tools ||= require('./tools')
|
|
54
|
+
} catch (e) {
|
|
55
|
+
tools = false
|
|
56
|
+
throw e
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return tools.defaultEngineReportingSignature(document, operationName)
|
|
60
|
+
} catch {
|
|
61
|
+
// safety net
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (operationType) {
|
|
66
|
+
if (operationName) {
|
|
67
|
+
return `${operationType} ${operationName}`
|
|
68
|
+
}
|
|
69
|
+
return operationType
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return operationName ?? ''
|
|
73
|
+
}
|
|
74
|
+
|
|
47
75
|
module.exports = {
|
|
48
76
|
extractErrorIntoSpanEvent,
|
|
77
|
+
getSignature,
|
|
49
78
|
}
|
|
@@ -86,12 +86,11 @@ class GrpcClientPlugin extends ClientPlugin {
|
|
|
86
86
|
// The only scheme we want to support here is ipv[46]:port, although
|
|
87
87
|
// more are supported by the library
|
|
88
88
|
// https://github.com/grpc/grpc/blob/v1.60.0/doc/naming.md
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
span.setTag('network.destination.
|
|
94
|
-
span.setTag('network.destination.port', port)
|
|
89
|
+
const colonIndex = peer.lastIndexOf(':')
|
|
90
|
+
const tail = colonIndex === -1 ? '' : peer.slice(colonIndex + 1)
|
|
91
|
+
if (tail && /^\d+$/.test(tail)) {
|
|
92
|
+
span.setTag('network.destination.ip', peer.slice(0, colonIndex))
|
|
93
|
+
span.setTag('network.destination.port', tail)
|
|
95
94
|
} else {
|
|
96
95
|
span.setTag('network.destination.ip', peer)
|
|
97
96
|
}
|
|
@@ -121,7 +120,7 @@ function inject (tracer, span, metadata) {
|
|
|
121
120
|
|
|
122
121
|
tracer.inject(span, TEXT_MAP, carrier)
|
|
123
122
|
|
|
124
|
-
for (const key
|
|
123
|
+
for (const key of Object.keys(carrier)) {
|
|
125
124
|
metadata.set(key, carrier[key])
|
|
126
125
|
}
|
|
127
126
|
}
|
|
@@ -3,46 +3,81 @@
|
|
|
3
3
|
const pick = require('../../datadog-core/src/utils/src/pick')
|
|
4
4
|
const log = require('../../dd-trace/src/log')
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {object} ParsedMethodPath
|
|
8
|
+
* @property {string} name
|
|
9
|
+
* @property {string} service
|
|
10
|
+
* @property {string} package
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// Sentinel returned by `getFilter` when the user has not configured a metadata
|
|
14
|
+
// filter. `addMetadataTags` short-circuits on this identity to skip the
|
|
15
|
+
// `metadata.getMap()` clone in the default no-filter case.
|
|
6
16
|
function getEmptyObject () {
|
|
7
17
|
return {}
|
|
8
18
|
}
|
|
9
19
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
/**
|
|
21
|
+
* gRPC method paths are stable per service definition (e.g.
|
|
22
|
+
* `/pkg.Service/Method`); a service typically only has a small finite set.
|
|
23
|
+
* Cache the parsed `{name, service, package}` triple by path so we skip the
|
|
24
|
+
* `path.split('/')` + `serviceParts.split('.')` + `serviceParts.pop()` work
|
|
25
|
+
* on every call.
|
|
26
|
+
*
|
|
27
|
+
* @type {Map<string, ParsedMethodPath>}
|
|
28
|
+
*/
|
|
29
|
+
const methodPathCache = new Map()
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {string} path
|
|
33
|
+
* @returns {ParsedMethodPath}
|
|
34
|
+
*/
|
|
35
|
+
function parseMethodPath (path) {
|
|
36
|
+
const methodParts = path.split('/')
|
|
37
|
+
|
|
38
|
+
if (methodParts.length > 2) {
|
|
39
|
+
const serviceParts = methodParts[1].split('.')
|
|
40
|
+
return {
|
|
41
|
+
name: methodParts[2],
|
|
42
|
+
service: serviceParts.pop(),
|
|
43
|
+
package: serviceParts.join('.'),
|
|
18
44
|
}
|
|
45
|
+
}
|
|
19
46
|
|
|
20
|
-
|
|
47
|
+
return { name: methodParts.at(-1), service: '', package: '' }
|
|
48
|
+
}
|
|
21
49
|
|
|
22
|
-
|
|
50
|
+
module.exports = {
|
|
51
|
+
getEmptyObject,
|
|
23
52
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const pkg = serviceParts.join('.')
|
|
53
|
+
getMethodMetadata (path, kind) {
|
|
54
|
+
if (typeof path !== 'string') {
|
|
55
|
+
return { path, kind, name: '', service: '', package: '' }
|
|
56
|
+
}
|
|
29
57
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
tags.name = methodParts.at(-1)
|
|
58
|
+
let parsed = methodPathCache.get(path)
|
|
59
|
+
if (parsed === undefined) {
|
|
60
|
+
parsed = parseMethodPath(path)
|
|
61
|
+
methodPathCache.set(path, parsed)
|
|
35
62
|
}
|
|
36
63
|
|
|
37
|
-
return
|
|
64
|
+
return {
|
|
65
|
+
path,
|
|
66
|
+
kind,
|
|
67
|
+
name: parsed.name,
|
|
68
|
+
service: parsed.service,
|
|
69
|
+
package: parsed.package,
|
|
70
|
+
}
|
|
38
71
|
},
|
|
39
72
|
|
|
40
73
|
addMetadataTags (span, metadata, filter, type) {
|
|
41
74
|
if (!metadata || typeof metadata.getMap !== 'function') return
|
|
75
|
+
// Default no-op filter: skip the full metadata clone via `getMap()`.
|
|
76
|
+
if (filter === getEmptyObject) return
|
|
42
77
|
|
|
43
78
|
const values = filter(metadata.getMap())
|
|
44
79
|
|
|
45
|
-
for (const key
|
|
80
|
+
for (const key of Object.keys(values)) {
|
|
46
81
|
span.setTag(`grpc.${type}.metadata.${key}`, values[key])
|
|
47
82
|
}
|
|
48
83
|
},
|
|
@@ -39,10 +39,10 @@ class HttpClientPlugin extends ClientPlugin {
|
|
|
39
39
|
// TODO delegate to super.startspan
|
|
40
40
|
const span = this.startSpan(this.operationName(), {
|
|
41
41
|
childOf,
|
|
42
|
-
integrationName: this.
|
|
42
|
+
integrationName: this.component,
|
|
43
43
|
service: this.serviceName({ pluginConfig: this.config, sessionDetails: extractSessionDetails(options) }),
|
|
44
44
|
meta: {
|
|
45
|
-
[COMPONENT]: this.
|
|
45
|
+
[COMPONENT]: this.component,
|
|
46
46
|
'span.kind': 'client',
|
|
47
47
|
'resource.name': method,
|
|
48
48
|
'span.type': 'http',
|
|
@@ -79,11 +79,7 @@ class HttpClientPlugin extends ClientPlugin {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
shouldInjectTraceHeaders (options, uri) {
|
|
82
|
-
|
|
83
|
-
return false
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return true
|
|
82
|
+
return Boolean(this.config.propagationFilter(uri))
|
|
87
83
|
}
|
|
88
84
|
|
|
89
85
|
bindAsyncStart ({ parentStore }) {
|
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
TEST_SOURCE_START,
|
|
22
22
|
TEST_ITR_UNSKIPPABLE,
|
|
23
23
|
TEST_ITR_FORCED_RUN,
|
|
24
|
+
TEST_ITR_SKIPPING_ENABLED,
|
|
24
25
|
TEST_CODE_OWNERS,
|
|
25
26
|
ITR_CORRELATION_ID,
|
|
26
27
|
TEST_SOURCE_FILE,
|
|
@@ -107,6 +108,7 @@ class JestPlugin extends CiPlugin {
|
|
|
107
108
|
process.on('message', handler)
|
|
108
109
|
}
|
|
109
110
|
this.testSuiteSpanPerTestSuiteAbsolutePath = new Map()
|
|
111
|
+
this.pendingTestSuiteFinishes = new Set()
|
|
110
112
|
|
|
111
113
|
this.addSub('ci:jest:session:finish', ({
|
|
112
114
|
status,
|
|
@@ -123,58 +125,66 @@ class JestPlugin extends CiPlugin {
|
|
|
123
125
|
isTestManagementTestsEnabled,
|
|
124
126
|
onDone,
|
|
125
127
|
}) => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
const finishSession = () => {
|
|
129
|
+
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
130
|
+
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
128
131
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
addIntelligentTestRunnerSpanTags(
|
|
135
|
-
this.testSessionSpan,
|
|
136
|
-
this.testModuleSpan,
|
|
137
|
-
{
|
|
138
|
-
isSuitesSkipped,
|
|
139
|
-
isSuitesSkippingEnabled,
|
|
140
|
-
isCodeCoverageEnabled,
|
|
141
|
-
testCodeCoverageLinesTotal,
|
|
142
|
-
skippingType: 'suite',
|
|
143
|
-
skippingCount: numSkippedSuites,
|
|
144
|
-
hasUnskippableSuites,
|
|
145
|
-
hasForcedToRunSuites,
|
|
132
|
+
if (error) {
|
|
133
|
+
this.testSessionSpan.setTag('error', error)
|
|
134
|
+
this.testModuleSpan.setTag('error', error)
|
|
146
135
|
}
|
|
147
|
-
)
|
|
148
136
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
137
|
+
addIntelligentTestRunnerSpanTags(
|
|
138
|
+
this.testSessionSpan,
|
|
139
|
+
this.testModuleSpan,
|
|
140
|
+
{
|
|
141
|
+
isSuitesSkipped,
|
|
142
|
+
isSuitesSkippingEnabled,
|
|
143
|
+
isCodeCoverageEnabled,
|
|
144
|
+
testCodeCoverageLinesTotal,
|
|
145
|
+
skippingType: 'suite',
|
|
146
|
+
skippingCount: numSkippedSuites,
|
|
147
|
+
hasUnskippableSuites,
|
|
148
|
+
hasForcedToRunSuites,
|
|
149
|
+
}
|
|
150
|
+
)
|
|
158
151
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
152
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
153
|
+
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_ENABLED, 'true')
|
|
154
|
+
}
|
|
155
|
+
if (isEarlyFlakeDetectionFaulty) {
|
|
156
|
+
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_ABORT_REASON, 'faulty')
|
|
157
|
+
}
|
|
158
|
+
if (isTestManagementTestsEnabled) {
|
|
159
|
+
this.testSessionSpan.setTag(TEST_MANAGEMENT_ENABLED, 'true')
|
|
160
|
+
}
|
|
166
161
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
162
|
+
this.testModuleSpan.finish()
|
|
163
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
164
|
+
this.testSessionSpan.finish()
|
|
165
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session', {
|
|
166
|
+
hasFailedTestReplay: this.libraryConfig?.isDiEnabled || undefined,
|
|
167
|
+
})
|
|
168
|
+
finishAllTraceSpans(this.testSessionSpan)
|
|
169
|
+
|
|
170
|
+
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
171
|
+
provider: this.ciProviderName,
|
|
172
|
+
autoInjected: !!this._tracerConfig.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER,
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
appClosingTelemetry()
|
|
176
|
+
this.tracer._exporter.flush(() => {
|
|
177
|
+
if (onDone) {
|
|
178
|
+
onDone()
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
}
|
|
171
182
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
})
|
|
183
|
+
if (this.pendingTestSuiteFinishes.size > 0) {
|
|
184
|
+
Promise.all(this.pendingTestSuiteFinishes).then(finishSession)
|
|
185
|
+
} else {
|
|
186
|
+
finishSession()
|
|
187
|
+
}
|
|
178
188
|
})
|
|
179
189
|
|
|
180
190
|
// Test suites can be run in a different process from jest's main one.
|
|
@@ -197,6 +207,7 @@ class JestPlugin extends CiPlugin {
|
|
|
197
207
|
config._ddIsDiEnabled = this.libraryConfig?.isDiEnabled ?? false
|
|
198
208
|
config._ddIsKnownTestsEnabled = this.libraryConfig?.isKnownTestsEnabled ?? false
|
|
199
209
|
config._ddIsImpactedTestsEnabled = this.libraryConfig?.isImpactedTestsEnabled ?? false
|
|
210
|
+
config._ddItrSkippingEnabledTags = this.getSessionItrSkippingEnabledTags()
|
|
200
211
|
}
|
|
201
212
|
})
|
|
202
213
|
|
|
@@ -217,6 +228,7 @@ class JestPlugin extends CiPlugin {
|
|
|
217
228
|
_ddForcedToRun,
|
|
218
229
|
_ddUnskippable,
|
|
219
230
|
_ddTestCodeCoverageEnabled,
|
|
231
|
+
_ddItrSkippingEnabledTags: itrSkippingEnabledTags,
|
|
220
232
|
} = testEnvironmentOptions
|
|
221
233
|
|
|
222
234
|
const testSessionSpanContext = this.tracer.extract('text_map', {
|
|
@@ -228,6 +240,7 @@ class JestPlugin extends CiPlugin {
|
|
|
228
240
|
...getTestSuiteCommonTags(testCommand, frameworkVersion, testSuite, 'jest'),
|
|
229
241
|
// requestErrorTags from test env options may be undefined
|
|
230
242
|
...(requestErrorTags !== undefined && requestErrorTags !== null ? requestErrorTags : {}),
|
|
243
|
+
...(itrSkippingEnabledTags !== undefined && itrSkippingEnabledTags !== null ? itrSkippingEnabledTags : {}),
|
|
231
244
|
}
|
|
232
245
|
|
|
233
246
|
if (_ddUnskippable) {
|
|
@@ -305,10 +318,18 @@ class JestPlugin extends CiPlugin {
|
|
|
305
318
|
}
|
|
306
319
|
})
|
|
307
320
|
|
|
308
|
-
this.addSub('ci:jest:test-suite:finish', ({
|
|
321
|
+
this.addSub('ci:jest:test-suite:finish', ({
|
|
322
|
+
status,
|
|
323
|
+
errorMessage,
|
|
324
|
+
error,
|
|
325
|
+
testSuiteAbsolutePath,
|
|
326
|
+
waitForFinish,
|
|
327
|
+
onDone,
|
|
328
|
+
}) => {
|
|
309
329
|
const testSuiteSpan = this.testSuiteSpanPerTestSuiteAbsolutePath.get(testSuiteAbsolutePath)
|
|
310
330
|
if (!testSuiteSpan) {
|
|
311
331
|
log.warn('"ci:jest:test-suite:finish": no span found for test suite absolute path %s', testSuiteAbsolutePath)
|
|
332
|
+
onDone?.()
|
|
312
333
|
return
|
|
313
334
|
}
|
|
314
335
|
testSuiteSpan.setTag(TEST_STATUS, status)
|
|
@@ -319,8 +340,13 @@ class JestPlugin extends CiPlugin {
|
|
|
319
340
|
testSuiteSpan.setTag('error', new Error(errorMessage))
|
|
320
341
|
testSuiteSpan.setTag(TEST_STATUS, 'fail')
|
|
321
342
|
}
|
|
322
|
-
|
|
323
|
-
|
|
343
|
+
let resolvePendingFinish
|
|
344
|
+
const pendingFinish = new Promise(resolve => {
|
|
345
|
+
resolvePendingFinish = resolve
|
|
346
|
+
})
|
|
347
|
+
this.pendingTestSuiteFinishes.add(pendingFinish)
|
|
348
|
+
|
|
349
|
+
const finish = () => {
|
|
324
350
|
testSuiteSpan.finish()
|
|
325
351
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
326
352
|
// Suites potentially run in a different process than the session,
|
|
@@ -334,7 +360,19 @@ class JestPlugin extends CiPlugin {
|
|
|
334
360
|
}
|
|
335
361
|
this.removeAllDiProbes()
|
|
336
362
|
this.testSuiteSpanPerTestSuiteAbsolutePath.delete(testSuiteAbsolutePath)
|
|
337
|
-
|
|
363
|
+
this.pendingTestSuiteFinishes.delete(pendingFinish)
|
|
364
|
+
resolvePendingFinish()
|
|
365
|
+
if (onDone) {
|
|
366
|
+
onDone()
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (waitForFinish) {
|
|
371
|
+
// Give late async work time to run before Jest restarts a worker because of workerIdleMemoryLimit.
|
|
372
|
+
realSetTimeout(finish)
|
|
373
|
+
} else {
|
|
374
|
+
process.nextTick(finish)
|
|
375
|
+
}
|
|
338
376
|
})
|
|
339
377
|
|
|
340
378
|
this.addSub('ci:jest:test-suite:error', ({ error, errorMessage, testSuiteAbsolutePath }) => {
|
|
@@ -558,6 +596,10 @@ class JestPlugin extends CiPlugin {
|
|
|
558
596
|
extraTags[TEST_HAS_DYNAMIC_NAME] = 'true'
|
|
559
597
|
}
|
|
560
598
|
const testSuiteSpan = this.testSuiteSpanPerTestSuiteAbsolutePath.get(testSuiteAbsolutePath) || this.testSuiteSpan
|
|
599
|
+
const skippingEnabled = testSuiteSpan?.context()._tags?.[TEST_ITR_SKIPPING_ENABLED]
|
|
600
|
+
if (skippingEnabled !== undefined) {
|
|
601
|
+
extraTags[TEST_ITR_SKIPPING_ENABLED] = skippingEnabled
|
|
602
|
+
}
|
|
561
603
|
|
|
562
604
|
return super.startTestSpan(name, suite, testSuiteSpan, extraTags)
|
|
563
605
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { readFileSync } = require('fs')
|
|
4
4
|
const { parse } = require('../../../vendor/dist/jest-docblock')
|
|
5
5
|
|
|
6
|
-
const { getTestSuitePath
|
|
6
|
+
const { getTestSuitePath } = require('../../dd-trace/src/plugins/util/test')
|
|
7
7
|
const log = require('../../dd-trace/src/log')
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -172,5 +172,4 @@ module.exports = {
|
|
|
172
172
|
getJestTestName,
|
|
173
173
|
getJestSuitesToRun,
|
|
174
174
|
isMarkedAsUnskippable,
|
|
175
|
-
getEfdRetryCount,
|
|
176
175
|
}
|
|
@@ -105,6 +105,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
105
105
|
'mocha'
|
|
106
106
|
),
|
|
107
107
|
...this.getSessionRequestErrorTags(),
|
|
108
|
+
...this.getSessionItrSkippingEnabledTags(),
|
|
108
109
|
}
|
|
109
110
|
if (isUnskippable) {
|
|
110
111
|
testSuiteMetadata[TEST_ITR_UNSKIPPABLE] = 'true'
|
|
@@ -218,12 +219,16 @@ class MochaPlugin extends CiPlugin {
|
|
|
218
219
|
isAttemptToFixRetry,
|
|
219
220
|
isAtrRetry,
|
|
220
221
|
finalStatus,
|
|
222
|
+
earlyFlakeAbortReason,
|
|
221
223
|
}) => {
|
|
222
224
|
if (span) {
|
|
223
225
|
span.setTag(TEST_STATUS, status)
|
|
224
226
|
if (finalStatus) {
|
|
225
227
|
span.setTag(TEST_FINAL_STATUS, finalStatus)
|
|
226
228
|
}
|
|
229
|
+
if (earlyFlakeAbortReason) {
|
|
230
|
+
span.setTag(TEST_EARLY_FLAKE_ABORT_REASON, earlyFlakeAbortReason)
|
|
231
|
+
}
|
|
227
232
|
if (hasBeenRetried) {
|
|
228
233
|
span.setTag(TEST_IS_RETRY, 'true')
|
|
229
234
|
if (isAtrRetry) {
|
|
@@ -90,9 +90,8 @@ class MongodbCorePlugin extends DatabasePlugin {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
93
|
+
const MAX_DEPTH = 10
|
|
94
|
+
const MAX_QUERY_LENGTH = 10_000
|
|
96
95
|
|
|
97
96
|
function extractQuery (statements) {
|
|
98
97
|
if (statements.length === 1 && statements[0].q) return statements[0].q
|
|
@@ -100,7 +99,7 @@ function extractQuery (statements) {
|
|
|
100
99
|
const extractedQueries = []
|
|
101
100
|
for (let i = 0; i < statements.length; i++) {
|
|
102
101
|
if (statements[i].q) {
|
|
103
|
-
extractedQueries.push(
|
|
102
|
+
extractedQueries.push(statements[i].q)
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
|
|
@@ -110,12 +109,12 @@ function extractQuery (statements) {
|
|
|
110
109
|
function getQuery (cmd) {
|
|
111
110
|
if (!cmd || (typeof cmd !== 'object' && !Array.isArray(cmd))) return
|
|
112
111
|
|
|
113
|
-
if (Array.isArray(cmd)) return
|
|
114
|
-
if (cmd.query) return
|
|
115
|
-
if (cmd.filter) return
|
|
116
|
-
if (cmd.pipeline) return
|
|
117
|
-
if (cmd.deletes) return
|
|
118
|
-
if (cmd.updates) return
|
|
112
|
+
if (Array.isArray(cmd)) return sanitiseAndStringify(extractQuery(cmd))
|
|
113
|
+
if (cmd.query) return sanitiseAndStringify(cmd.query)
|
|
114
|
+
if (cmd.filter) return sanitiseAndStringify(cmd.filter)
|
|
115
|
+
if (cmd.pipeline) return sanitiseAndStringify(cmd.pipeline)
|
|
116
|
+
if (cmd.deletes) return sanitiseAndStringify(extractQuery(cmd.deletes))
|
|
117
|
+
if (cmd.updates) return sanitiseAndStringify(extractQuery(cmd.updates))
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
function getResource (plugin, ns, query, operationName) {
|
|
@@ -129,72 +128,40 @@ function getResource (plugin, ns, query, operationName) {
|
|
|
129
128
|
}
|
|
130
129
|
|
|
131
130
|
function truncate (input) {
|
|
132
|
-
return input.slice(0,
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function shouldSimplify (input) {
|
|
136
|
-
return !isObject(input) || typeof input.toJSON === 'function'
|
|
131
|
+
return input.length > MAX_QUERY_LENGTH ? input.slice(0, MAX_QUERY_LENGTH) : input
|
|
137
132
|
}
|
|
138
133
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const {
|
|
160
|
-
input, output, depth,
|
|
161
|
-
} = queue.pop()
|
|
162
|
-
const nextDepth = depth + 1
|
|
163
|
-
for (const key of Object.keys(input)) {
|
|
164
|
-
let child = input[key]
|
|
165
|
-
if (typeof child === 'function') continue
|
|
166
|
-
|
|
167
|
-
if (isBSON(child)) {
|
|
168
|
-
child = typeof child.toJSON === 'function' ? child.toJSON() : '?'
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (depth >= 10 || shouldHide(child)) {
|
|
172
|
-
output[key] = '?'
|
|
173
|
-
} else if (shouldSimplify(child)) {
|
|
174
|
-
output[key] = child
|
|
175
|
-
} else {
|
|
176
|
-
queue.push({
|
|
177
|
-
input: child,
|
|
178
|
-
output: output[key] = {},
|
|
179
|
-
depth: nextDepth,
|
|
180
|
-
})
|
|
134
|
+
// Single-pass sanitisation. The replacer:
|
|
135
|
+
// - skips functions and coerces bigint to its decimal string,
|
|
136
|
+
// - returns '?' for Buffer / BSON Binary on the *original* value (JSON.stringify already invoked
|
|
137
|
+
// toJSON before calling us; Buffer / Binary do have toJSON outputs we want to suppress),
|
|
138
|
+
// - lets JSON.stringify call toJSON on other BSON types (ObjectId, Long, Decimal128, Date, Timestamp, ...)
|
|
139
|
+
// so the result lands here as a primitive or plain object,
|
|
140
|
+
// - returns '?' for BSON types without toJSON (MinKey, MaxKey) where `value === original`,
|
|
141
|
+
// - tracks depth via an ancestor stack so cycles and depth >= MAX_DEPTH collapse to '?'.
|
|
142
|
+
function sanitiseAndStringify (input) {
|
|
143
|
+
const ancestors = []
|
|
144
|
+
return JSON.stringify(input, function (key, value) {
|
|
145
|
+
if (typeof value === 'function') return
|
|
146
|
+
if (typeof value === 'bigint') return value.toString()
|
|
147
|
+
|
|
148
|
+
const original = key === '' ? value : this[key]
|
|
149
|
+
if (typeof original === 'object' && original !== null) {
|
|
150
|
+
if (Buffer.isBuffer(original)) return '?'
|
|
151
|
+
const bsontype = original._bsontype
|
|
152
|
+
if (bsontype !== undefined && (bsontype === 'Binary' || value === original)) {
|
|
153
|
+
return '?'
|
|
181
154
|
}
|
|
182
155
|
}
|
|
183
|
-
}
|
|
184
156
|
|
|
185
|
-
|
|
186
|
-
}
|
|
157
|
+
if (value === null || typeof value !== 'object') return value
|
|
187
158
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
function isBSON (val) {
|
|
193
|
-
return val && val._bsontype && !isBinary(val)
|
|
194
|
-
}
|
|
159
|
+
while (ancestors.length > 0 && ancestors.at(-1) !== this) ancestors.pop()
|
|
160
|
+
if (ancestors.length >= MAX_DEPTH || ancestors.includes(value)) return '?'
|
|
161
|
+
ancestors.push(value)
|
|
195
162
|
|
|
196
|
-
|
|
197
|
-
|
|
163
|
+
return value
|
|
164
|
+
})
|
|
198
165
|
}
|
|
199
166
|
|
|
200
167
|
function isHeartbeat (ops, config) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { storage } = require('../../datadog-core')
|
|
4
|
-
const CLIENT_PORT_KEY = require('../../dd-trace/src/constants')
|
|
4
|
+
const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
|
|
5
5
|
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
6
6
|
|
|
7
7
|
class MySQLPlugin extends DatabasePlugin {
|