dd-trace 5.82.0 → 5.84.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 +77 -79
- package/ci/init.js +6 -6
- package/index.d.ts +213 -4
- package/loader-hook.mjs +1 -1
- package/package.json +59 -56
- package/packages/datadog-core/src/storage.js +7 -7
- package/packages/datadog-esbuild/index.js +6 -0
- package/packages/datadog-instrumentations/src/ai.js +7 -3
- package/packages/datadog-instrumentations/src/child_process.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +1 -1
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/instrumentations.js +4 -3
- package/packages/datadog-instrumentations/src/helpers/register.js +3 -7
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +6 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +73 -16
- package/packages/datadog-instrumentations/src/http/client.js +2 -2
- package/packages/datadog-instrumentations/src/jest.js +124 -64
- package/packages/datadog-instrumentations/src/koa.js +2 -1
- package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/worker.js +1 -1
- package/packages/datadog-instrumentations/src/mocha.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/mysql2.js +2 -2
- package/packages/datadog-instrumentations/src/net.js +13 -5
- package/packages/datadog-instrumentations/src/nyc.js +1 -1
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -4
- package/packages/datadog-instrumentations/src/pg.js +4 -2
- package/packages/datadog-instrumentations/src/playwright.js +15 -11
- package/packages/datadog-instrumentations/src/selenium.js +2 -2
- package/packages/datadog-instrumentations/src/undici.js +12 -1
- package/packages/datadog-plugin-aws-sdk/src/base.js +4 -4
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +2 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +2 -2
- package/packages/datadog-plugin-cucumber/src/index.js +35 -34
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -2
- package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -2
- package/packages/datadog-plugin-express/src/code_origin.js +21 -15
- package/packages/datadog-plugin-fastify/src/code_origin.js +17 -4
- package/packages/datadog-plugin-jest/src/index.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +26 -26
- package/packages/datadog-plugin-undici/src/index.js +305 -2
- package/packages/datadog-plugin-vitest/src/index.js +5 -5
- package/packages/datadog-shimmer/src/shimmer.js +2 -5
- package/packages/dd-trace/index.js +19 -0
- package/packages/dd-trace/src/agent/info.js +57 -0
- package/packages/dd-trace/src/agent/url.js +28 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +47 -7
- package/packages/dd-trace/src/appsec/rasp/index.js +2 -4
- package/packages/dd-trace/src/azure_metadata.js +8 -3
- package/packages/dd-trace/src/baggage.js +36 -11
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +5 -1
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +5 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +5 -11
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -4
- package/packages/dd-trace/src/ci-visibility/telemetry.js +6 -2
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
- package/packages/dd-trace/src/{config_defaults.js → config/defaults.js} +3 -3
- package/packages/dd-trace/src/{config-helper.js → config/helper.js} +88 -15
- package/packages/dd-trace/src/{config.js → config/index.js} +107 -46
- package/packages/dd-trace/src/config/remote_config.js +188 -19
- package/packages/dd-trace/src/{config_stable.js → config/stable.js} +20 -32
- package/packages/dd-trace/src/{supported-configurations.json → config/supported-configurations.json} +3 -1
- package/packages/dd-trace/src/crashtracking/crashtracker.js +2 -5
- package/packages/dd-trace/src/datastreams/processor.js +1 -1
- package/packages/dd-trace/src/datastreams/writer.js +2 -8
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -7
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +10 -11
- package/packages/dd-trace/src/debugger/devtools_client/send.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +1 -1
- package/packages/dd-trace/src/debugger/index.js +83 -15
- package/packages/dd-trace/src/dogstatsd.js +5 -11
- package/packages/dd-trace/src/encode/0.4.js +2 -2
- package/packages/dd-trace/src/exporter.js +1 -1
- package/packages/dd-trace/src/exporters/agent/index.js +5 -11
- package/packages/dd-trace/src/exporters/agent/writer.js +12 -16
- package/packages/dd-trace/src/exporters/common/{agent-info-exporter.js → buffering-exporter.js} +10 -37
- package/packages/dd-trace/src/exporters/common/docker.js +2 -2
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/common/util.js +2 -2
- package/packages/dd-trace/src/exporters/span-stats/index.js +3 -10
- package/packages/dd-trace/src/flare/index.js +1 -1
- package/packages/dd-trace/src/guardrails/telemetry.js +1 -1
- package/packages/dd-trace/src/index.js +4 -4
- package/packages/dd-trace/src/lambda/handler.js +2 -2
- package/packages/dd-trace/src/lambda/index.js +2 -2
- package/packages/dd-trace/src/lambda/runtime/patch.js +2 -2
- package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +8 -1
- package/packages/dd-trace/src/llmobs/index.js +2 -2
- package/packages/dd-trace/src/llmobs/noop.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +3 -4
- package/packages/dd-trace/src/llmobs/sdk.js +33 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +17 -7
- package/packages/dd-trace/src/llmobs/tagger.js +175 -1
- package/packages/dd-trace/src/llmobs/writers/base.js +118 -45
- package/packages/dd-trace/src/llmobs/writers/spans.js +4 -3
- package/packages/dd-trace/src/llmobs/writers/util.js +3 -9
- package/packages/dd-trace/src/log/index.js +50 -35
- package/packages/dd-trace/src/log/writer.js +13 -78
- package/packages/dd-trace/src/noop/proxy.js +3 -3
- package/packages/dd-trace/src/openfeature/writers/base.js +9 -16
- package/packages/dd-trace/src/openfeature/writers/util.js +3 -8
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +48 -6
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +45 -21
- package/packages/dd-trace/src/opentracing/span.js +4 -4
- package/packages/dd-trace/src/plugin_manager.js +8 -6
- package/packages/dd-trace/src/plugins/util/ci.js +5 -8
- package/packages/dd-trace/src/plugins/util/git-cache.js +3 -3
- package/packages/dd-trace/src/plugins/util/test.js +1 -1
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +41 -43
- package/packages/dd-trace/src/profiler.js +4 -39
- package/packages/dd-trace/src/profiling/config.js +74 -34
- package/packages/dd-trace/src/profiling/exporter_cli.js +5 -5
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +9 -2
- package/packages/dd-trace/src/profiling/index.js +1 -1
- package/packages/dd-trace/src/profiling/libuv-size.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +57 -2
- package/packages/dd-trace/src/proxy.js +34 -5
- package/packages/dd-trace/src/remote_config/capabilities.js +4 -0
- package/packages/dd-trace/src/remote_config/index.js +2 -7
- package/packages/dd-trace/src/ritm.js +8 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
- package/packages/dd-trace/src/serverless.js +2 -2
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/startup-log.js +7 -16
- package/packages/dd-trace/src/telemetry/endpoints.js +67 -5
- package/packages/dd-trace/src/telemetry/send-data.js +103 -4
- package/packages/dd-trace/src/telemetry/telemetry.js +229 -110
- package/vendor/dist/@isaacs/ttlcache/index.js +1 -1
- package/vendor/dist/esquery/index.js +1 -1
- package/vendor/dist/meriyah/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- /package/packages/dd-trace/src/{git_properties.js → config/git_properties.js} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const { getValueFromEnvSources } = require('./config/helper')
|
|
3
4
|
const NoopProxy = require('./noop/proxy')
|
|
4
5
|
const DatadogTracer = require('./tracer')
|
|
5
6
|
const getConfig = require('./config')
|
|
@@ -130,7 +131,10 @@ class Tracer extends NoopProxy {
|
|
|
130
131
|
const rc = new RemoteConfig(config)
|
|
131
132
|
|
|
132
133
|
const tracingRemoteConfig = require('./config/remote_config')
|
|
133
|
-
tracingRemoteConfig.enable(rc, config,
|
|
134
|
+
tracingRemoteConfig.enable(rc, config, () => {
|
|
135
|
+
this.#updateTracing(config)
|
|
136
|
+
this.#updateDebugger(config, rc)
|
|
137
|
+
})
|
|
134
138
|
|
|
135
139
|
rc.setProductHandler('AGENT_CONFIG', (action, conf) => {
|
|
136
140
|
if (!conf?.name?.startsWith('flare-log-level.')) return
|
|
@@ -183,7 +187,7 @@ class Tracer extends NoopProxy {
|
|
|
183
187
|
runtimeMetrics.start(config)
|
|
184
188
|
}
|
|
185
189
|
|
|
186
|
-
this
|
|
190
|
+
this.#updateTracing(config)
|
|
187
191
|
|
|
188
192
|
this._modules.rewriter.enable(config)
|
|
189
193
|
|
|
@@ -196,7 +200,7 @@ class Tracer extends NoopProxy {
|
|
|
196
200
|
this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
|
|
197
201
|
}
|
|
198
202
|
if (config.ciVisAgentlessLogSubmissionEnabled) {
|
|
199
|
-
if (
|
|
203
|
+
if (getValueFromEnvSources('DD_API_KEY')) {
|
|
200
204
|
const LogSubmissionPlugin = require('./ci-visibility/log-submission/log-submission-plugin')
|
|
201
205
|
const automaticLogPlugin = new LogSubmissionPlugin(this)
|
|
202
206
|
automaticLogPlugin.configure({ ...config, enabled: true })
|
|
@@ -242,7 +246,7 @@ class Tracer extends NoopProxy {
|
|
|
242
246
|
}
|
|
243
247
|
}
|
|
244
248
|
|
|
245
|
-
|
|
249
|
+
#updateTracing (config) {
|
|
246
250
|
if (config.tracing !== false) {
|
|
247
251
|
if (config.appsec.enabled) {
|
|
248
252
|
this._modules.appsec.enable(config)
|
|
@@ -287,6 +291,31 @@ class Tracer extends NoopProxy {
|
|
|
287
291
|
}
|
|
288
292
|
}
|
|
289
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Updates the debugger (Dynamic Instrumentation) state based on remote config changes.
|
|
296
|
+
* Handles starting, stopping, and reconfiguring the debugger dynamically.
|
|
297
|
+
*
|
|
298
|
+
* @param {object} config - The tracer configuration object
|
|
299
|
+
* @param {object} rc - The RemoteConfig instance
|
|
300
|
+
*/
|
|
301
|
+
#updateDebugger (config, rc) {
|
|
302
|
+
const shouldBeEnabled = config.dynamicInstrumentation.enabled
|
|
303
|
+
const isCurrentlyStarted = DynamicInstrumentation.isStarted()
|
|
304
|
+
|
|
305
|
+
if (shouldBeEnabled) {
|
|
306
|
+
if (isCurrentlyStarted) {
|
|
307
|
+
log.debug('[proxy] Reconfiguring Dynamic Instrumentation via remote config')
|
|
308
|
+
DynamicInstrumentation.configure(config)
|
|
309
|
+
} else {
|
|
310
|
+
log.debug('[proxy] Starting Dynamic Instrumentation via remote config')
|
|
311
|
+
DynamicInstrumentation.start(config, rc)
|
|
312
|
+
}
|
|
313
|
+
} else if (isCurrentlyStarted) {
|
|
314
|
+
log.debug('[proxy] Stopping Dynamic Instrumentation via remote config')
|
|
315
|
+
DynamicInstrumentation.stop()
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
290
319
|
/**
|
|
291
320
|
* @override
|
|
292
321
|
*/
|
|
@@ -31,9 +31,13 @@ module.exports = {
|
|
|
31
31
|
ASM_NETWORK_FINGERPRINT: 1n << 34n,
|
|
32
32
|
ASM_HEADER_FINGERPRINT: 1n << 35n,
|
|
33
33
|
ASM_RASP_CMDI: 1n << 37n,
|
|
34
|
+
APM_TRACING_ENABLE_DYNAMIC_INSTRUMENTATION: 1n << 38n,
|
|
35
|
+
APM_TRACING_ENABLE_CODE_ORIGIN: 1n << 40n,
|
|
36
|
+
APM_TRACING_ENABLE_LIVE_DEBUGGING: 1n << 41n,
|
|
34
37
|
ASM_DD_MULTICONFIG: 1n << 42n,
|
|
35
38
|
ASM_TRACE_TAGGING_RULES: 1n << 43n,
|
|
36
39
|
ASM_EXTENDED_DATA_COLLECTION: 1n << 44n,
|
|
40
|
+
APM_TRACING_MULTICONFIG: 1n << 45n,
|
|
37
41
|
FFE_FLAG_CONFIGURATION_RULES: 1n << 46n,
|
|
38
42
|
/*
|
|
39
43
|
DO NOT ADD ARBITRARY CAPABILITIES IN YOUR CODE
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { URL, format } = require('url')
|
|
4
3
|
const uuid = require('../../../../vendor/dist/crypto-randomuuid')
|
|
5
4
|
const tracerVersion = require('../../../../package.json').version
|
|
6
5
|
const request = require('../exporters/common/request')
|
|
@@ -8,7 +7,7 @@ const log = require('../log')
|
|
|
8
7
|
const { getExtraServices } = require('../service-naming/extra-services')
|
|
9
8
|
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
10
9
|
const tagger = require('../tagger')
|
|
11
|
-
const
|
|
10
|
+
const { getAgentUrl } = require('../agent/url')
|
|
12
11
|
const processTags = require('../process-tags')
|
|
13
12
|
const Scheduler = require('./scheduler')
|
|
14
13
|
const { UNACKNOWLEDGED, ACKNOWLEDGED, ERROR } = require('./apply_states')
|
|
@@ -29,11 +28,7 @@ class RemoteConfig {
|
|
|
29
28
|
constructor (config) {
|
|
30
29
|
const pollInterval = Math.floor(config.remoteConfig.pollInterval * 1000)
|
|
31
30
|
|
|
32
|
-
this.url = config
|
|
33
|
-
protocol: 'http:',
|
|
34
|
-
hostname: config.hostname || defaults.hostname,
|
|
35
|
-
port: config.port
|
|
36
|
-
}))
|
|
31
|
+
this.url = getAgentUrl(config)
|
|
37
32
|
|
|
38
33
|
tagger.add(config.tags, {
|
|
39
34
|
'_dd.rc.client_id': clientId
|
|
@@ -7,8 +7,8 @@ const Module = require('module')
|
|
|
7
7
|
const dc = require('dc-polyfill')
|
|
8
8
|
|
|
9
9
|
const parse = require('../../../vendor/dist/module-details-from-path')
|
|
10
|
-
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
11
10
|
const { isRelativeRequire } = require('../../datadog-instrumentations/src/helpers/shared-utils')
|
|
11
|
+
const { getEnvironmentVariable, getValueFromEnvSources } = require('./config/helper')
|
|
12
12
|
|
|
13
13
|
const origRequire = Module.prototype.require
|
|
14
14
|
// derived from require-in-the-middle@3 with tweaks
|
|
@@ -63,6 +63,7 @@ function Hook (modules, options, onrequire) {
|
|
|
63
63
|
*/
|
|
64
64
|
let filename
|
|
65
65
|
try {
|
|
66
|
+
// @ts-expect-error Module._resolveFilename is not typed
|
|
66
67
|
filename = Module._resolveFilename(request, this)
|
|
67
68
|
} catch {
|
|
68
69
|
return _origRequire.apply(this, arguments)
|
|
@@ -71,9 +72,10 @@ function Hook (modules, options, onrequire) {
|
|
|
71
72
|
let name, basedir, hooks
|
|
72
73
|
// return known patched modules immediately
|
|
73
74
|
if (cache[filename]) {
|
|
75
|
+
const externalCacheEntry = require.cache[filename]
|
|
74
76
|
// require.cache was potentially altered externally
|
|
75
|
-
if (
|
|
76
|
-
return
|
|
77
|
+
if (externalCacheEntry && externalCacheEntry.exports !== cache[filename].original) {
|
|
78
|
+
return externalCacheEntry.exports
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
return cache[filename].exports
|
|
@@ -113,7 +115,7 @@ function Hook (modules, options, onrequire) {
|
|
|
113
115
|
name = filename
|
|
114
116
|
} else {
|
|
115
117
|
const inAWSLambda = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') !== undefined
|
|
116
|
-
const hasLambdaHandler =
|
|
118
|
+
const hasLambdaHandler = getValueFromEnvSources('DD_LAMBDA_HANDLER') !== undefined
|
|
117
119
|
const segments = filename.split(path.sep)
|
|
118
120
|
const filenameFromNodeModule = segments.includes('node_modules')
|
|
119
121
|
// decide how to assign the stat
|
|
@@ -127,6 +129,7 @@ function Hook (modules, options, onrequire) {
|
|
|
127
129
|
hooks = moduleHooks[name]
|
|
128
130
|
if (!hooks) return exports // abort if module name isn't on whitelist
|
|
129
131
|
|
|
132
|
+
// @ts-expect-error Module._resolveLookupPaths is not typed
|
|
130
133
|
const paths = Module._resolveLookupPaths(name, this, true)
|
|
131
134
|
if (!paths) {
|
|
132
135
|
// abort if _resolveLookupPaths return null
|
|
@@ -135,6 +138,7 @@ function Hook (modules, options, onrequire) {
|
|
|
135
138
|
|
|
136
139
|
let res
|
|
137
140
|
try {
|
|
141
|
+
// @ts-expect-error Module._findPath is not typed
|
|
138
142
|
res = Module._findPath(name, [basedir, ...paths])
|
|
139
143
|
} catch {
|
|
140
144
|
// case where the file specified in package.json "main" doesn't exist
|
|
@@ -8,12 +8,12 @@ const process = require('process')
|
|
|
8
8
|
const { performance, PerformanceObserver, monitorEventLoopDelay } = require('perf_hooks')
|
|
9
9
|
const { DogStatsDClient, MetricsAggregationClient } = require('../dogstatsd')
|
|
10
10
|
const log = require('../log')
|
|
11
|
-
const {
|
|
11
|
+
const { getValueFromEnvSources } = require('../config/helper')
|
|
12
12
|
|
|
13
13
|
const { NODE_MAJOR } = require('../../../../version')
|
|
14
14
|
// TODO: This environment variable may not be changed, since the agent expects a flush every ten seconds.
|
|
15
15
|
// It is only a variable for testing. Think about alternatives.
|
|
16
|
-
const DD_RUNTIME_METRICS_FLUSH_INTERVAL =
|
|
16
|
+
const DD_RUNTIME_METRICS_FLUSH_INTERVAL = getValueFromEnvSources('DD_RUNTIME_METRICS_FLUSH_INTERVAL') ?? '10000'
|
|
17
17
|
const INTERVAL = Number.parseInt(DD_RUNTIME_METRICS_FLUSH_INTERVAL, 10)
|
|
18
18
|
|
|
19
19
|
const eventLoopDelayResolution = 4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { getEnvironmentVariable } = require('./config
|
|
3
|
+
const { getEnvironmentVariable, getValueFromEnvSources } = require('./config/helper')
|
|
4
4
|
const { isFalse } = require('./util')
|
|
5
5
|
|
|
6
6
|
function getIsGCPFunction () {
|
|
@@ -19,7 +19,7 @@ function getIsGCPFunction () {
|
|
|
19
19
|
* PUSH: GCP sends HTTP POST requests to the service with message data in headers.
|
|
20
20
|
*/
|
|
21
21
|
function enableGCPPubSubPushSubscription () {
|
|
22
|
-
const isGCPPubSubPushSubscriptionEnabled =
|
|
22
|
+
const isGCPPubSubPushSubscriptionEnabled = getValueFromEnvSources('DD_TRACE_GCP_PUBSUB_PUSH_ENABLED')
|
|
23
23
|
return getEnvironmentVariable('K_SERVICE') !== undefined && !isFalse(isGCPPubSubPushSubscriptionEnabled)
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -4,8 +4,8 @@ const log = require('./log')
|
|
|
4
4
|
const spanFormat = require('./span_format')
|
|
5
5
|
const SpanSampler = require('./span_sampler')
|
|
6
6
|
const GitMetadataTagger = require('./git_metadata_tagger')
|
|
7
|
-
const { getEnvironmentVariable } = require('./config-helper')
|
|
8
7
|
const processTags = require('./process-tags')
|
|
8
|
+
const { getValueFromEnvSources } = require('./config/helper')
|
|
9
9
|
|
|
10
10
|
const startedSpans = new WeakSet()
|
|
11
11
|
const finishedSpans = new WeakSet()
|
|
@@ -88,7 +88,7 @@ class SpanProcessor {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
_erase (trace, active) {
|
|
91
|
-
if (
|
|
91
|
+
if (getValueFromEnvSources('DD_TRACE_EXPERIMENTAL_STATE_TRACKING') === 'true') {
|
|
92
92
|
const started = new Set()
|
|
93
93
|
const startedIds = new Set()
|
|
94
94
|
const finished = new Set()
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const os = require('os')
|
|
4
4
|
const { inspect } = require('util')
|
|
5
|
-
|
|
6
5
|
const tracerVersion = require('../../../package.json').version
|
|
7
|
-
const
|
|
6
|
+
const { getAgentUrl } = require('./agent/url')
|
|
8
7
|
const { info, warn } = require('./log/writer')
|
|
9
8
|
|
|
10
9
|
const errors = {}
|
|
@@ -15,23 +14,15 @@ let samplingRules = []
|
|
|
15
14
|
let alreadyRan = false
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
|
-
* @param {{
|
|
17
|
+
* @param {{ status: number, message: string } } [agentError]
|
|
19
18
|
*/
|
|
20
|
-
function startupLog (
|
|
21
|
-
if (!config || !pluginManager) {
|
|
22
|
-
return
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (alreadyRan) {
|
|
19
|
+
function startupLog (agentError) {
|
|
20
|
+
if (alreadyRan || !config || !config.startupLogs || !pluginManager) {
|
|
26
21
|
return
|
|
27
22
|
}
|
|
28
23
|
|
|
29
24
|
alreadyRan = true
|
|
30
25
|
|
|
31
|
-
if (!config.startupLogs) {
|
|
32
|
-
return
|
|
33
|
-
}
|
|
34
|
-
|
|
35
26
|
const out = tracerInfo()
|
|
36
27
|
|
|
37
28
|
if (agentError) {
|
|
@@ -42,8 +33,8 @@ function startupLog ({ agentError } = {}) {
|
|
|
42
33
|
if (agentError) {
|
|
43
34
|
warn('DATADOG TRACER DIAGNOSTIC - Agent Error: ' + agentError.message)
|
|
44
35
|
errors.agentError = {
|
|
45
|
-
code: agentError.
|
|
46
|
-
message: `Agent Error
|
|
36
|
+
code: agentError.status,
|
|
37
|
+
message: `Agent Error: ${agentError.message}`
|
|
47
38
|
}
|
|
48
39
|
}
|
|
49
40
|
}
|
|
@@ -52,7 +43,7 @@ function startupLog ({ agentError } = {}) {
|
|
|
52
43
|
* @returns {Record<string, unknown>}
|
|
53
44
|
*/
|
|
54
45
|
function tracerInfo () {
|
|
55
|
-
const url = config
|
|
46
|
+
const url = getAgentUrl(config)
|
|
56
47
|
|
|
57
48
|
const out = {
|
|
58
49
|
[inspect.custom] () {
|
|
@@ -3,35 +3,75 @@
|
|
|
3
3
|
const dc = require('dc-polyfill')
|
|
4
4
|
const { sendData } = require('./send-data')
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* RetryData is information that `telemetry.js` keeps in-memory to be merged into the next payload.
|
|
8
|
+
*
|
|
9
|
+
* @callback GetRetryData
|
|
10
|
+
* @returns {{ payload: Record<string, unknown>, reqType: string } | null}
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {import('./send-data').TelemetryConfig & {
|
|
14
|
+
* appsec?: { apiSecurity?: { endpointCollectionEnabled?: boolean, endpointCollectionMessageLimit?: number } }
|
|
15
|
+
* }} TelemetryConfig
|
|
16
|
+
*/
|
|
17
|
+
|
|
6
18
|
const fastifyRouteCh = dc.channel('apm:fastify:route:added')
|
|
7
19
|
const expressRouteCh = dc.channel('apm:express:route:added')
|
|
8
20
|
const routerRouteCh = dc.channel('apm:router:route:added')
|
|
9
21
|
|
|
22
|
+
/** @type {TelemetryConfig} */
|
|
10
23
|
let config
|
|
24
|
+
|
|
25
|
+
/** @type {import('./send-data').TelemetryApplication} */
|
|
11
26
|
let application
|
|
27
|
+
|
|
28
|
+
/** @type {import('./send-data').TelemetryHost} */
|
|
12
29
|
let host
|
|
30
|
+
|
|
31
|
+
/** @type {GetRetryData} */
|
|
13
32
|
let getRetryData
|
|
33
|
+
|
|
34
|
+
/** @type {import('./send-data').SendDataCallback} */
|
|
14
35
|
let updateRetryData
|
|
15
36
|
|
|
16
37
|
/**
|
|
17
38
|
* Keep track of endpoints that still need to be sent.
|
|
18
39
|
* Map key is `${METHOD} ${PATH}`, value is { method, path, operationName }
|
|
19
40
|
*/
|
|
41
|
+
/** @type {Map<string, { method: string, path: string, operationName: string }>} */
|
|
20
42
|
const pendingEndpoints = new Map()
|
|
43
|
+
|
|
44
|
+
/** @type {Set<string>} */
|
|
21
45
|
const wildcardEndpoints = new Set()
|
|
22
46
|
let flushScheduled = false
|
|
23
47
|
let isFirstPayload = true
|
|
24
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @param {string} method
|
|
51
|
+
* @param {string} path
|
|
52
|
+
* @returns {string}
|
|
53
|
+
*/
|
|
25
54
|
function endpointKey (method, path) {
|
|
26
55
|
return `${method.toUpperCase()} ${path}`
|
|
27
56
|
}
|
|
28
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @returns {void}
|
|
60
|
+
*/
|
|
29
61
|
function scheduleFlush () {
|
|
30
62
|
if (flushScheduled) return
|
|
31
63
|
flushScheduled = true
|
|
32
|
-
setImmediate(
|
|
64
|
+
// this used to be setImmediate() instead, but it was making the system test flaky
|
|
65
|
+
// don't ask me why
|
|
66
|
+
setTimeout(flushAndSend).unref()
|
|
33
67
|
}
|
|
34
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @param {string} method
|
|
71
|
+
* @param {string} path
|
|
72
|
+
* @param {string} operationName
|
|
73
|
+
* @returns {void}
|
|
74
|
+
*/
|
|
35
75
|
function recordEndpoint (method, path, operationName) {
|
|
36
76
|
const key = endpointKey(method, path)
|
|
37
77
|
if (pendingEndpoints.has(key)) return
|
|
@@ -40,6 +80,9 @@ function recordEndpoint (method, path, operationName) {
|
|
|
40
80
|
scheduleFlush()
|
|
41
81
|
}
|
|
42
82
|
|
|
83
|
+
/**
|
|
84
|
+
* @param {{ routeOptions?: { path?: string, method: string | string[] } } | null | undefined} routeData
|
|
85
|
+
*/
|
|
43
86
|
function onFastifyRoute (routeData) {
|
|
44
87
|
const routeOptions = routeData?.routeOptions
|
|
45
88
|
if (!routeOptions?.path) return
|
|
@@ -50,6 +93,9 @@ function onFastifyRoute (routeData) {
|
|
|
50
93
|
}
|
|
51
94
|
}
|
|
52
95
|
|
|
96
|
+
/**
|
|
97
|
+
* @param {{ method?: string, path?: string }} param0
|
|
98
|
+
*/
|
|
53
99
|
function onExpressRoute ({ method, path }) {
|
|
54
100
|
if (!method || !path) return
|
|
55
101
|
|
|
@@ -70,6 +116,9 @@ function onExpressRoute ({ method, path }) {
|
|
|
70
116
|
}
|
|
71
117
|
}
|
|
72
118
|
|
|
119
|
+
/**
|
|
120
|
+
* @param {{ method: string, path: string, operationName: string }[]} endpoints
|
|
121
|
+
*/
|
|
73
122
|
function buildEndpointObjects (endpoints) {
|
|
74
123
|
return endpoints.map(({ method, path, operationName }) => {
|
|
75
124
|
return {
|
|
@@ -82,6 +131,9 @@ function buildEndpointObjects (endpoints) {
|
|
|
82
131
|
})
|
|
83
132
|
}
|
|
84
133
|
|
|
134
|
+
/**
|
|
135
|
+
* @returns {void}
|
|
136
|
+
*/
|
|
85
137
|
function flushAndSend () {
|
|
86
138
|
flushScheduled = false
|
|
87
139
|
if (pendingEndpoints.size === 0) return
|
|
@@ -90,7 +142,8 @@ function flushAndSend () {
|
|
|
90
142
|
for (const [key, endpoint] of pendingEndpoints) {
|
|
91
143
|
batchEndpoints.push(endpoint)
|
|
92
144
|
pendingEndpoints.delete(key)
|
|
93
|
-
|
|
145
|
+
// Config is set when endpoint collection is enabled; message limit is optional
|
|
146
|
+
if (batchEndpoints.length >= (config.appsec?.apiSecurity?.endpointCollectionMessageLimit ?? 0)) break
|
|
94
147
|
}
|
|
95
148
|
|
|
96
149
|
const payloadObj = {
|
|
@@ -98,7 +151,10 @@ function flushAndSend () {
|
|
|
98
151
|
endpoints: buildEndpointObjects(batchEndpoints)
|
|
99
152
|
}
|
|
100
153
|
|
|
154
|
+
/** @type {import('./send-data').TelemetryRequestType} */
|
|
101
155
|
let reqType = 'app-endpoints'
|
|
156
|
+
|
|
157
|
+
/** @type {import('./send-data').TelemetryPayload} */
|
|
102
158
|
let payload = payloadObj
|
|
103
159
|
|
|
104
160
|
const retryData = getRetryData()
|
|
@@ -120,8 +176,15 @@ function flushAndSend () {
|
|
|
120
176
|
if (pendingEndpoints.size) scheduleFlush()
|
|
121
177
|
}
|
|
122
178
|
|
|
123
|
-
|
|
124
|
-
|
|
179
|
+
/**
|
|
180
|
+
* @param {TelemetryConfig} _config
|
|
181
|
+
* @param {import('./send-data').TelemetryApplication} _application
|
|
182
|
+
* @param {import('./send-data').TelemetryHost} _host
|
|
183
|
+
* @param {GetRetryData} getRetryDataFunction
|
|
184
|
+
* @param {import('./send-data').SendDataCallback} updateRetryDataFunction
|
|
185
|
+
*/
|
|
186
|
+
function start (_config, _application, _host, getRetryDataFunction, updateRetryDataFunction) {
|
|
187
|
+
if (!_config.appsec?.apiSecurity?.endpointCollectionEnabled) return
|
|
125
188
|
|
|
126
189
|
config = _config
|
|
127
190
|
application = _application
|
|
@@ -141,7 +204,6 @@ function stop () {
|
|
|
141
204
|
|
|
142
205
|
pendingEndpoints.clear()
|
|
143
206
|
flushScheduled = false
|
|
144
|
-
config = application = host = getRetryData = updateRetryData = null
|
|
145
207
|
}
|
|
146
208
|
|
|
147
209
|
module.exports = {
|
|
@@ -3,10 +3,93 @@
|
|
|
3
3
|
const request = require('../exporters/common/request')
|
|
4
4
|
const log = require('../log')
|
|
5
5
|
const { isTrue } = require('../util')
|
|
6
|
-
const {
|
|
6
|
+
const { getValueFromEnvSources } = require('../config/helper')
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Record<string, unknown>} TelemetryPayloadObject
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Telemetry "request_type" values sent by this library.
|
|
13
|
+
*
|
|
14
|
+
* @typedef {'app-started'
|
|
15
|
+
* | 'app-integrations-change'
|
|
16
|
+
* | 'app-heartbeat'
|
|
17
|
+
* | 'app-extended-heartbeat'
|
|
18
|
+
* | 'app-client-configuration-change'
|
|
19
|
+
* | 'app-closing'
|
|
20
|
+
* | 'app-dependencies-loaded'
|
|
21
|
+
* | 'app-endpoints'
|
|
22
|
+
* | 'generate-metrics'
|
|
23
|
+
* | 'distributions'
|
|
24
|
+
* | 'logs'
|
|
25
|
+
* | 'message-batch'} TelemetryRequestType
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {{ request_type: string, payload: TelemetryPayloadObject }} MessageBatchItem
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {MessageBatchItem[]} MessageBatchPayload
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Telemetry payloads are usually single objects, but some request types (e.g. `message-batch`)
|
|
35
|
+
* send arrays.
|
|
36
|
+
*
|
|
37
|
+
* @typedef {TelemetryPayloadObject | MessageBatchPayload} TelemetryPayload
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* @typedef {{language_name: string, tracer_version: string} & Record<string, unknown>} TelemetryApplication
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {Exclude<TelemetryRequestType, 'message-batch'>} NonBatchTelemetryRequestType
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* @typedef {{
|
|
47
|
+
* payload: TelemetryPayloadObject,
|
|
48
|
+
* reqType: NonBatchTelemetryRequestType
|
|
49
|
+
* } | {
|
|
50
|
+
* payload: MessageBatchPayload,
|
|
51
|
+
* reqType: 'message-batch'
|
|
52
|
+
* }} SendDataRetryObject
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {{
|
|
56
|
+
* hostname: string,
|
|
57
|
+
* os: string,
|
|
58
|
+
* architecture: string,
|
|
59
|
+
* os_version?: string,
|
|
60
|
+
* kernel_version?: string,
|
|
61
|
+
* kernel_release?: string,
|
|
62
|
+
* kernel_name?: string
|
|
63
|
+
* } & Record<string, unknown>} TelemetryHost
|
|
64
|
+
*/
|
|
65
|
+
/**
|
|
66
|
+
* @typedef {{
|
|
67
|
+
* hostname?: string,
|
|
68
|
+
* port?: string | number,
|
|
69
|
+
* url?: string | URL,
|
|
70
|
+
* site?: string,
|
|
71
|
+
* apiKey?: string,
|
|
72
|
+
* isCiVisibility?: boolean,
|
|
73
|
+
* spanAttributeSchema?: string,
|
|
74
|
+
* tags: Record<string, string>,
|
|
75
|
+
* telemetry?: { debug?: boolean }
|
|
76
|
+
* }} TelemetryConfig
|
|
77
|
+
*/
|
|
78
|
+
/**
|
|
79
|
+
* @callback SendDataCallback
|
|
80
|
+
* @param {Error | null | undefined} error
|
|
81
|
+
* @param {SendDataRetryObject} retryObj
|
|
82
|
+
* @returns {void}
|
|
83
|
+
*/
|
|
7
84
|
|
|
8
85
|
let agentTelemetry = true
|
|
9
86
|
|
|
87
|
+
/**
|
|
88
|
+
* @param {TelemetryConfig} config
|
|
89
|
+
* @param {TelemetryApplication} application
|
|
90
|
+
* @param {TelemetryRequestType} reqType
|
|
91
|
+
* @returns {Record<string, string>}
|
|
92
|
+
*/
|
|
10
93
|
function getHeaders (config, application, reqType) {
|
|
11
94
|
const headers = {
|
|
12
95
|
'content-type': 'application/json',
|
|
@@ -25,6 +108,9 @@ function getHeaders (config, application, reqType) {
|
|
|
25
108
|
return headers
|
|
26
109
|
}
|
|
27
110
|
|
|
111
|
+
/**
|
|
112
|
+
* @param {string | undefined} site
|
|
113
|
+
*/
|
|
28
114
|
function getAgentlessTelemetryEndpoint (site) {
|
|
29
115
|
if (site === 'datad0g.com') { // staging
|
|
30
116
|
return 'https://all-http-intake.logs.datad0g.com'
|
|
@@ -34,6 +120,10 @@ function getAgentlessTelemetryEndpoint (site) {
|
|
|
34
120
|
|
|
35
121
|
let seqId = 0
|
|
36
122
|
|
|
123
|
+
/**
|
|
124
|
+
* @param {TelemetryPayload} payload
|
|
125
|
+
* @returns {TelemetryPayload}
|
|
126
|
+
*/
|
|
37
127
|
function getPayload (payload) {
|
|
38
128
|
// Some telemetry endpoints payloads accept collections of elements such as the 'logs' endpoint.
|
|
39
129
|
// 'logs' request type payload is meant to send library logs to Datadog’s backend.
|
|
@@ -44,6 +134,15 @@ function getPayload (payload) {
|
|
|
44
134
|
return trimmedPayload
|
|
45
135
|
}
|
|
46
136
|
|
|
137
|
+
// TODO(BridgeAR): Simplify this code. A lot does not need to be recalculated on every call.
|
|
138
|
+
/**
|
|
139
|
+
* @param {TelemetryConfig} config
|
|
140
|
+
* @param {TelemetryApplication} application
|
|
141
|
+
* @param {TelemetryHost} host
|
|
142
|
+
* @param {TelemetryRequestType} reqType
|
|
143
|
+
* @param {TelemetryPayload} [payload]
|
|
144
|
+
* @param {SendDataCallback} [cb]
|
|
145
|
+
*/
|
|
47
146
|
function sendData (config, application, host, reqType, payload = {}, cb = () => {}) {
|
|
48
147
|
const {
|
|
49
148
|
hostname,
|
|
@@ -54,7 +153,7 @@ function sendData (config, application, host, reqType, payload = {}, cb = () =>
|
|
|
54
153
|
let url = config.url
|
|
55
154
|
|
|
56
155
|
const isCiVisibilityAgentlessMode = isCiVisibility &&
|
|
57
|
-
isTrue(
|
|
156
|
+
isTrue(getValueFromEnvSources('DD_CIVISIBILITY_AGENTLESS_ENABLED'))
|
|
58
157
|
|
|
59
158
|
if (isCiVisibilityAgentlessMode) {
|
|
60
159
|
try {
|
|
@@ -88,14 +187,14 @@ function sendData (config, application, host, reqType, payload = {}, cb = () =>
|
|
|
88
187
|
})
|
|
89
188
|
|
|
90
189
|
request(data, options, (error) => {
|
|
91
|
-
if (error &&
|
|
190
|
+
if (error && getValueFromEnvSources('DD_API_KEY') && config.site) {
|
|
92
191
|
if (agentTelemetry) {
|
|
93
192
|
log.warn('Agent telemetry failed, started agentless telemetry')
|
|
94
193
|
agentTelemetry = false
|
|
95
194
|
}
|
|
96
195
|
// figure out which data center to send to
|
|
97
196
|
const backendUrl = getAgentlessTelemetryEndpoint(config.site)
|
|
98
|
-
const backendHeader = { ...options.headers, 'DD-API-KEY':
|
|
197
|
+
const backendHeader = { ...options.headers, 'DD-API-KEY': getValueFromEnvSources('DD_API_KEY') }
|
|
99
198
|
const backendOptions = {
|
|
100
199
|
...options,
|
|
101
200
|
url: backendUrl,
|