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
|
@@ -10,8 +10,10 @@ const {
|
|
|
10
10
|
HTTP_ENDPOINT,
|
|
11
11
|
HTTP_ROUTE,
|
|
12
12
|
HTTP_METHOD,
|
|
13
|
+
SPAN_KIND,
|
|
14
|
+
GRPC_STATUS_CODE,
|
|
13
15
|
} = require('../../../ext/tags')
|
|
14
|
-
const { ORIGIN_KEY, TOP_LEVEL_KEY, SVC_SRC_KEY } = require('./constants')
|
|
16
|
+
const { ORIGIN_KEY, TOP_LEVEL_KEY, SVC_SRC_KEY, GRPC_STATUS_NAMES } = require('./constants')
|
|
15
17
|
const { version } = require('./pkg')
|
|
16
18
|
const processTags = require('./process-tags')
|
|
17
19
|
|
|
@@ -27,43 +29,32 @@ class SpanAggStats {
|
|
|
27
29
|
this.aggKey = aggKey
|
|
28
30
|
this.hits = 0
|
|
29
31
|
this.topLevelHits = 0
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
32
|
+
this.topLevelOkDistribution = new LogCollapsingLowestDenseDDSketch()
|
|
33
|
+
this.topLevelErrorDistribution = new LogCollapsingLowestDenseDDSketch()
|
|
34
|
+
this.nonTopLevelOkDistribution = new LogCollapsingLowestDenseDDSketch()
|
|
35
|
+
this.nonTopLevelErrorDistribution = new LogCollapsingLowestDenseDDSketch()
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
record (span) {
|
|
37
39
|
const durationNs = span.duration
|
|
38
40
|
this.hits++
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (span.metrics[TOP_LEVEL_KEY]) {
|
|
42
|
-
this.topLevelHits++
|
|
43
|
-
}
|
|
44
|
-
|
|
41
|
+
const isTopLevel = Boolean(span.metrics[TOP_LEVEL_KEY])
|
|
42
|
+
if (isTopLevel) this.topLevelHits++
|
|
45
43
|
if (span.error) {
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
44
|
+
if (isTopLevel) this.topLevelErrorDistribution.accept(durationNs)
|
|
45
|
+
else this.nonTopLevelErrorDistribution.accept(durationNs)
|
|
48
46
|
} else {
|
|
49
|
-
this.
|
|
47
|
+
if (isTopLevel) this.topLevelOkDistribution.accept(durationNs)
|
|
48
|
+
else this.nonTopLevelOkDistribution.accept(durationNs)
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
toJSON () {
|
|
54
53
|
const {
|
|
55
|
-
name,
|
|
56
|
-
|
|
57
|
-
resource,
|
|
58
|
-
type,
|
|
59
|
-
statusCode,
|
|
60
|
-
synthetics,
|
|
61
|
-
method,
|
|
62
|
-
endpoint,
|
|
63
|
-
srvSrc,
|
|
54
|
+
name, service, resource, type, statusCode, synthetics, method, endpoint, srvSrc,
|
|
55
|
+
spanKind, rpcStatusCode,
|
|
64
56
|
} = this.aggKey
|
|
65
|
-
|
|
66
|
-
return {
|
|
57
|
+
const base = {
|
|
67
58
|
Name: name,
|
|
68
59
|
Service: service,
|
|
69
60
|
Resource: resource,
|
|
@@ -73,13 +64,34 @@ class SpanAggStats {
|
|
|
73
64
|
HTTPMethod: method,
|
|
74
65
|
HTTPEndpoint: endpoint,
|
|
75
66
|
srv_src: srvSrc,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
67
|
+
SpanKind: spanKind,
|
|
68
|
+
GRPCStatusCode: rpcStatusCode,
|
|
69
|
+
}
|
|
70
|
+
const rows = []
|
|
71
|
+
if (this.topLevelHits > 0) {
|
|
72
|
+
rows.push({
|
|
73
|
+
...base,
|
|
74
|
+
Hits: this.topLevelHits,
|
|
75
|
+
TopLevelHits: this.topLevelHits,
|
|
76
|
+
Errors: this.topLevelErrorDistribution.count,
|
|
77
|
+
Duration: this.topLevelOkDistribution.sum + this.topLevelErrorDistribution.sum,
|
|
78
|
+
OkSummary: this.topLevelOkDistribution.toProto(),
|
|
79
|
+
ErrorSummary: this.topLevelErrorDistribution.toProto(),
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
const nonTopLevelHits = this.hits - this.topLevelHits
|
|
83
|
+
if (nonTopLevelHits > 0) {
|
|
84
|
+
rows.push({
|
|
85
|
+
...base,
|
|
86
|
+
Hits: nonTopLevelHits,
|
|
87
|
+
TopLevelHits: 0,
|
|
88
|
+
Errors: this.nonTopLevelErrorDistribution.count,
|
|
89
|
+
Duration: this.nonTopLevelOkDistribution.sum + this.nonTopLevelErrorDistribution.sum,
|
|
90
|
+
OkSummary: this.nonTopLevelOkDistribution.toProto(), // TODO: custom proto encoding
|
|
91
|
+
ErrorSummary: this.nonTopLevelErrorDistribution.toProto(), // TODO: custom proto encoding
|
|
92
|
+
})
|
|
82
93
|
}
|
|
94
|
+
return rows
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
97
|
|
|
@@ -94,6 +106,12 @@ class SpanAggKey {
|
|
|
94
106
|
this.endpoint = span.meta[HTTP_ROUTE] || span.meta[HTTP_ENDPOINT] || ''
|
|
95
107
|
this.method = span.meta[HTTP_METHOD] || ''
|
|
96
108
|
this.srvSrc = span.meta[SVC_SRC_KEY] || ''
|
|
109
|
+
this.spanKind = span.meta[SPAN_KIND] || ''
|
|
110
|
+
// dd gRPC plugin sets a numeric code via setTag; OTel/manual sets a string name via meta.
|
|
111
|
+
const grpcCode = span.meta[GRPC_STATUS_CODE] ?? span.metrics?.[GRPC_STATUS_CODE]
|
|
112
|
+
this.rpcStatusCode = typeof grpcCode === 'number'
|
|
113
|
+
? (GRPC_STATUS_NAMES[grpcCode] ?? String(grpcCode))
|
|
114
|
+
: (grpcCode ?? '')
|
|
97
115
|
}
|
|
98
116
|
|
|
99
117
|
toString () {
|
|
@@ -107,6 +125,8 @@ class SpanAggKey {
|
|
|
107
125
|
this.method,
|
|
108
126
|
this.endpoint,
|
|
109
127
|
this.srvSrc,
|
|
128
|
+
this.spanKind,
|
|
129
|
+
this.rpcStatusCode,
|
|
110
130
|
].join(',')
|
|
111
131
|
}
|
|
112
132
|
}
|
|
@@ -137,57 +157,60 @@ class TimeBuckets extends Map {
|
|
|
137
157
|
class SpanStatsProcessor {
|
|
138
158
|
constructor ({
|
|
139
159
|
stats: {
|
|
140
|
-
enabled = false,
|
|
160
|
+
DD_TRACE_STATS_COMPUTATION_ENABLED: enabled = false,
|
|
141
161
|
interval = 10,
|
|
142
|
-
},
|
|
162
|
+
} = {},
|
|
143
163
|
hostname,
|
|
144
164
|
port,
|
|
145
165
|
url,
|
|
146
166
|
env,
|
|
147
167
|
tags,
|
|
148
|
-
version,
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
port,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
this.
|
|
157
|
-
this.bucketSizeNs = interval * 1e9
|
|
168
|
+
version: appVersion,
|
|
169
|
+
_DD_TRACE_METRICS_OTEL_FLUSH_INTERVAL: flushIntervalMs,
|
|
170
|
+
} = {}, otlpExporter) {
|
|
171
|
+
if (!otlpExporter) {
|
|
172
|
+
this.exporter = new SpanStatsExporter({ hostname, port, tags, url })
|
|
173
|
+
}
|
|
174
|
+
const intervalMs = otlpExporter ? (flushIntervalMs ?? 10_000) : interval * 1e3
|
|
175
|
+
this.interval = intervalMs / 1e3
|
|
176
|
+
this.bucketSizeNs = intervalMs * 1e6
|
|
158
177
|
this.buckets = new TimeBuckets()
|
|
159
178
|
this.hostname = os.hostname()
|
|
160
179
|
this.enabled = enabled
|
|
180
|
+
this.otlpExporter = otlpExporter || null
|
|
161
181
|
this.env = env
|
|
162
182
|
this.tags = tags || {}
|
|
163
183
|
this.sequence = 0
|
|
164
|
-
this.version =
|
|
184
|
+
this.version = appVersion
|
|
165
185
|
|
|
166
|
-
if (this.enabled) {
|
|
167
|
-
this.timer = setInterval(this.onInterval.bind(this),
|
|
186
|
+
if (this.enabled || this.otlpExporter) {
|
|
187
|
+
this.timer = setInterval(this.onInterval.bind(this), intervalMs)
|
|
168
188
|
this.timer.unref?.()
|
|
169
189
|
}
|
|
170
190
|
}
|
|
171
191
|
|
|
172
192
|
onInterval () {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
193
|
+
const drained = this.#drainBuckets()
|
|
194
|
+
|
|
195
|
+
if (this.enabled && !this.otlpExporter) {
|
|
196
|
+
this.exporter.export({
|
|
197
|
+
Hostname: this.hostname,
|
|
198
|
+
Env: this.env,
|
|
199
|
+
Version: this.version || version,
|
|
200
|
+
Stats: this.#toV06Payload(drained),
|
|
201
|
+
Lang: 'javascript',
|
|
202
|
+
TracerVersion: pkg.version,
|
|
203
|
+
RuntimeID: this.tags['runtime-id'],
|
|
204
|
+
Sequence: ++this.sequence,
|
|
205
|
+
ProcessTags: processTags.serialized,
|
|
206
|
+
})
|
|
207
|
+
} else if (this.otlpExporter && drained.length > 0) {
|
|
208
|
+
this.otlpExporter.export(drained, this.bucketSizeNs)
|
|
209
|
+
}
|
|
187
210
|
}
|
|
188
211
|
|
|
189
212
|
onSpanFinished (span) {
|
|
190
|
-
if (!this.enabled) return
|
|
213
|
+
if (!this.enabled && !this.otlpExporter) return
|
|
191
214
|
if (!span.metrics[TOP_LEVEL_KEY] && !span.metrics[MEASURED]) return
|
|
192
215
|
|
|
193
216
|
const spanEndNs = span.start + span.duration
|
|
@@ -198,27 +221,22 @@ class SpanStatsProcessor {
|
|
|
198
221
|
.record(span)
|
|
199
222
|
}
|
|
200
223
|
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
const serializedBuckets = []
|
|
204
|
-
|
|
224
|
+
#drainBuckets () {
|
|
225
|
+
const drained = []
|
|
205
226
|
for (const [timeNs, bucket] of this.buckets.entries()) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
for (const stats of bucket.values()) {
|
|
209
|
-
bucketAggStats.push(stats.toJSON())
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
serializedBuckets.push({
|
|
213
|
-
Start: timeNs,
|
|
214
|
-
Duration: bucketSizeNs,
|
|
215
|
-
Stats: bucketAggStats,
|
|
216
|
-
})
|
|
227
|
+
drained.push({ timeNs, bucket })
|
|
217
228
|
}
|
|
218
|
-
|
|
219
229
|
this.buckets.clear()
|
|
230
|
+
return drained
|
|
231
|
+
}
|
|
220
232
|
|
|
221
|
-
|
|
233
|
+
#toV06Payload (drained) {
|
|
234
|
+
const { bucketSizeNs } = this
|
|
235
|
+
return drained.map(({ timeNs, bucket }) => ({
|
|
236
|
+
Start: timeNs,
|
|
237
|
+
Duration: bucketSizeNs,
|
|
238
|
+
Stats: [...bucket.values()].flatMap(stats => stats.toJSON()),
|
|
239
|
+
}))
|
|
222
240
|
}
|
|
223
241
|
}
|
|
224
242
|
|
|
@@ -76,6 +76,7 @@ function logGenericError (message) {
|
|
|
76
76
|
*/
|
|
77
77
|
function configInfo () {
|
|
78
78
|
const url = config.url
|
|
79
|
+
const profilingEnabled = config.profiling.DD_PROFILING_ENABLED
|
|
79
80
|
|
|
80
81
|
return {
|
|
81
82
|
[inspect.custom] () {
|
|
@@ -104,7 +105,7 @@ function configInfo () {
|
|
|
104
105
|
...(config.tags && config.tags.version && { dd_version: config.tags.version }),
|
|
105
106
|
log_injection_enabled: !!config.logInjection,
|
|
106
107
|
runtime_metrics_enabled: !!config.runtimeMetrics,
|
|
107
|
-
profiling_enabled:
|
|
108
|
+
profiling_enabled: profilingEnabled === 'true' || profilingEnabled === 'auto',
|
|
108
109
|
appsec_enabled: config.appsec.enabled,
|
|
109
110
|
data_streams_enabled: !!config.dsmEnabled,
|
|
110
111
|
}
|
|
@@ -32,7 +32,7 @@ function waitAndSend (config, application, host) {
|
|
|
32
32
|
const [name, version, initialLoadModule] = dependency.split(' ')
|
|
33
33
|
// If a dependency is from the initial load, *always* send the event
|
|
34
34
|
// Otherwise, only send if dependencyCollection is enabled
|
|
35
|
-
const sendModule = isTrue(initialLoadModule) || config.telemetry
|
|
35
|
+
const sendModule = isTrue(initialLoadModule) || config.telemetry.DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED
|
|
36
36
|
|
|
37
37
|
savedDependenciesToSend.delete(dependency)
|
|
38
38
|
|
|
@@ -11,7 +11,10 @@ const { sendData } = require('./send-data')
|
|
|
11
11
|
*/
|
|
12
12
|
/**
|
|
13
13
|
* @typedef {import('./send-data').TelemetryConfig & {
|
|
14
|
-
* appsec
|
|
14
|
+
* appsec: {
|
|
15
|
+
* DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED: boolean,
|
|
16
|
+
* DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT: number
|
|
17
|
+
* }
|
|
15
18
|
* }} TelemetryConfig
|
|
16
19
|
*/
|
|
17
20
|
|
|
@@ -142,8 +145,7 @@ function flushAndSend () {
|
|
|
142
145
|
for (const [key, endpoint] of pendingEndpoints) {
|
|
143
146
|
batchEndpoints.push(endpoint)
|
|
144
147
|
pendingEndpoints.delete(key)
|
|
145
|
-
|
|
146
|
-
if (batchEndpoints.length >= (config.appsec?.apiSecurity?.endpointCollectionMessageLimit ?? 0)) break
|
|
148
|
+
if (batchEndpoints.length >= config.appsec.DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT) break
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
const payloadObj = {
|
|
@@ -184,7 +186,7 @@ function flushAndSend () {
|
|
|
184
186
|
* @param {import('./send-data').SendDataCallback} updateRetryDataFunction
|
|
185
187
|
*/
|
|
186
188
|
function start (_config, _application, _host, getRetryDataFunction, updateRetryDataFunction) {
|
|
187
|
-
if (!_config.appsec
|
|
189
|
+
if (!_config.appsec.DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED) return
|
|
188
190
|
|
|
189
191
|
config = _config
|
|
190
192
|
application = _application
|
|
@@ -5,14 +5,14 @@ let telemetry
|
|
|
5
5
|
// Lazy load the telemetry module to avoid the performance impact of loading it unconditionally
|
|
6
6
|
module.exports = {
|
|
7
7
|
start (config, ...args) {
|
|
8
|
-
if (!config.telemetry.
|
|
8
|
+
if (!config.telemetry.DD_INSTRUMENTATION_TELEMETRY_ENABLED) return
|
|
9
9
|
telemetry ??= require('./telemetry')
|
|
10
10
|
telemetry.start(config, ...args)
|
|
11
11
|
},
|
|
12
12
|
// This might be called before `start` so we have to trigger loading the
|
|
13
13
|
// underlying module here as well.
|
|
14
14
|
updateConfig (changes, config, ...args) {
|
|
15
|
-
if (!config.telemetry.
|
|
15
|
+
if (!config.telemetry.DD_INSTRUMENTATION_TELEMETRY_ENABLED) return
|
|
16
16
|
telemetry ??= require('./telemetry')
|
|
17
17
|
telemetry.updateConfig(changes, config, ...args)
|
|
18
18
|
},
|
|
@@ -87,12 +87,12 @@ function getHeaders (config, application, reqType) {
|
|
|
87
87
|
if (config.DD_ROOT_JS_SESSION_ID) {
|
|
88
88
|
headers['dd-root-session-id'] = config.DD_ROOT_JS_SESSION_ID
|
|
89
89
|
}
|
|
90
|
-
const debug = config.telemetry && config.telemetry.
|
|
90
|
+
const debug = config.telemetry && config.telemetry.DD_TELEMETRY_DEBUG
|
|
91
91
|
if (debug) {
|
|
92
92
|
headers['dd-telemetry-debug-enabled'] = 'true'
|
|
93
93
|
}
|
|
94
|
-
if (config.
|
|
95
|
-
headers['dd-api-key'] = config.
|
|
94
|
+
if (config.DD_API_KEY) {
|
|
95
|
+
headers['dd-api-key'] = config.DD_API_KEY
|
|
96
96
|
}
|
|
97
97
|
return headers
|
|
98
98
|
}
|
|
@@ -137,16 +137,16 @@ function sendData (config, application, host, reqType, payload = {}, cb = () =>
|
|
|
137
137
|
hostname,
|
|
138
138
|
port,
|
|
139
139
|
isCiVisibility,
|
|
140
|
-
|
|
140
|
+
testOptimization,
|
|
141
141
|
} = config
|
|
142
142
|
|
|
143
143
|
let url = config.url
|
|
144
144
|
|
|
145
|
-
const isCiVisibilityAgentlessMode = isCiVisibility && DD_CIVISIBILITY_AGENTLESS_ENABLED
|
|
145
|
+
const isCiVisibilityAgentlessMode = isCiVisibility && testOptimization.DD_CIVISIBILITY_AGENTLESS_ENABLED
|
|
146
146
|
|
|
147
147
|
if (isCiVisibilityAgentlessMode) {
|
|
148
148
|
try {
|
|
149
|
-
url =
|
|
149
|
+
url = testOptimization.DD_CIVISIBILITY_AGENTLESS_URL ?? new URL(getAgentlessTelemetryEndpoint(config.site))
|
|
150
150
|
} catch (err) {
|
|
151
151
|
log.error('Telemetry endpoint url is invalid', err)
|
|
152
152
|
// No point to do the request if the URL is invalid
|
|
@@ -176,7 +176,7 @@ function sendData (config, application, host, reqType, payload = {}, cb = () =>
|
|
|
176
176
|
})
|
|
177
177
|
|
|
178
178
|
request(data, options, (error) => {
|
|
179
|
-
if (error && config.
|
|
179
|
+
if (error && config.DD_API_KEY && config.site) {
|
|
180
180
|
if (agentTelemetry) {
|
|
181
181
|
log.warn('Agent telemetry failed, started agentless telemetry')
|
|
182
182
|
agentTelemetry = false
|
|
@@ -189,7 +189,7 @@ function sendData (config, application, host, reqType, payload = {}, cb = () =>
|
|
|
189
189
|
log.error('Invalid Telemetry URL')
|
|
190
190
|
return
|
|
191
191
|
}
|
|
192
|
-
const backendHeader = { ...options.headers, 'DD-API-KEY': config.
|
|
192
|
+
const backendHeader = { ...options.headers, 'DD-API-KEY': config.DD_API_KEY }
|
|
193
193
|
const backendOptions = {
|
|
194
194
|
...options,
|
|
195
195
|
url: backendUrl,
|
|
@@ -40,7 +40,7 @@ function onChildProcessStart (context) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function start (config) {
|
|
43
|
-
if (!config.telemetry
|
|
43
|
+
if (!config.telemetry.DD_INSTRUMENTATION_TELEMETRY_ENABLED || subscribed) return
|
|
44
44
|
subscribed = true
|
|
45
45
|
|
|
46
46
|
runtimeId = config.DD_ROOT_JS_SESSION_ID || config.tags['runtime-id']
|
|
@@ -154,7 +154,7 @@ function getProducts (config) {
|
|
|
154
154
|
},
|
|
155
155
|
profiler: {
|
|
156
156
|
version: tracerVersion,
|
|
157
|
-
enabled: profilingEnabledToBoolean(config.profiling.
|
|
157
|
+
enabled: profilingEnabledToBoolean(config.profiling.DD_PROFILING_ENABLED),
|
|
158
158
|
},
|
|
159
159
|
}
|
|
160
160
|
}
|
|
@@ -193,7 +193,7 @@ function appStarted (config) {
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
function appClosing () {
|
|
196
|
-
if (!config?.telemetry
|
|
196
|
+
if (!config?.telemetry.DD_INSTRUMENTATION_TELEMETRY_ENABLED) {
|
|
197
197
|
return
|
|
198
198
|
}
|
|
199
199
|
// Give chance to listeners to update metrics before shutting down.
|
|
@@ -244,7 +244,7 @@ function createHostObject () {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
function getTelemetryData () {
|
|
247
|
-
return { config, application, host, heartbeatInterval: config?.telemetry.
|
|
247
|
+
return { config, application, host, heartbeatInterval: config?.telemetry.DD_TELEMETRY_HEARTBEAT_INTERVAL }
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
/**
|
|
@@ -291,7 +291,7 @@ function heartbeat (config, application) {
|
|
|
291
291
|
|
|
292
292
|
const { reqType, payload } = createPayload('app-heartbeat')
|
|
293
293
|
sendData(config, application, host, reqType, payload, updateRetryData)
|
|
294
|
-
}, config.telemetry.
|
|
294
|
+
}, config.telemetry.DD_TELEMETRY_HEARTBEAT_INTERVAL).unref?.()
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
/** @param {import('../config/config-base')} config */
|
|
@@ -307,7 +307,7 @@ function extendedHeartbeat (config) {
|
|
|
307
307
|
heartbeatFailedDependencies = []
|
|
308
308
|
}
|
|
309
309
|
sendData(config, application, host, 'app-extended-heartbeat', appPayload)
|
|
310
|
-
}, config.telemetry.
|
|
310
|
+
}, config.telemetry.DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL).unref?.()
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
/**
|
|
@@ -315,8 +315,8 @@ function extendedHeartbeat (config) {
|
|
|
315
315
|
* @param {PluginManager} thePluginManager
|
|
316
316
|
*/
|
|
317
317
|
function start (aConfig, thePluginManager) {
|
|
318
|
-
if (!aConfig.telemetry.
|
|
319
|
-
if (aConfig.appsec.
|
|
318
|
+
if (!aConfig.telemetry.DD_INSTRUMENTATION_TELEMETRY_ENABLED) {
|
|
319
|
+
if (aConfig.appsec.DD_APPSEC_SCA_ENABLED) {
|
|
320
320
|
logger.warn('DD_APPSEC_SCA_ENABLED requires enabling telemetry to work.')
|
|
321
321
|
}
|
|
322
322
|
|
|
@@ -347,7 +347,7 @@ function start (aConfig, thePluginManager) {
|
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
function updateIntegrations () {
|
|
350
|
-
if (!config?.telemetry.
|
|
350
|
+
if (!config?.telemetry.DD_INSTRUMENTATION_TELEMETRY_ENABLED) {
|
|
351
351
|
return
|
|
352
352
|
}
|
|
353
353
|
const integrations = getIntegrations()
|
|
@@ -367,7 +367,7 @@ let latestConfiguration = []
|
|
|
367
367
|
* @param {import('../config/config-base')} config
|
|
368
368
|
*/
|
|
369
369
|
function updateConfig (configuration, config) {
|
|
370
|
-
if (!config.telemetry.
|
|
370
|
+
if (!config.telemetry.DD_INSTRUMENTATION_TELEMETRY_ENABLED) return
|
|
371
371
|
|
|
372
372
|
logger.trace(configuration)
|
|
373
373
|
|