dd-trace 5.82.0 → 5.83.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 +78 -79
- package/ci/init.js +6 -6
- package/index.d.ts +152 -3
- package/loader-hook.mjs +1 -1
- package/package.json +58 -55
- 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/index.js +1 -1
- package/packages/datadog-instrumentations/src/http/client.js +2 -2
- package/packages/datadog-instrumentations/src/jest.js +35 -14
- 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 +3 -3
- 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 +2 -2
- 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 +3 -3
- package/packages/datadog-plugin-undici/src/index.js +305 -2
- package/packages/datadog-plugin-vitest/src/index.js +5 -5
- package/packages/dd-trace/index.js +19 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -1
- 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/agentless/coverage-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -2
- 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 +3 -2
- 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/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} +92 -45
- package/packages/dd-trace/src/config/remote_config.js +187 -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} +2 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +1 -1
- package/packages/dd-trace/src/datastreams/writer.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +1 -1
- 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 +2 -2
- 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 +2 -4
- package/packages/dd-trace/src/exporters/agent/writer.js +9 -14
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +1 -1
- 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 +1 -1
- 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 +116 -37
- package/packages/dd-trace/src/llmobs/writers/spans.js +4 -3
- package/packages/dd-trace/src/log/index.js +5 -5
- package/packages/dd-trace/src/noop/proxy.js +3 -3
- package/packages/dd-trace/src/openfeature/writers/base.js +7 -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 -31
- 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 +3 -0
- package/packages/dd-trace/src/remote_config/index.js +1 -1
- 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 +6 -15
- 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/packages/dd-trace/src/{git_properties.js → config/git_properties.js} +0 -0
|
@@ -1,34 +1,202 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const RemoteConfigCapabilities = require('../remote_config/capabilities')
|
|
4
|
+
const log = require('../log')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
enable
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {object} RemoteConfigOptions
|
|
12
|
+
* @property {boolean} [dynamic_instrumentation_enabled] - Enable Dynamic Instrumentation
|
|
13
|
+
* @property {boolean} [code_origin_enabled] - Enable code origin tagging for spans
|
|
14
|
+
* @property {Array<{header: string, tag_name?: string}>} [tracing_header_tags] - HTTP headers to tag
|
|
15
|
+
* @property {Array<string>} [tracing_tags] - Global tags (format: "key:value")
|
|
16
|
+
* @property {number} [tracing_sampling_rate] - Global sampling rate (0.0-1.0)
|
|
17
|
+
* @property {boolean} [log_injection_enabled] - Enable trace context log injection
|
|
18
|
+
* @property {boolean} [tracing_enabled] - Enable/disable tracing globally
|
|
19
|
+
* @property {Array<object>} [tracing_sampling_rules] - Trace sampling rules configuration
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {ReturnType<import('../config')>} Config
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Manages multiple APM_TRACING configurations with priority-based merging
|
|
28
|
+
*/
|
|
29
|
+
class RCClientLibConfigManager {
|
|
30
|
+
/**
|
|
31
|
+
* @param {string} currentService - Current service name
|
|
32
|
+
* @param {string} currentEnv - Current environment name
|
|
33
|
+
*/
|
|
34
|
+
constructor (currentService, currentEnv) {
|
|
35
|
+
this.configs = new Map() // config_id -> { conf, priority }
|
|
36
|
+
this.currentService = currentService
|
|
37
|
+
this.currentEnv = currentEnv
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Calculate priority based on target specificity. Higher values take precedence.
|
|
42
|
+
* Priority order (highest → lowest):
|
|
43
|
+
* Service+Env (5) > Service (4) > Env (3) > Cluster (2) > Org (1)
|
|
44
|
+
*
|
|
45
|
+
* @param {object} conf - Remote config object with service_target and k8s_target_v2 properties
|
|
46
|
+
* @returns {number} Priority value from 1 (org-level) to 5 (service+env specific)
|
|
47
|
+
*/
|
|
48
|
+
calculatePriority (conf) {
|
|
49
|
+
const serviceTarget = conf.service_target
|
|
50
|
+
const k8sTarget = conf.k8s_target_v2
|
|
51
|
+
|
|
52
|
+
if (serviceTarget) {
|
|
53
|
+
const service = serviceTarget.service
|
|
54
|
+
const env = serviceTarget.env
|
|
55
|
+
|
|
56
|
+
const hasSpecificService = service && service !== '*'
|
|
57
|
+
const hasSpecificEnv = env && env !== '*'
|
|
58
|
+
|
|
59
|
+
if (hasSpecificService && hasSpecificEnv) return 5
|
|
60
|
+
if (hasSpecificService) return 4
|
|
61
|
+
if (hasSpecificEnv) return 3
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (k8sTarget) return 2
|
|
65
|
+
|
|
66
|
+
return 1 // Org level
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Check if config matches current service/env
|
|
71
|
+
*
|
|
72
|
+
* @param {object} conf - Remote config object with service_target property
|
|
73
|
+
* @returns {boolean} True if config matches current service/env or has no filter
|
|
74
|
+
*/
|
|
75
|
+
matchesCurrentServiceEnv (conf) {
|
|
76
|
+
const serviceTarget = conf.service_target
|
|
77
|
+
if (!serviceTarget) return true // No filter means match all
|
|
78
|
+
|
|
79
|
+
const service = serviceTarget.service
|
|
80
|
+
const env = serviceTarget.env
|
|
81
|
+
|
|
82
|
+
// Check service match
|
|
83
|
+
if (service && service !== '*' && service !== this.currentService) {
|
|
84
|
+
log.debug('[config/remote_config] Ignoring config for service: %s (current: %s)',
|
|
85
|
+
service, this.currentService)
|
|
86
|
+
return false
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Check env match
|
|
90
|
+
if (env && env !== '*' && env !== this.currentEnv) {
|
|
91
|
+
log.debug('[config/remote_config] Ignoring config for env: %s (current: %s)',
|
|
92
|
+
env, this.currentEnv)
|
|
93
|
+
return false
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return true
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Add or update a config
|
|
101
|
+
*
|
|
102
|
+
* @param {string} configId - Unique identifier for the config
|
|
103
|
+
* @param {object} conf - Remote config object to add
|
|
104
|
+
*/
|
|
105
|
+
addConfig (configId, conf) {
|
|
106
|
+
if (!this.matchesCurrentServiceEnv(conf)) {
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const priority = this.calculatePriority(conf)
|
|
111
|
+
this.configs.set(configId, { conf, priority })
|
|
112
|
+
|
|
113
|
+
log.debug('[config/remote_config] Added config %s with priority %d', configId, priority)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Remove a config
|
|
118
|
+
*
|
|
119
|
+
* @param {string} configId - Unique identifier for the config to remove
|
|
120
|
+
*/
|
|
121
|
+
removeConfig (configId) {
|
|
122
|
+
const removed = this.configs.delete(configId)
|
|
123
|
+
if (removed) {
|
|
124
|
+
log.debug('[config/remote_config] Removed config %s', configId)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Get merged lib_config with higher priority configs overriding lower priority ones
|
|
130
|
+
*
|
|
131
|
+
* @returns {RemoteConfigOptions|null} Merged config object or null if no configs present
|
|
132
|
+
*/
|
|
133
|
+
getMergedLibConfig () {
|
|
134
|
+
if (this.configs.size === 0) return null
|
|
135
|
+
|
|
136
|
+
let hasLibConfig = false
|
|
137
|
+
|
|
138
|
+
const merged = [...this.configs.values()]
|
|
139
|
+
.sort((a, b) => a.priority - b.priority)
|
|
140
|
+
.reduce((merged, { conf }) => {
|
|
141
|
+
if (conf.lib_config != null) hasLibConfig = true
|
|
142
|
+
return Object.assign(merged, conf.lib_config)
|
|
143
|
+
}, {})
|
|
144
|
+
|
|
145
|
+
return hasLibConfig ? merged : null
|
|
146
|
+
}
|
|
147
|
+
}
|
|
4
148
|
|
|
5
149
|
/**
|
|
6
150
|
* Configures remote config for core APM tracing functionality
|
|
7
151
|
*
|
|
8
|
-
* @param {
|
|
9
|
-
* @param {
|
|
10
|
-
* @param {
|
|
152
|
+
* @param {import('../remote_config')} rc - RemoteConfig instance
|
|
153
|
+
* @param {Config} config - Tracer config
|
|
154
|
+
* @param {() => void} onConfigUpdated - Function to call when config is updated
|
|
11
155
|
*/
|
|
12
|
-
function enable (rc, config,
|
|
13
|
-
//
|
|
156
|
+
function enable (rc, config, onConfigUpdated) {
|
|
157
|
+
// This tracer supports receiving config subsets via the APM_TRACING product handler.
|
|
158
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_MULTICONFIG, true)
|
|
159
|
+
|
|
160
|
+
// Tracing
|
|
161
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_ENABLED, true)
|
|
162
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RATE, true)
|
|
163
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RULES, true)
|
|
14
164
|
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_CUSTOM_TAGS, true)
|
|
15
165
|
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_HTTP_HEADER_TAGS, true)
|
|
166
|
+
|
|
167
|
+
// Log Management
|
|
16
168
|
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_LOGS_INJECTION, true)
|
|
17
|
-
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RATE, true)
|
|
18
|
-
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_ENABLED, true)
|
|
19
|
-
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RULES, true)
|
|
20
169
|
|
|
21
|
-
//
|
|
22
|
-
rc.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
170
|
+
// Debugger
|
|
171
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_ENABLE_DYNAMIC_INSTRUMENTATION, true)
|
|
172
|
+
|
|
173
|
+
// Code Origin
|
|
174
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_ENABLE_CODE_ORIGIN, true)
|
|
175
|
+
|
|
176
|
+
const rcClientLibConfigManager = new RCClientLibConfigManager(config.service, config.env)
|
|
177
|
+
|
|
178
|
+
// Subscribe to APM_TRACING product (setBatchHandler used below doesn't automatically subscribe)
|
|
179
|
+
rc.subscribeProducts('APM_TRACING')
|
|
180
|
+
|
|
181
|
+
// Use a batch handler to process all changes before updating the config. This is important in case there's
|
|
182
|
+
// conflicting configs between, for example, the org and service level.
|
|
183
|
+
rc.setBatchHandler(['APM_TRACING'], (transaction) => {
|
|
184
|
+
const { toUnapply, toApply, toModify } = transaction
|
|
185
|
+
|
|
186
|
+
for (const item of toUnapply) {
|
|
187
|
+
rcClientLibConfigManager.removeConfig(item.id)
|
|
188
|
+
transaction.ack(item.path)
|
|
27
189
|
}
|
|
28
|
-
enableOrDisableTracing(config, rc)
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
190
|
|
|
32
|
-
|
|
33
|
-
|
|
191
|
+
for (const item of [...toApply, ...toModify]) {
|
|
192
|
+
rcClientLibConfigManager.addConfig(item.id, item.file)
|
|
193
|
+
transaction.ack(item.path)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Get merged config and apply it
|
|
197
|
+
const mergedLibConfig = rcClientLibConfigManager.getMergedLibConfig()
|
|
198
|
+
config.setRemoteConfig(mergedLibConfig)
|
|
199
|
+
|
|
200
|
+
onConfigUpdated()
|
|
201
|
+
})
|
|
34
202
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const os = require('os')
|
|
4
4
|
const fs = require('fs')
|
|
5
|
-
const { getEnvironmentVariable } = require('
|
|
5
|
+
const { getEnvironmentVariable } = require('./helper')
|
|
6
6
|
|
|
7
7
|
class StableConfig {
|
|
8
8
|
constructor () {
|
|
@@ -11,14 +11,10 @@ class StableConfig {
|
|
|
11
11
|
this.fleetEntries = {}
|
|
12
12
|
this.wasm_loaded = false
|
|
13
13
|
|
|
14
|
-
const { localConfigPath, fleetConfigPath } = this
|
|
15
|
-
if (!fs.existsSync(localConfigPath) && !fs.existsSync(fleetConfigPath)) {
|
|
16
|
-
// Bail out early if files don't exist to avoid unnecessary library loading
|
|
17
|
-
return
|
|
18
|
-
}
|
|
14
|
+
const { localConfigPath, fleetConfigPath } = this.#getStableConfigPaths()
|
|
19
15
|
|
|
20
|
-
const localConfig = this
|
|
21
|
-
const fleetConfig = this
|
|
16
|
+
const localConfig = this.#readConfigFromPath(localConfigPath)
|
|
17
|
+
const fleetConfig = this.#readConfigFromPath(fleetConfigPath)
|
|
22
18
|
if (!localConfig && !fleetConfig) {
|
|
23
19
|
// Bail out early if files are empty or we can't read them to avoid unnecessary library loading
|
|
24
20
|
return
|
|
@@ -47,7 +43,7 @@ class StableConfig {
|
|
|
47
43
|
// eslint-disable-next-line eslint-rules/eslint-process-env
|
|
48
44
|
configurator.set_envp(Object.entries(process.env).map(([key, value]) => `${key}=${value}`))
|
|
49
45
|
configurator.set_args(process.argv)
|
|
50
|
-
configurator.get_configuration(localConfig
|
|
46
|
+
configurator.get_configuration(localConfig, fleetConfig).forEach((entry) => {
|
|
51
47
|
if (entry.source === 'local_stable_config') {
|
|
52
48
|
this.localEntries[entry.name] = entry.value
|
|
53
49
|
} else if (entry.source === 'fleet_stable_config') {
|
|
@@ -59,43 +55,35 @@ class StableConfig {
|
|
|
59
55
|
}
|
|
60
56
|
}
|
|
61
57
|
|
|
62
|
-
|
|
58
|
+
#readConfigFromPath (path) {
|
|
63
59
|
try {
|
|
64
60
|
return fs.readFileSync(path, 'utf8')
|
|
65
61
|
} catch (err) {
|
|
66
62
|
if (err.code !== 'ENOENT') {
|
|
67
63
|
this.warnings.push(`Error reading config file at ${path}. ${err.code}: ${err.message}`)
|
|
68
64
|
}
|
|
69
|
-
return '' // Always return a string
|
|
65
|
+
return '' // Always return a string for configurator.get_configuration()
|
|
70
66
|
}
|
|
71
67
|
}
|
|
72
68
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
fleetConfigPath = '/etc/datadog-agent/managed/datadog-agent/stable/application_monitoring.yaml'
|
|
80
|
-
break
|
|
69
|
+
#getStableConfigPaths () {
|
|
70
|
+
// TODO(BridgeAR): Remove these environment variables once we have a proper way to test the stable config.
|
|
71
|
+
// Allow overriding the paths for testing
|
|
72
|
+
let localConfigPath = getEnvironmentVariable('DD_TEST_LOCAL_CONFIG_PATH')
|
|
73
|
+
let fleetConfigPath = getEnvironmentVariable('DD_TEST_FLEET_CONFIG_PATH')
|
|
74
|
+
switch (os.platform()) {
|
|
81
75
|
case 'darwin':
|
|
82
|
-
localConfigPath
|
|
83
|
-
fleetConfigPath
|
|
76
|
+
localConfigPath ??= '/opt/datadog-agent/etc/application_monitoring.yaml'
|
|
77
|
+
fleetConfigPath ??= '/opt/datadog-agent/etc/managed/datadog-agent/stable/application_monitoring.yaml'
|
|
84
78
|
break
|
|
85
79
|
case 'win32':
|
|
86
|
-
localConfigPath
|
|
87
|
-
fleetConfigPath
|
|
80
|
+
localConfigPath ??= String.raw`C:\ProgramData\Datadog\application_monitoring.yaml`
|
|
81
|
+
fleetConfigPath ??= String.raw`C:\ProgramData\Datadog\managed\datadog-agent\stable\application_monitoring.yaml`
|
|
88
82
|
break
|
|
89
83
|
default:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// Allow overriding the paths for testing
|
|
94
|
-
if (getEnvironmentVariable('DD_TEST_LOCAL_CONFIG_PATH') !== undefined) {
|
|
95
|
-
localConfigPath = getEnvironmentVariable('DD_TEST_LOCAL_CONFIG_PATH')
|
|
96
|
-
}
|
|
97
|
-
if (getEnvironmentVariable('DD_TEST_FLEET_CONFIG_PATH') !== undefined) {
|
|
98
|
-
fleetConfigPath = getEnvironmentVariable('DD_TEST_FLEET_CONFIG_PATH')
|
|
84
|
+
// Linux and other platforms as fallback
|
|
85
|
+
localConfigPath ??= '/etc/datadog-agent/application_monitoring.yaml'
|
|
86
|
+
fleetConfigPath ??= '/etc/datadog-agent/managed/datadog-agent/stable/application_monitoring.yaml'
|
|
99
87
|
}
|
|
100
88
|
|
|
101
89
|
return { localConfigPath, fleetConfigPath }
|
package/packages/dd-trace/src/{supported-configurations.json → config/supported-configurations.json}
RENAMED
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
"DD_GIT_TAG": ["A"],
|
|
94
94
|
"DD_GIT_PULL_REQUEST_BASE_BRANCH": ["A"],
|
|
95
95
|
"DD_GIT_PULL_REQUEST_BASE_BRANCH_SHA": ["A"],
|
|
96
|
+
"DD_GIT_COMMIT_HEAD_SHA": ["A"],
|
|
96
97
|
"DD_GRPC_CLIENT_ERROR_STATUSES": ["A"],
|
|
97
98
|
"DD_GRPC_SERVER_ERROR_STATUSES": ["A"],
|
|
98
99
|
"DD_HEAP_SNAPSHOT_COUNT": ["A"],
|
|
@@ -112,6 +113,7 @@
|
|
|
112
113
|
"DD_IAST_TELEMETRY_VERBOSITY": ["A"],
|
|
113
114
|
"DD_INJECT_FORCE": ["A"],
|
|
114
115
|
"DD_INJECTION_ENABLED": ["A"],
|
|
116
|
+
"DD_ENABLE_NX_SERVICE_NAME": ["A"],
|
|
115
117
|
"DD_INSTRUMENTATION_CONFIG_ID": ["A"],
|
|
116
118
|
"DD_INSTRUMENTATION_INSTALL_ID": ["A"],
|
|
117
119
|
"DD_INSTRUMENTATION_INSTALL_TIME": ["A"],
|
|
@@ -7,7 +7,7 @@ const libdatadog = require('@datadog/libdatadog')
|
|
|
7
7
|
const binding = libdatadog.load('crashtracker')
|
|
8
8
|
|
|
9
9
|
const log = require('../log')
|
|
10
|
-
const defaults = require('../
|
|
10
|
+
const defaults = require('../config/defaults')
|
|
11
11
|
const pkg = require('../../../../package.json')
|
|
12
12
|
const processTags = require('../process-tags')
|
|
13
13
|
|
|
@@ -156,7 +156,7 @@ class DataStreamsProcessor {
|
|
|
156
156
|
this.timer = setInterval(this.onInterval.bind(this), flushInterval)
|
|
157
157
|
this.timer.unref()
|
|
158
158
|
}
|
|
159
|
-
|
|
159
|
+
globalThis[Symbol.for('dd-trace')].beforeExitHandlers.add(this.onInterval.bind(this))
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
onInterval () {
|
|
@@ -6,7 +6,7 @@ const pkg = require('../../../../package.json')
|
|
|
6
6
|
const log = require('../log')
|
|
7
7
|
const request = require('../exporters/common/request')
|
|
8
8
|
const { MsgpackEncoder } = require('../msgpack')
|
|
9
|
-
const defaults = require('../
|
|
9
|
+
const defaults = require('../config/defaults')
|
|
10
10
|
|
|
11
11
|
const msgpack = new MsgpackEncoder()
|
|
12
12
|
|
|
@@ -206,7 +206,7 @@ function isTypedArray (variable) {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
function isInstanceOfCoreType (type, variable, fallback = `${variable} instanceof ${type}`) {
|
|
209
|
-
return `(
|
|
209
|
+
return `(globalThis[Symbol.for('dd-trace')].utilTypes?.is${type}?.(${variable}) ?? ${fallback})`
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
function getSize (variable) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { workerData: { config: parentConfig, parentThreadId, configPort } } = require('node:worker_threads')
|
|
4
4
|
const { format } = require('node:url')
|
|
5
|
-
const defaults = require('../../
|
|
5
|
+
const defaults = require('../../config/defaults')
|
|
6
6
|
const log = require('./log')
|
|
7
7
|
|
|
8
8
|
const config = module.exports = {
|
|
@@ -6,7 +6,7 @@ const { stringify } = require('querystring')
|
|
|
6
6
|
const request = require('../../exporters/common/request')
|
|
7
7
|
const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags')
|
|
8
8
|
const { version } = require('../../../../../package.json')
|
|
9
|
-
const {
|
|
9
|
+
const { getValueFromEnvSources } = require('../../config/helper')
|
|
10
10
|
const log = require('./log')
|
|
11
11
|
const JSONBuffer = require('./json-buffer')
|
|
12
12
|
const config = require('./config')
|
|
@@ -23,8 +23,8 @@ const hostname = getHostname()
|
|
|
23
23
|
const service = config.service
|
|
24
24
|
|
|
25
25
|
const ddtags = [
|
|
26
|
-
['env',
|
|
27
|
-
['version',
|
|
26
|
+
['env', getValueFromEnvSources('DD_ENV')],
|
|
27
|
+
['version', getValueFromEnvSources('DD_VERSION')],
|
|
28
28
|
['debugger_version', version],
|
|
29
29
|
['host_name', hostname],
|
|
30
30
|
[GIT_COMMIT_SHA, config.commitSHA],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { getEnvironmentVariable } = require('../../../config
|
|
3
|
+
const { getEnvironmentVariable } = require('../../../config/helper')
|
|
4
4
|
|
|
5
5
|
const largeObjectSkipThreshold = Number(
|
|
6
6
|
getEnvironmentVariable('_DD_DYNAMIC_INSTRUMENTATION_EXPERIMENTAL_LARGE_OBJECT_SKIP_THRESHOLD')
|
|
@@ -10,26 +10,49 @@ const getDebuggerConfig = require('./config')
|
|
|
10
10
|
let worker = null
|
|
11
11
|
let configChannel = null
|
|
12
12
|
let ackId = 0
|
|
13
|
+
let rcAckCallbacks = null
|
|
14
|
+
let rc = null
|
|
13
15
|
|
|
14
16
|
// eslint-disable-next-line eslint-rules/eslint-process-env
|
|
15
17
|
const { NODE_OPTIONS, ...env } = process.env
|
|
16
18
|
|
|
17
19
|
module.exports = {
|
|
20
|
+
isStarted,
|
|
18
21
|
start,
|
|
19
|
-
configure
|
|
22
|
+
configure,
|
|
23
|
+
stop
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Check if the Debugger worker is currently running
|
|
28
|
+
*
|
|
29
|
+
* @returns {boolean} True if the worker is started, false otherwise
|
|
30
|
+
*/
|
|
31
|
+
function isStarted () {
|
|
32
|
+
return worker !== null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Start the Debugger worker thread.
|
|
37
|
+
* Creates a worker thread, sets up message channels, and registers
|
|
38
|
+
* the LIVE_DEBUGGING product handler with remote config.
|
|
39
|
+
* Does nothing if the worker is already started.
|
|
40
|
+
*
|
|
41
|
+
* @param {object} config - The tracer configuration object
|
|
42
|
+
* @param {object} rcInstance - The RemoteConfig instance
|
|
43
|
+
*/
|
|
44
|
+
function start (config, rcInstance) {
|
|
23
45
|
if (worker !== null) return
|
|
24
46
|
|
|
25
47
|
log.debug('[debugger] Starting Dynamic Instrumentation client...')
|
|
26
48
|
|
|
27
|
-
|
|
49
|
+
rc = rcInstance
|
|
50
|
+
rcAckCallbacks = new Map()
|
|
28
51
|
const probeChannel = new MessageChannel()
|
|
29
52
|
const logChannel = new MessageChannel()
|
|
30
53
|
configChannel = new MessageChannel()
|
|
31
54
|
|
|
32
|
-
|
|
55
|
+
globalThis[Symbol.for('dd-trace')].utilTypes = types
|
|
33
56
|
|
|
34
57
|
readProbeFile(config.dynamicInstrumentation.probeFile, (probes) => {
|
|
35
58
|
const action = 'apply'
|
|
@@ -84,19 +107,10 @@ function start (config, rc) {
|
|
|
84
107
|
worker.on('error', (err) => log.error('[debugger] worker thread error', err))
|
|
85
108
|
worker.on('messageerror', (err) => log.error('[debugger] received "messageerror" from worker', err))
|
|
86
109
|
|
|
87
|
-
worker.
|
|
110
|
+
worker.once('exit', (code) => {
|
|
88
111
|
const error = new Error(`Dynamic Instrumentation worker thread exited unexpectedly with code ${code}`)
|
|
89
|
-
|
|
90
112
|
log.error('[debugger] worker thread exited unexpectedly', error)
|
|
91
|
-
|
|
92
|
-
// Be nice, clean up now that the worker thread encountered an issue and we can't continue
|
|
93
|
-
rc.removeProductHandler('LIVE_DEBUGGING')
|
|
94
|
-
worker.removeAllListeners()
|
|
95
|
-
configChannel = null
|
|
96
|
-
for (const ackId of rcAckCallbacks.keys()) {
|
|
97
|
-
rcAckCallbacks.get(ackId)(error)
|
|
98
|
-
rcAckCallbacks.delete(ackId)
|
|
99
|
-
}
|
|
113
|
+
cleanup(error) // Be nice, clean up now that the worker thread encountered an issue and we can't continue
|
|
100
114
|
})
|
|
101
115
|
|
|
102
116
|
worker.unref()
|
|
@@ -108,11 +122,65 @@ function start (config, rc) {
|
|
|
108
122
|
configChannel.port2.unref()
|
|
109
123
|
}
|
|
110
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Reconfigure the Debugger worker with updated settings.
|
|
127
|
+
* Sends the new configuration to the worker thread via the config channel.
|
|
128
|
+
* Does nothing if the worker is not started.
|
|
129
|
+
*
|
|
130
|
+
* @param {object} config - The updated tracer configuration object
|
|
131
|
+
*/
|
|
111
132
|
function configure (config) {
|
|
112
133
|
if (configChannel === null) return
|
|
113
134
|
configChannel.port2.postMessage(getDebuggerConfig(config))
|
|
114
135
|
}
|
|
115
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Stop the Debugger worker thread.
|
|
139
|
+
* Terminates the worker and cleans up resources.
|
|
140
|
+
* Safe to call even if the worker is not started.
|
|
141
|
+
*/
|
|
142
|
+
function stop () {
|
|
143
|
+
if (worker === null) return
|
|
144
|
+
|
|
145
|
+
log.debug('[debugger] Stopping Dynamic Instrumentation client...')
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
worker.terminate()
|
|
149
|
+
cleanup() // Graceful shutdown - termination succeeded
|
|
150
|
+
} catch (err) {
|
|
151
|
+
log.error('[debugger] Error terminating worker', err)
|
|
152
|
+
cleanup(err) // Cleanup with error - termination failed
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Internal cleanup function to reset all debugger resources.
|
|
158
|
+
* Called when stopping the debugger or when the worker exits unexpectedly.
|
|
159
|
+
*
|
|
160
|
+
* @param {Error} [error] - Optional error to pass to pending ack callbacks (for unexpected exits)
|
|
161
|
+
*/
|
|
162
|
+
function cleanup (error) {
|
|
163
|
+
if (rc) {
|
|
164
|
+
rc.removeProductHandler('LIVE_DEBUGGING')
|
|
165
|
+
rc = null
|
|
166
|
+
}
|
|
167
|
+
if (worker) {
|
|
168
|
+
worker.removeAllListeners()
|
|
169
|
+
worker = null
|
|
170
|
+
}
|
|
171
|
+
configChannel = null
|
|
172
|
+
|
|
173
|
+
// Call any pending ack callbacks
|
|
174
|
+
// Pass error for unexpected exits, or undefined for graceful shutdown
|
|
175
|
+
if (rcAckCallbacks) {
|
|
176
|
+
for (const ackId of rcAckCallbacks.keys()) {
|
|
177
|
+
rcAckCallbacks.get(ackId)(error)
|
|
178
|
+
rcAckCallbacks.delete(ackId)
|
|
179
|
+
}
|
|
180
|
+
rcAckCallbacks = null
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
116
184
|
function readProbeFile (path, cb) {
|
|
117
185
|
if (!path) return
|
|
118
186
|
|
|
@@ -8,7 +8,7 @@ const { URL, format } = require('url')
|
|
|
8
8
|
const request = require('./exporters/common/request')
|
|
9
9
|
const log = require('./log')
|
|
10
10
|
const Histogram = require('./histogram')
|
|
11
|
-
const defaults = require('./
|
|
11
|
+
const defaults = require('./config/defaults')
|
|
12
12
|
|
|
13
13
|
const MAX_BUFFER_SIZE = 1024 // limit from the agent
|
|
14
14
|
|
|
@@ -360,7 +360,7 @@ class CustomMetrics {
|
|
|
360
360
|
// TODO(bengl) this magic number should be configurable
|
|
361
361
|
setInterval(flush, 10 * 1000).unref()
|
|
362
362
|
|
|
363
|
-
|
|
363
|
+
globalThis[Symbol.for('dd-trace')].beforeExitHandlers.add(flush)
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
increment (stat, value = 1, tags) {
|
|
@@ -4,7 +4,7 @@ const { MsgpackChunk, MsgpackEncoder } = require('../msgpack')
|
|
|
4
4
|
const log = require('../log')
|
|
5
5
|
const { isTrue } = require('../util')
|
|
6
6
|
const { memoize } = require('../log/utils')
|
|
7
|
-
const {
|
|
7
|
+
const { getValueFromEnvSources } = require('../config/helper')
|
|
8
8
|
const { truncateSpan, normalizeSpan } = require('./tags-processors')
|
|
9
9
|
|
|
10
10
|
const SOFT_LIMIT = 8 * 1024 * 1024 // 8MB
|
|
@@ -31,7 +31,7 @@ class AgentEncoder {
|
|
|
31
31
|
this._stringBytes = new MsgpackChunk()
|
|
32
32
|
this._writer = writer
|
|
33
33
|
this._reset()
|
|
34
|
-
this._debugEncoding = isTrue(
|
|
34
|
+
this._debugEncoding = isTrue(getValueFromEnvSources('DD_TRACE_ENCODING_DEBUG'))
|
|
35
35
|
this._config = this._writer?._config
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const exporters = require('../../../ext/exporters')
|
|
5
|
-
const { getEnvironmentVariable } = require('../../dd-trace/src/config
|
|
5
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config/helper')
|
|
6
6
|
const constants = require('./constants')
|
|
7
7
|
|
|
8
8
|
module.exports = function getExporter (name) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { URL, format } = require('url')
|
|
4
4
|
const log = require('../../log')
|
|
5
|
-
const defaults = require('../../
|
|
5
|
+
const defaults = require('../../config/defaults')
|
|
6
6
|
const Writer = require('./writer')
|
|
7
7
|
|
|
8
8
|
class AgentExporter {
|
|
@@ -31,9 +31,7 @@ class AgentExporter {
|
|
|
31
31
|
config
|
|
32
32
|
})
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
this.flush()
|
|
36
|
-
})
|
|
34
|
+
globalThis[Symbol.for('dd-trace')].beforeExitHandlers.add(this.flush.bind(this))
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
setUrl (url) {
|