-
Notifications
You must be signed in to change notification settings - Fork 355
Support all configurations with Declarative Config #6694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| // This method, and callers of this method, need to be updated to check for declarative config sources as well. | ||
| getEnvironmentVariable (name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getEnvironmentVariable is called 150+ times across the codebase. I'm thinking the changes described on line 81 should be done in a separate PR.
BenchmarksBenchmark execution time: 2025-10-28 19:47:22 Comparing candidate commit 095fffd in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 1606 metrics, 64 unstable metrics. |
Overall package sizeSelf size: 13.15 MB Dependency sizes| name | version | self size | total size | |------|---------|-----------|------------| | @datadog/libdatadog | 0.7.0 | 35.02 MB | 35.02 MB | | @datadog/native-appsec | 10.3.0 | 20.73 MB | 20.74 MB | | @datadog/native-iast-taint-tracking | 4.0.0 | 11.72 MB | 11.73 MB | | @datadog/pprof | 5.11.1 | 9.96 MB | 10.34 MB | | @opentelemetry/core | 1.30.1 | 908.66 kB | 7.16 MB | | protobufjs | 7.5.4 | 2.95 MB | 5.82 MB | | @datadog/wasm-js-rewriter | 4.0.1 | 2.85 MB | 3.58 MB | | @opentelemetry/resources | 1.9.1 | 306.54 kB | 1.74 MB | | @datadog/native-metrics | 3.1.1 | 1.02 MB | 1.43 MB | | @opentelemetry/api-logs | 0.207.0 | 201.39 kB | 1.42 MB | | @opentelemetry/api | 1.9.0 | 1.22 MB | 1.22 MB | | jsonpath-plus | 10.3.0 | 617.18 kB | 1.08 MB | | import-in-the-middle | 1.15.0 | 127.66 kB | 856.24 kB | | lru-cache | 10.4.3 | 804.3 kB | 804.3 kB | | @datadog/openfeature-node-server | 0.1.0-preview.12 | 95.11 kB | 401.68 kB | | opentracing | 0.14.7 | 194.81 kB | 194.81 kB | | source-map | 0.7.6 | 185.63 kB | 185.63 kB | | pprof-format | 2.2.1 | 163.06 kB | 163.06 kB | | @datadog/sketches-js | 2.1.1 | 109.9 kB | 109.9 kB | | lodash.sortby | 4.7.0 | 75.76 kB | 75.76 kB | | ignore | 7.0.5 | 63.38 kB | 63.38 kB | | istanbul-lib-coverage | 3.2.2 | 34.37 kB | 34.37 kB | | rfdc | 1.4.1 | 27.15 kB | 27.15 kB | | dc-polyfill | 0.1.10 | 26.73 kB | 26.73 kB | | @isaacs/ttlcache | 1.4.1 | 25.2 kB | 25.2 kB | | tlhunter-sorted-set | 0.1.0 | 24.94 kB | 24.94 kB | | shell-quote | 1.8.3 | 23.74 kB | 23.74 kB | | limiter | 1.1.5 | 23.17 kB | 23.17 kB | | retry | 0.13.1 | 18.85 kB | 18.85 kB | | semifies | 1.0.0 | 15.84 kB | 15.84 kB | | jest-docblock | 29.7.0 | 8.99 kB | 12.76 kB | | crypto-randomuuid | 1.0.0 | 11.18 kB | 11.18 kB | | ttl-set | 1.0.0 | 4.61 kB | 9.69 kB | | mutexify | 1.4.0 | 5.71 kB | 8.74 kB | | path-to-regexp | 0.1.12 | 6.6 kB | 6.6 kB | | module-details-from-path | 1.0.4 | 3.96 kB | 3.96 kB |🤖 This report was automatically generated by heaviest-objects-in-the-universe |
This comment has been minimized.
This comment has been minimized.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6694 +/- ##
==========================================
- Coverage 84.06% 84.04% -0.02%
==========================================
Files 506 506
Lines 21212 21241 +29
==========================================
+ Hits 17831 17852 +21
- Misses 3381 3389 +8 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
BridgeAR
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great work, fixing multiple issues with the sources!
I left a few comments, mostly as question.
| this.#setBoolean(env, 'reportHostname', DD_TRACE_REPORT_HOSTNAME) | ||
| this.#setString(target, 'protocolVersion', DD_TRACE_AGENT_PROTOCOL_VERSION) | ||
| this.#setString(target, 'queryStringObfuscation', DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP) | ||
| this.#setBoolean(target, 'remoteConfig.enabled', DD_REMOTE_CONFIGURATION_ENABLED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change makes sense as such, that we expect a user never to define this value if in a serverless environment. If they do however use a single configuration for serverless and non-serverless and they have this set to enabled, it would cause a regression, if I am not mistaken.
| this.#setBoolean(target, 'startupLogs', DD_TRACE_STARTUP_LOGS) | ||
| this.#setTags(target, 'tags', tags) | ||
| target.tagsHeaderMaxLength = DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH | ||
| this.#setBoolean(target, 'telemetry.enabled', DD_INSTRUMENTATION_TELEMETRY_ENABLED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as with remote config enabled:
This change makes sense as such, that we expect a user never to define this value if in a serverless environment or when using jest. If they do however use a single configuration for serverless and non-serverless and they have this set to enabled, it would cause a regression, if I am not mistaken.
I wonder if we just want to ignore the value if we are in serverless or when using jest. That way it would indeed fall back to the default value, which we can also define as such. In addition, we could use a unprocessed object for it, so that we still know the user defined it.
It is just an interesting edge case for how to handle it correct.
| this.#setBoolean(obj, 'runtimeMetrics.enabled', DD_RUNTIME_METRICS_ENABLED) | ||
| this.#setString(obj, 'service', DD_SERVICE) | ||
| this.#setString(obj, 'version', DD_VERSION) | ||
| this.#applyConfigValues(config, obj, {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The third argument means we will fill that object but never use it, as far as I can tell. Should we potentially just not set the unprocessed values, if we do not pass through a third argument?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually do not understand what the "unprocessedTarget" does. I just used {} to maintain existing patterns.
I guess the question is: Does StableConfig need an "unprocessedTarget"? If not, then yes, we could:
- Not pass a third argument
- Modify the logic in applyConfigValues to only set entries on unprocessedTarget if it exists
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unprocessed exists because we used to override some values with calculated ones. To still send out the original user defined value, we tracked both cases. That is definitely not ideal and it would be better not to change anything in the first place. That way unprocessed would not be necessary at all.
I believe your changes pretty much resolve most of this already, I just did not check if all cases.
…D defaults to happen in applyDefaults, instead of applyCalculated
…n checking DD_TRACE_FLUSH_INTERVAL
| if (DD_TRACE_CLOUD_RESPONSE_PAYLOAD_TAGGING) { | ||
| this.#setBoolean(target, 'cloudPayloadTagging.responsesEnabled', true) | ||
| } | ||
| target['cloudPayloadTagging.rules'] = appendRules( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| target['cloudPayloadTagging.rules'] = appendRules( | |
| target.cloudPayloadTagging.rules = appendRules( |
And the object might have to be initialized up front as well as empty object.
| ) | ||
| } | ||
| if (DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH) { | ||
| target['cloudPayloadTagging.maxDepth'] = maybeInt(DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| target['cloudPayloadTagging.maxDepth'] = maybeInt(DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH) | |
| target.cloudPayloadTagging.maxDepth = maybeInt(DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH) |
packages/dd-trace/src/config.js
Outdated
| if (options.cloudPayloadTagging) { | ||
| this.#setBoolean(opts, 'cloudPayloadTagging.requestsEnabled', options.cloudPayloadTagging.requestsEnabled) | ||
| this.#setBoolean(opts, 'cloudPayloadTagging.responsesEnabled', options.cloudPayloadTagging.responsesEnabled) | ||
| opts['cloudPayloadTagging.maxDepth'] = maybeInt(options.cloudPayloadTagging.maxDepth) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| opts['cloudPayloadTagging.maxDepth'] = maybeInt(options.cloudPayloadTagging.maxDepth) | |
| opts.cloudPayloadTagging.maxDepth = maybeInt(options.cloudPayloadTagging.maxDepth) |
packages/dd-trace/src/config.js
Outdated
| this.#setBoolean(opts, 'cloudPayloadTagging.responsesEnabled', options.cloudPayloadTagging.responsesEnabled) | ||
| opts['cloudPayloadTagging.maxDepth'] = maybeInt(options.cloudPayloadTagging.maxDepth) | ||
| if (options.cloudPayloadTagging.request || options.cloudPayloadTagging.response) { | ||
| opts['cloudPayloadTagging.rules'] = appendRules( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| opts['cloudPayloadTagging.rules'] = appendRules( | |
| opts.cloudPayloadTagging.rules = appendRules( |
…al logic to its previous state
BridgeAR
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
LGTM
* Sync declarative config and env var support; add tests * Move runtime specific evaluations to defaults (e.g. remote config, crashtracking, etc) * Handle cloudPayloadTagging and installSignature
* Sync declarative config and env var support; add tests * Move runtime specific evaluations to defaults (e.g. remote config, crashtracking, etc) * Handle cloudPayloadTagging and installSignature
* Sync declarative config and env var support; add tests * Move runtime specific evaluations to defaults (e.g. remote config, crashtracking, etc) * Handle cloudPayloadTagging and installSignature
What does this PR do?
Previously, only product-enablement configs were supported for Declarative Config (application_monitoring.yaml files). This PR adds support for all env-var configs. Now, all 3 sources -- local file, env vars, and fleet file -- go through the same core logic in new function _applyConfigValues.
The following [smaller] changes were also made as a result of necessary refactoring:
should support legacy direct-set fields through all stableconfig and env var sources)Motivation
RFC
Declarative Config allows APM configuration to be managed at the host level through a YAML-formatted file. This approach is used in the fleet automation workflow, where users can apply configurations to their SDKs via the Fleet UI, or manage them directly through YAML files. Expanding support to all environment-variable-based settings bolsters feature parity and allows greater flexibility for users who prefer or rely on declarative configuration.
Plugin Checklist
Additional Notes