Skip to content

Conversation

@mtoffl01
Copy link
Contributor

@mtoffl01 mtoffl01 commented Nov 24, 2025

Reviewer tips

The majority of code changes are just replacing getEnvironmentVariable with getValueFromEnvSources. Feel free to gloss over those changes once you get the idea from a few, and instead focus on:

  • packages/dd-trace/src/config-helper.js
  • packages/dd-trace-/src/config.js
  • packages/dd-trace-/src/profiling/...

Background

Currently, stable config files and environment variables are only processed when the Config class is instantiated, which happens in tracer.init(). This limits us from earlier access: code that runs before tracer.init() can't access stable config values.
This PR allows us to access stable config values before tracer.init(), when we peek at DD_TRACE env vars.
It also deduplicates configuration sourcing in profiler.

What does this PR do?

Introduces getValueFromEnvSources API in config-helper.js that resolves configuration from local stable config, environment variables, and fleet stable config in ascending priority order, before the Config singleton is initialized. This method can be used instead of getEnvironmentVariable when we want to see whether particular DD_TRACE configs have been set.

Key additions:

config-helper:

  • getValueFromEnvSources(): Queries for the value at specified config in fleet stable config, env var, and local stable config input, in that order
  • Comprehensive tests for the new config-helper functionality

profiler

  • Profiling config now consumes tracer Config fields: profiling/config.js reads options passed down from the main Config singleton, instead of re-reading them directly. For "DD_" configs that are not yet processed by the Config singleton, we use getValueFromEnvSources in order to resolve them from stable config inputs in addition to process.env
  • Profiling tests updated to mirror runtime behavior: profiling/config.spec.js and profiling/profiler.spec.js now construct profiling Config with a realistic agent URL (and hostname/port when relevant), matching what the tracer Config would provide at runtime, so tests exercise the same code paths the profiler uses in production.

Motivation

All environment variables must be set-able via stable config files: RFC

Note

Not all calls to getEnvironmentVariable were replaced by getResolvedEnv. In some cases, we are really looking for an environment variable that is a heuristic for a particular type of environment. Stable config is not relevant in these cases.

Plugin Checklist

Additional Notes

@github-actions
Copy link

github-actions bot commented Nov 24, 2025

Overall package size

Self size: 4.43 MB
Deduped: 5.25 MB
No deduping: 5.25 MB

Dependency sizes | name | version | self size | total size | |------|---------|-----------|------------| | import-in-the-middle | 2.0.0 | 68.46 kB | 797.03 kB | | dc-polyfill | 0.1.10 | 26.73 kB | 26.73 kB |

🤖 This report was automatically generated by heaviest-objects-in-the-universe

@datadog-official
Copy link

datadog-official bot commented Nov 24, 2025

⚠️ Tests

Fix all issues with Cursor

⚠️ Warnings

❄️ 1 New flaky test detected

cypress@latest esm flaky test retries retries flaky tests from integration-tests/cypress/cypress.spec.js (Datadog) (Fix with Cursor)
Expected values to be strictly equal:

18 !== 10

ℹ️ Info

🧪 All tests passed

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: af99299 | Docs | Datadog PR Page | Was this helpful? Give us feedback!

@codecov
Copy link

codecov bot commented Nov 24, 2025

Codecov Report

❌ Patch coverage is 86.63793% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.17%. Comparing base (971bdd5) to head (af99299).

Files with missing lines Patch % Lines
packages/dd-trace/src/profiling/profiler.js 6.25% 15 Missing ⚠️
packages/dd-trace/src/telemetry/telemetry.js 86.27% 7 Missing ⚠️
...e/src/ci-visibility/exporters/test-worker/index.js 50.00% 2 Missing ⚠️
packages/dd-trace/src/llmobs/sdk.js 33.33% 2 Missing ⚠️
...ility/test-management/get-test-management-tests.js 50.00% 1 Missing ⚠️
packages/dd-trace/src/profiler.js 0.00% 1 Missing ⚠️
packages/dd-trace/src/proxy.js 50.00% 1 Missing ⚠️
packages/dd-trace/src/ritm.js 80.00% 1 Missing ⚠️
packages/dd-trace/src/telemetry/send-data.js 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6982      +/-   ##
==========================================
+ Coverage   85.14%   85.17%   +0.03%     
==========================================
  Files         532      532              
  Lines       22897    22922      +25     
==========================================
+ Hits        19495    19524      +29     
+ Misses       3402     3398       -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mtoffl01 mtoffl01 added AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos core labels Nov 24, 2025
@pr-commenter
Copy link

pr-commenter bot commented Nov 24, 2025

Benchmarks

Benchmark execution time: 2026-01-20 01:44:41

Comparing candidate commit af99299 in PR branch mtoff/dcfg-getEnv-migration with baseline commit 971bdd5 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 230 metrics, 30 unstable metrics.

@mtoffl01 mtoffl01 changed the title Look in StableConfig & Env sources for config pre-init Create class ConfigEnvSources to merge stable config and environment variables Nov 24, 2025
@mtoffl01 mtoffl01 changed the title Create class ConfigEnvSources to merge stable config and environment variables Add class ConfigEnvSources to merge stable config and environment variables Nov 24, 2025
@mtoffl01 mtoffl01 force-pushed the mtoff/dcfg-getEnv-migration branch from eacb99d to a532c6a Compare December 4, 2025 17:12
@mtoffl01 mtoffl01 marked this pull request as ready for review December 4, 2025 21:14
@mtoffl01 mtoffl01 requested review from a team as code owners December 4, 2025 21:14
@mtoffl01 mtoffl01 requested review from BridgeAR and removed request for a team December 4, 2025 21:14
@BridgeAR BridgeAR force-pushed the mtoff/dcfg-getEnv-migration branch 2 times, most recently from 282f094 to 948ddde Compare December 29, 2025 16:35
Comment on lines 85 to 87
localStableConfig: localStableConfig ?? {},
fleetStableConfig: fleetStableConfig ?? {},
stableConfigWarnings: stableConfigWarnings ?? []
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can see these 3 variables will never be undefined, so this could be written as:

Suggested change
localStableConfig: localStableConfig ?? {},
fleetStableConfig: fleetStableConfig ?? {},
stableConfigWarnings: stableConfigWarnings ?? []
localStableConfig,
fleetStableConfig,
stableConfigWarnings

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

Copy link
Collaborator

@watson watson Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you said in some of your other comments, this is not strictly true. In case of a serverless environment, these will be undefined. However, in the code we never actually call this function in that case, so it should work without the undefined check. However, the JSDoc @returns is now technically wrong I guess. But it's all a mess because if you guard the call getStableConfigSources with a check for if we're not in serverless, then they are guaranteed to be objects, so 🤷

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I just checked the overall calls and we guard against calling this in config.js by first checking if the environment is not serverless.

I guess it is a minimal risk to not have the fallback in case a refactoring would ever change that in a weird way. Otherwise this should be good as is. That also applies to the JSDoc as such 😅

I am fine either way. What is your preferred way of handling this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to keep it as is

@BridgeAR BridgeAR force-pushed the mtoff/dcfg-getEnv-migration branch 2 times, most recently from 21955bc to 6f3422a Compare January 8, 2026 09:40
Comment on lines 85 to 87
localStableConfig: localStableConfig ?? {},
fleetStableConfig: fleetStableConfig ?? {},
stableConfigWarnings: stableConfigWarnings ?? []
Copy link
Collaborator

@watson watson Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you said in some of your other comments, this is not strictly true. In case of a serverless environment, these will be undefined. However, in the code we never actually call this function in that case, so it should work without the undefined check. However, the JSDoc @returns is now technically wrong I guess. But it's all a mess because if you guard the call getStableConfigSources with a check for if we're not in serverless, then they are guaranteed to be objects, so 🤷

'Datadog-Meta-Lang': 'nodejs',
'Datadog-Meta-Lang-Version': process.version,
'Datadog-Meta-Lang-Interpreter': process.jsEngine || 'v8'
'Datadog-Meta-Lang-Interpreter': process.versions.bun ? 'JavaScriptCore' : 'V8'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I believe this is just a value we read, while it could theoretically have an impact on dashboards that look for the lowercase version (most cases would be case insensitive anyway though).

makeRequest(_protocolVersion, data, count, _url, _headers, _lookup, true, (err, res, status) => {
makeRequest(_protocolVersion, data, count, _url, _headers, _lookup, (err, res, status) => {
// Note that logging will only happen once, regardless of how many times this is called.
startupLog(status !== 404 && status !== 200 ? { status, message: err?.message ?? inspect(err) } : undefined)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I am uncertain about the fallback (it should never happen that an error has no message, but just in theory). We would receive the full stacktrace in case it's still a regular error, which would be likely.

errors.agentError = {
code: agentError.code ?? '',
message: `Agent Error:${agentError.message}`
code: agentError.status,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am actually uncertain, if this is definitely correct. I have to verify that again.

Comment on lines +224 to +228
if (errors.agentError) {
app.error = errors.agentError
errors.agentError = undefined
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am unsure why this was never activated before. I am going to try to verify that before landing.

architecture: os.arch(),
os_version: os.version()
}
if (os.platform() === 'win32') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This is actually a bug fix.

@BridgeAR BridgeAR force-pushed the mtoff/dcfg-getEnv-migration branch from c745a69 to b1308bc Compare January 12, 2026 21:38
fleetConfigPath = '/etc/datadog-agent/managed/datadog-agent/stable/application_monitoring.yaml'
break
#getStableConfigPaths () {
// TODO(BridgeAR): Remove these environment variables once we have a proper way to test the stable config.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As much as we'd like to avoid mocking .... would a filesystem mock suffice here? I think it's sufficiently low level and not mocking dd-trace functionality that it might be appropriate here.

Copy link
Collaborator

@BridgeAR BridgeAR Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would work. I just did not want to make even more changes 😅

Comment on lines 16 to 35
function getInterprocessTraceCode () {
if (getEnvironmentVariable('JEST_WORKER_ID')) {
return JEST_WORKER_TRACE_PAYLOAD_CODE
}
if (getEnvironmentVariable('CUCUMBER_WORKER_ID')) {
return CUCUMBER_WORKER_TRACE_PAYLOAD_CODE
}
if (getEnvironmentVariable('MOCHA_WORKER_ID')) {
return MOCHA_WORKER_TRACE_PAYLOAD_CODE
}
if (getEnvironmentVariable('DD_PLAYWRIGHT_WORKER')) {
if (getValueFromEnvSources('DD_PLAYWRIGHT_WORKER')) {
return PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE
}
if (getEnvironmentVariable('TINYPOOL_WORKER_ID')) {
return VITEST_WORKER_TRACE_PAYLOAD_CODE
}
if (getEnvironmentVariable('DD_VITEST_WORKER')) {
if (getValueFromEnvSources('DD_VITEST_WORKER')) {
return VITEST_WORKER_TRACE_PAYLOAD_CODE
}
return null
Copy link
Member

@simon-id simon-id Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like eyes of @juan-fernandez on the test-viz changes, some of the env vars here are DD_ and some are not. Should we really change it to geTValueFromEnvSources ? Is having a mix of getEnvironementVariable() and getValueFromEnvSources() the behavior we want ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe having this mix of behaviors depending on the env var name in this function will cause unexpected behavior to customers or even to our own devs.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am going to check, what our RFCs say about stable config and non DD_ envs. It would only depend on that.

mtoffl01 and others added 2 commits January 20, 2026 02:10
fix circular dependency

Migrate civis call to use getEnvironmnetVariableSources instead

run linter

cleanup comments on config-env-sources

complete ci/init.js migration

migrate otel-sdk-trace.js

assert getResolvedEnv behaves just like getEnvironmentVariable when only envs exist

migrate register.js

migrate DD_TRACE_AWS_SDK_BATCH_PROPAGATION_ENABLED

migrate DD_TRACE_AZURE_EVENTHUBS_BATCH_LINKS_ENABLED and DD_TRACE_AZURE_SERVICEBUS_BATCH_LINKS_ENABLED

migrate cypress and cucumber DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER

migrate dd-trace-api, mocha and jest

migrate mongodb, playwright and vitest plugins

migrate index.js -- specifically for disablement env vars -- and update tests to call resetEnvConfigSources

migrate plugin_manager

migrate DD_API_KEY in proxy.js

Finish bulk migration

fix debugger test: reset configenvsources

Fix failing tests in ci

fix failing lambda tets and aws-sdk tests

whoops - include all changes to lambda tests

migrate DD_TRACE_ENCODING_DEBUG and DD_TRACE_EXPERIMENTAL_STATE_TRACKING

Try out not cachine env vars

update config-env-sources tests accordingly

Remove calls to resetConfigEnvSources in legacy tests

nits

restore exporter.spec.js

have Config re-use the stable config entries from ConfigEnvSources

Add doc for ConfigEnvSources

drop config-env-sources; just use config-helper

delete config env sources

try again to delete config-env-sources

Apply getValueFromEnvSources to rest of DD calls; fix serverless.js

fix ritm

fix more referecnes to config env sources

fix another import

fix calls to getEnvironmentVariables that need getValueFromEnvSources

pass 'config' all the way down into profiler; remove duplicate config resolution logic

use getValueFromEnvSources in profiler for DD_ configs

leave TODO
Potentially split this into multiple PRs
@BridgeAR BridgeAR force-pushed the mtoff/dcfg-getEnv-migration branch from b1308bc to af99299 Compare January 20, 2026 01:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos core semver-minor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants