diff --git a/ci/init.js b/ci/init.js index 748194919e8..202a2080dba 100644 --- a/ci/init.js +++ b/ci/init.js @@ -5,6 +5,7 @@ const tracer = require('../packages/dd-trace') const { isTrue, isFalse } = require('../packages/dd-trace/src/util') const log = require('../packages/dd-trace/src/log') const { getEnvironmentVariable } = require('../packages/dd-trace/src/config-helper') +const { getResolvedEnv } = require('../packages/dd-trace/src/config-env-sources') const PACKAGE_MANAGERS = ['npm', 'yarn', 'pnpm'] const DEFAULT_FLUSH_INTERVAL = 5000 @@ -43,8 +44,8 @@ const baseOptions = { flushInterval: isJestWorker ? JEST_FLUSH_INTERVAL : DEFAULT_FLUSH_INTERVAL } -let shouldInit = !isFalse(getEnvironmentVariable('DD_CIVISIBILITY_ENABLED')) -const isAgentlessEnabled = isTrue(getEnvironmentVariable('DD_CIVISIBILITY_AGENTLESS_ENABLED')) +let shouldInit = !isFalse(getResolvedEnv('DD_CIVISIBILITY_ENABLED')) +const isAgentlessEnabled = isTrue(getResolvedEnv('DD_CIVISIBILITY_AGENTLESS_ENABLED')) if (!isTestWorker && isPackageManager()) { log.debug('dd-trace is not initialized in a package manager.') @@ -58,7 +59,7 @@ if (isTestWorker) { } } else { if (isAgentlessEnabled) { - if (getEnvironmentVariable('DD_API_KEY')) { + if (getResolvedEnv('DD_API_KEY')) { baseOptions.experimental = { exporter: 'datadog' } diff --git a/packages/datadog-instrumentations/src/helpers/register.js b/packages/datadog-instrumentations/src/helpers/register.js index 6e5f0f3985a..0d7b490233e 100644 --- a/packages/datadog-instrumentations/src/helpers/register.js +++ b/packages/datadog-instrumentations/src/helpers/register.js @@ -9,14 +9,10 @@ const log = require('../../../dd-trace/src/log') const checkRequireCache = require('./check-require-cache') const telemetry = require('../../../dd-trace/src/guardrails/telemetry') const { isInServerlessEnvironment } = require('../../../dd-trace/src/serverless') -const { getEnvironmentVariables } = require('../../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../../dd-trace/src/config-env-sources') -const envs = getEnvironmentVariables() - -const { - DD_TRACE_DISABLED_INSTRUMENTATIONS = '', - DD_TRACE_DEBUG = '' -} = envs +const DD_TRACE_DISABLED_INSTRUMENTATIONS = getResolvedEnv('DD_TRACE_DISABLED_INSTRUMENTATIONS') || '' +const DD_TRACE_DEBUG = getResolvedEnv('DD_TRACE_DEBUG') || '' const hooks = require('./hooks') const instrumentations = require('./instrumentations') diff --git a/packages/datadog-instrumentations/src/otel-sdk-trace.js b/packages/datadog-instrumentations/src/otel-sdk-trace.js index 90c9f30f475..3f50b94e263 100644 --- a/packages/datadog-instrumentations/src/otel-sdk-trace.js +++ b/packages/datadog-instrumentations/src/otel-sdk-trace.js @@ -3,11 +3,11 @@ const { addHook } = require('./helpers/instrument') const shimmer = require('../../datadog-shimmer') const tracer = require('../../dd-trace') -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') -const otelSdkEnabled = getEnvironmentVariable('DD_TRACE_OTEL_ENABLED') || -getEnvironmentVariable('OTEL_SDK_DISABLED') - ? !getEnvironmentVariable('OTEL_SDK_DISABLED') +const otelSdkEnabled = getResolvedEnv('DD_TRACE_OTEL_ENABLED') || +getResolvedEnv('OTEL_SDK_DISABLED') + ? !getResolvedEnv('OTEL_SDK_DISABLED') : undefined if (otelSdkEnabled) { diff --git a/packages/datadog-plugin-aws-sdk/src/base.js b/packages/datadog-plugin-aws-sdk/src/base.js index 6ff6d6f4bec..a5ea309b6ae 100644 --- a/packages/datadog-plugin-aws-sdk/src/base.js +++ b/packages/datadog-plugin-aws-sdk/src/base.js @@ -6,6 +6,7 @@ const { storage } = require('../../datadog-core') const { isTrue } = require('../../dd-trace/src/util') const { tagsFromRequest, tagsFromResponse } = require('../../dd-trace/src/payload-tagging') const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') class BaseAwsSdkPlugin extends ClientPlugin { static id = 'aws' @@ -190,7 +191,7 @@ class BaseAwsSdkPlugin extends ClientPlugin { isEnabled (request) { const serviceId = this.serviceIdentifier.toUpperCase() - const envVarValue = getEnvironmentVariable(`DD_TRACE_AWS_SDK_${serviceId}_ENABLED`) + const envVarValue = getEnvironmentVariable(`DD_TRACE_AWS_SDK_${serviceId}_ENABLED`) // I'm not sure about this one return envVarValue ? isTrue(envVarValue) : true } @@ -273,9 +274,10 @@ function normalizeConfig (config, serviceIdentifier) { const serviceId = serviceIdentifier.toUpperCase() const batchPropagationEnabled = isTrue( specificConfig.batchPropagationEnabled ?? + // Or this one getEnvironmentVariable(`DD_TRACE_AWS_SDK_${serviceId}_BATCH_PROPAGATION_ENABLED`) ?? config.batchPropagationEnabled ?? - getEnvironmentVariable('DD_TRACE_AWS_SDK_BATCH_PROPAGATION_ENABLED') + getResolvedEnv('DD_TRACE_AWS_SDK_BATCH_PROPAGATION_ENABLED') ) // Merge the specific config back into the main config diff --git a/packages/datadog-plugin-azure-event-hubs/src/producer.js b/packages/datadog-plugin-azure-event-hubs/src/producer.js index 44e38aba99d..937c5c34c1e 100644 --- a/packages/datadog-plugin-azure-event-hubs/src/producer.js +++ b/packages/datadog-plugin-azure-event-hubs/src/producer.js @@ -1,6 +1,6 @@ 'use strict' -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') const ProducerPlugin = require('../../dd-trace/src/plugins/producer') class AzureEventHubsProducerPlugin extends ProducerPlugin { @@ -75,7 +75,7 @@ function injectTraceContext (tracer, span, event) { } function batchLinksAreEnabled () { - const eh = getEnvironmentVariable('DD_TRACE_AZURE_EVENTHUBS_BATCH_LINKS_ENABLED') + const eh = getResolvedEnv('DD_TRACE_AZURE_EVENTHUBS_BATCH_LINKS_ENABLED') return eh !== 'false' } diff --git a/packages/datadog-plugin-azure-service-bus/src/producer.js b/packages/datadog-plugin-azure-service-bus/src/producer.js index 8fdd67f4cc7..bfa023f7cff 100644 --- a/packages/datadog-plugin-azure-service-bus/src/producer.js +++ b/packages/datadog-plugin-azure-service-bus/src/producer.js @@ -1,6 +1,6 @@ 'use strict' -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') const ProducerPlugin = require('../../dd-trace/src/plugins/producer') const spanContexts = new WeakMap() @@ -86,7 +86,7 @@ function injectTraceContext (tracer, span, msg) { } function batchLinksAreEnabled () { - const sb = getEnvironmentVariable('DD_TRACE_AZURE_SERVICEBUS_BATCH_LINKS_ENABLED') + const sb = getResolvedEnv('DD_TRACE_AZURE_SERVICEBUS_BATCH_LINKS_ENABLED') return sb !== 'false' } diff --git a/packages/datadog-plugin-cucumber/src/index.js b/packages/datadog-plugin-cucumber/src/index.js index 1168c358008..63bb236c7eb 100644 --- a/packages/datadog-plugin-cucumber/src/index.js +++ b/packages/datadog-plugin-cucumber/src/index.js @@ -3,6 +3,7 @@ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin') const { storage } = require('../../datadog-core') const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') const { TEST_SKIP_REASON, @@ -112,7 +113,7 @@ class CucumberPlugin extends CiPlugin { finishAllTraceSpans(this.testSessionSpan) this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName, - autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') + autoInjected: !!getResolvedEnv('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') }) this.libraryConfig = null diff --git a/packages/datadog-plugin-cypress/src/cypress-plugin.js b/packages/datadog-plugin-cypress/src/cypress-plugin.js index 842322ab24c..fbc11977b39 100644 --- a/packages/datadog-plugin-cypress/src/cypress-plugin.js +++ b/packages/datadog-plugin-cypress/src/cypress-plugin.js @@ -51,7 +51,7 @@ const { } = require('../../dd-trace/src/plugins/util/test') const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util') const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants') -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') const { appClosing: appClosingTelemetry } = require('../../dd-trace/src/telemetry') const log = require('../../dd-trace/src/log') @@ -644,7 +644,7 @@ class CypressPlugin { this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session') incrementCountMetric(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName, - autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') + autoInjected: !!getResolvedEnv('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') }) finishAllTraceSpans(this.testSessionSpan) diff --git a/packages/datadog-plugin-dd-trace-api/src/index.js b/packages/datadog-plugin-dd-trace-api/src/index.js index bc504550c40..6a479f6c562 100644 --- a/packages/datadog-plugin-dd-trace-api/src/index.js +++ b/packages/datadog-plugin-dd-trace-api/src/index.js @@ -3,13 +3,13 @@ const Plugin = require('../../dd-trace/src/plugins/plugin') const telemetryMetrics = require('../../dd-trace/src/telemetry/metrics') const apiMetrics = telemetryMetrics.manager.namespace('tracers') -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') // api ==> here const objectMap = new WeakMap() const injectionEnabledTag = - `injection_enabled:${getEnvironmentVariable('DD_INJECTION_ENABLED') ? 'yes' : 'no'}` + `injection_enabled:${getResolvedEnv('DD_INJECTION_ENABLED') ? 'yes' : 'no'}` module.exports = class DdTraceApiPlugin extends Plugin { static id = 'dd-trace-api' diff --git a/packages/datadog-plugin-jest/src/index.js b/packages/datadog-plugin-jest/src/index.js index a6ceaa143bd..c4e8fd6e8e2 100644 --- a/packages/datadog-plugin-jest/src/index.js +++ b/packages/datadog-plugin-jest/src/index.js @@ -3,6 +3,7 @@ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin') const { storage } = require('../../datadog-core') const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') const { TEST_STATUS, @@ -161,7 +162,7 @@ class JestPlugin extends CiPlugin { this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName, - autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') + autoInjected: !!getResolvedEnv('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') }) this.tracer._exporter.flush(() => { diff --git a/packages/datadog-plugin-mocha/src/index.js b/packages/datadog-plugin-mocha/src/index.js index 5636dc99a01..b672ae51741 100644 --- a/packages/datadog-plugin-mocha/src/index.js +++ b/packages/datadog-plugin-mocha/src/index.js @@ -2,7 +2,7 @@ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin') const { storage } = require('../../datadog-core') -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') const { TEST_STATUS, @@ -406,7 +406,7 @@ class MochaPlugin extends CiPlugin { finishAllTraceSpans(this.testSessionSpan) this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName, - autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') + autoInjected: !!getResolvedEnv('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') }) } this.libraryConfig = null diff --git a/packages/datadog-plugin-mongodb-core/src/index.js b/packages/datadog-plugin-mongodb-core/src/index.js index 2dcd801a119..856b44a931c 100644 --- a/packages/datadog-plugin-mongodb-core/src/index.js +++ b/packages/datadog-plugin-mongodb-core/src/index.js @@ -2,7 +2,7 @@ const { isTrue } = require('../../dd-trace/src/util') const DatabasePlugin = require('../../dd-trace/src/plugins/database') -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') class MongodbCorePlugin extends DatabasePlugin { static id = 'mongodb-core' @@ -20,7 +20,7 @@ class MongodbCorePlugin extends DatabasePlugin { configure (config) { super.configure(config) - const heartbeatFromEnv = getEnvironmentVariable('DD_TRACE_MONGODB_HEARTBEAT_ENABLED') + const heartbeatFromEnv = getResolvedEnv('DD_TRACE_MONGODB_HEARTBEAT_ENABLED') this.config.heartbeatEnabled = config.heartbeatEnabled ?? (heartbeatFromEnv && isTrue(heartbeatFromEnv)) ?? diff --git a/packages/datadog-plugin-playwright/src/index.js b/packages/datadog-plugin-playwright/src/index.js index ca5d9c612d5..25251e3c1c2 100644 --- a/packages/datadog-plugin-playwright/src/index.js +++ b/packages/datadog-plugin-playwright/src/index.js @@ -3,7 +3,7 @@ const { storage } = require('../../datadog-core') const id = require('../../dd-trace/src/id') const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin') -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') const { TEST_STATUS, @@ -106,7 +106,7 @@ class PlaywrightPlugin extends CiPlugin { finishAllTraceSpans(this.testSessionSpan) this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName, - autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') + autoInjected: !!getResolvedEnv('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') }) appClosingTelemetry() this.tracer._exporter.flush(onDone) @@ -393,7 +393,7 @@ class PlaywrightPlugin extends CiPlugin { span.finish() finishAllTraceSpans(span) - if (getEnvironmentVariable('DD_PLAYWRIGHT_WORKER')) { + if (getResolvedEnv('DD_PLAYWRIGHT_WORKER')) { this.tracer._exporter.flush(onDone) } }) diff --git a/packages/datadog-plugin-vitest/src/index.js b/packages/datadog-plugin-vitest/src/index.js index eaed04c2624..db218a508ea 100644 --- a/packages/datadog-plugin-vitest/src/index.js +++ b/packages/datadog-plugin-vitest/src/index.js @@ -2,7 +2,7 @@ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin') const { storage } = require('../../datadog-core') -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('../../dd-trace/src/config-env-sources') const { TEST_STATUS, @@ -281,11 +281,11 @@ class VitestPlugin extends CiPlugin { this.addBind('ci:vitest:test-suite:start', (ctx) => { const { testSuiteAbsolutePath, frameworkVersion } = ctx - this.command = getEnvironmentVariable('DD_CIVISIBILITY_TEST_COMMAND') + this.command = getResolvedEnv('DD_CIVISIBILITY_TEST_COMMAND') this.frameworkVersion = frameworkVersion const testSessionSpanContext = this.tracer.extract('text_map', { - 'x-datadog-trace-id': getEnvironmentVariable('DD_CIVISIBILITY_TEST_SESSION_ID'), - 'x-datadog-parent-id': getEnvironmentVariable('DD_CIVISIBILITY_TEST_MODULE_ID') + 'x-datadog-trace-id': getResolvedEnv('DD_CIVISIBILITY_TEST_SESSION_ID'), + 'x-datadog-parent-id': getResolvedEnv('DD_CIVISIBILITY_TEST_MODULE_ID') }) const trimmedCommand = DD_MAJOR < 6 ? this.command : 'vitest run' @@ -405,7 +405,7 @@ class VitestPlugin extends CiPlugin { finishAllTraceSpans(this.testSessionSpan) this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName, - autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') + autoInjected: !!getResolvedEnv('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER') }) this.tracer._exporter.flush(onFinish) }) diff --git a/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js b/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js index 6f10be0ba9d..09caf516f92 100644 --- a/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +++ b/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js @@ -3,7 +3,7 @@ const request = require('../../exporters/common/request') const id = require('../../id') const log = require('../../log') -const { getEnvironmentVariable } = require('../../config-helper') +const { getResolvedEnv } = require('../../config-env-sources') const { incrementCountMetric, @@ -51,7 +51,7 @@ function getKnownTests ({ options.path = `${evpProxyPrefix}/api/v2/ci/libraries/tests` options.headers['X-Datadog-EVP-Subdomain'] = 'api' } else { - const apiKey = getEnvironmentVariable('DD_API_KEY') + const apiKey = getResolvedEnv('DD_API_KEY') if (!apiKey) { return done(new Error('Known tests were not fetched because Datadog API key is not defined.')) } diff --git a/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js b/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js index b3646d81cfe..3f606cab2c3 100644 --- a/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +++ b/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js @@ -2,7 +2,7 @@ const request = require('../../../exporters/common/request') const log = require('../../../log') const { safeJSONStringify } = require('../../../exporters/common/util') -const { getEnvironmentVariable } = require('../../../config-helper') +const { getResolvedEnv } = require('../../../config-env-sources') const { CoverageCIVisibilityEncoder } = require('../../../encode/coverage-ci-visibility') const BaseWriter = require('../../../exporters/common/writer') @@ -29,7 +29,7 @@ class Writer extends BaseWriter { path: '/api/v2/citestcov', method: 'POST', headers: { - 'dd-api-key': getEnvironmentVariable('DD_API_KEY'), + 'dd-api-key': getResolvedEnv('DD_API_KEY'), ...form.getHeaders() }, timeout: 15_000, diff --git a/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js b/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js index 199b2910e8b..b7f023b26c2 100644 --- a/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +++ b/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js @@ -3,7 +3,7 @@ const request = require('../../../exporters/common/request') const log = require('../../../log') const { safeJSONStringify } = require('../../../exporters/common/util') const { JSONEncoder } = require('../../encode/json-encoder') -const { getEnvironmentVariable } = require('../../../config-helper') +const { getResolvedEnv } = require('../../../config-env-sources') const BaseWriter = require('../../../exporters/common/writer') @@ -24,7 +24,7 @@ class DynamicInstrumentationLogsWriter extends BaseWriter { path: '/api/v2/logs', method: 'POST', headers: { - 'dd-api-key': getEnvironmentVariable('DD_API_KEY'), + 'dd-api-key': getResolvedEnv('DD_API_KEY'), 'Content-Type': 'application/json' }, // TODO: what's a good value for timeout for the logs intake? diff --git a/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js b/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js index f4e017a3e0e..e25f40632e7 100644 --- a/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +++ b/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js @@ -2,7 +2,7 @@ const request = require('../../../exporters/common/request') const { safeJSONStringify } = require('../../../exporters/common/util') const log = require('../../../log') -const { getEnvironmentVariable } = require('../../../config-helper') +const { getResolvedEnv } = require('../../../config-env-sources') const { AgentlessCiVisibilityEncoder } = require('../../../encode/agentless-ci-visibility') const BaseWriter = require('../../../exporters/common/writer') @@ -30,7 +30,7 @@ class Writer extends BaseWriter { path: '/api/v2/citestcycle', method: 'POST', headers: { - 'dd-api-key': getEnvironmentVariable('DD_API_KEY'), + 'dd-api-key': getResolvedEnv('DD_API_KEY'), 'Content-Type': 'application/msgpack' }, timeout: 15_000, diff --git a/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js b/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js index 98ebed4e7c9..6eacaec4d1f 100644 --- a/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +++ b/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js @@ -5,7 +5,7 @@ const path = require('path') const FormData = require('../../../exporters/common/form-data') const request = require('../../../exporters/common/request') -const { getEnvironmentVariable } = require('../../../config-helper') +const { getResolvedEnv } = require('../../../config-env-sources') const log = require('../../../log') const { isFalse } = require('../../../util') @@ -51,7 +51,7 @@ function getCommonRequestOptions (url) { return { method: 'POST', headers: { - 'dd-api-key': getEnvironmentVariable('DD_API_KEY') + 'dd-api-key': getResolvedEnv('DD_API_KEY') }, timeout: 15_000, url @@ -288,7 +288,7 @@ function sendGitMetadata (url, { isEvpProxy, evpProxyPrefix }, configRepositoryU } // Otherwise we unshallow and get commits to upload again log.debug('It is shallow clone, unshallowing...') - if (!isFalse(getEnvironmentVariable('DD_CIVISIBILITY_GIT_UNSHALLOW_ENABLED'))) { + if (!isFalse(getResolvedEnv('DD_CIVISIBILITY_GIT_UNSHALLOW_ENABLED'))) { unshallowRepository(false) } diff --git a/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js b/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js index 5cd7e775387..6f05d83aa9b 100644 --- a/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +++ b/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js @@ -26,6 +26,7 @@ function getInterprocessTraceCode () { if (getEnvironmentVariable('DD_PLAYWRIGHT_WORKER')) { return PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE } + // ?? if (getEnvironmentVariable('TINYPOOL_WORKER_ID')) { return VITEST_WORKER_TRACE_PAYLOAD_CODE } diff --git a/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js b/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js index ac7e0e1ee8b..a71cdc59212 100644 --- a/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +++ b/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js @@ -2,7 +2,7 @@ const request = require('../../exporters/common/request') const log = require('../../log') -const { getEnvironmentVariable } = require('../../config-helper') +const { getResolvedEnv } = require('../../config-env-sources') const { incrementCountMetric, distributionMetric, @@ -49,7 +49,7 @@ function getSkippableSuites ({ options.path = `${evpProxyPrefix}/api/v2/ci/tests/skippable` options.headers['X-Datadog-EVP-Subdomain'] = 'api' } else { - const apiKey = getEnvironmentVariable('DD_API_KEY') + const apiKey = getResolvedEnv('DD_API_KEY') if (!apiKey) { return done(new Error('Skippable suites were not fetched because Datadog API key is not defined.')) } diff --git a/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js b/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js index 1e0fd6550e7..e211c687758 100644 --- a/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +++ b/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js @@ -2,7 +2,7 @@ const Plugin = require('../../plugins/plugin') const log = require('../../log') -const { getEnvironmentVariable } = require('../../config-helper') +const { getResolvedEnv } = require('../../config-env-sources') function getWinstonLogSubmissionParameters (config) { const { site, service } = config @@ -12,16 +12,16 @@ function getWinstonLogSubmissionParameters (config) { path: `/api/v2/logs?ddsource=winston&service=${service}`, ssl: true, headers: { - 'DD-API-KEY': getEnvironmentVariable('DD_API_KEY') + 'DD-API-KEY': getResolvedEnv('DD_API_KEY') } } - if (!getEnvironmentVariable('DD_AGENTLESS_LOG_SUBMISSION_URL')) { + if (!getResolvedEnv('DD_AGENTLESS_LOG_SUBMISSION_URL')) { return defaultParameters } try { - const url = new URL(getEnvironmentVariable('DD_AGENTLESS_LOG_SUBMISSION_URL')) + const url = new URL(getResolvedEnv('DD_AGENTLESS_LOG_SUBMISSION_URL')) return { host: url.hostname, port: url.port, diff --git a/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js b/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js index e16b62dcdfa..2c5ad36122f 100644 --- a/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +++ b/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js @@ -3,7 +3,7 @@ const request = require('../../exporters/common/request') const id = require('../../id') const log = require('../../log') -const { getEnvironmentVariable } = require('../../config-helper') +const { getResolvedEnv } = require('../../config-env-sources') const { incrementCountMetric, distributionMetric, @@ -48,7 +48,7 @@ function getLibraryConfiguration ({ options.path = `${evpProxyPrefix}/api/v2/libraries/tests/services/setting` options.headers['X-Datadog-EVP-Subdomain'] = 'api' } else { - const apiKey = getEnvironmentVariable('DD_API_KEY') + const apiKey = getResolvedEnv('DD_API_KEY') if (!apiKey) { return done(new Error('Request to settings endpoint was not done because Datadog API key is not defined.')) } @@ -126,11 +126,11 @@ function getLibraryConfiguration ({ log.debug('Remote settings: %j', settings) - if (getEnvironmentVariable('DD_CIVISIBILITY_DANGEROUSLY_FORCE_COVERAGE')) { + if (getResolvedEnv('DD_CIVISIBILITY_DANGEROUSLY_FORCE_COVERAGE')) { settings.isCodeCoverageEnabled = true log.debug('Dangerously set code coverage to true') } - if (getEnvironmentVariable('DD_CIVISIBILITY_DANGEROUSLY_FORCE_TEST_SKIPPING')) { + if (getResolvedEnv('DD_CIVISIBILITY_DANGEROUSLY_FORCE_TEST_SKIPPING')) { settings.isSuitesSkippingEnabled = true log.debug('Dangerously set test skipping to true') } diff --git a/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js b/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js index a6a8516efb6..db37bfa9b25 100644 --- a/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +++ b/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js @@ -2,7 +2,7 @@ const request = require('../../exporters/common/request') const id = require('../../id') -const { getEnvironmentVariable } = require('../../config-helper') +const { getResolvedEnv } = require('../../config-env-sources') const log = require('../../log') function getTestManagementTests ({ @@ -35,7 +35,7 @@ function getTestManagementTests ({ options.path = `${evpProxyPrefix}/api/v2/test/libraries/test-management/tests` options.headers['X-Datadog-EVP-Subdomain'] = 'api' } else { - const apiKey = getEnvironmentVariable('DD_API_KEY') + const apiKey = getResolvedEnv('DD_API_KEY') if (!apiKey) { return done(new Error('Test management tests were not fetched because Datadog API key is not defined.')) } diff --git a/packages/dd-trace/src/config-env-sources.js b/packages/dd-trace/src/config-env-sources.js new file mode 100644 index 00000000000..79788389cc8 --- /dev/null +++ b/packages/dd-trace/src/config-env-sources.js @@ -0,0 +1,112 @@ +'use strict' + +const { isInServerlessEnvironment } = require('./serverless') +const { getValueFromEnvSource, getEnvironmentVariable } = require('./config-helper') + +/** + * Internal helper that centralizes configuration coming from stable config files and environment variables. + * + * Responsibilities: + * - Load and parse the local and fleet stable configuration files (via `StableConfig`). + * - Expose the stable config maps (`localStableConfig`, `fleetStableConfig`) and any warnings + * `stableConfigWarnings`. + * - Provide `getResolvedEnv(name)` to resolve a configuration value from: + * 1. Fleet stable config + * 2. Environment variables (and their aliases) + * 3. Local stable config + * + * Usage patterns: + * - Most modules that need a single resolved value should call `getResolvedEnv(name)`. + * - The main `Config` class reads `localStableConfig` / `fleetStableConfig` directly so it can: + * - Preserve per-source origins (fleet/local/env) for telemetry reporting. + * - Merge sources in its own priority order. + * - Tests can reset the singleton with `resetConfigEnvSources()` to force re-loading after + * modifying stable config files or environment variables. + */ +class ConfigEnvSources { + constructor () { + const isServerless = isInServerlessEnvironment() + + let localStableConfig = {} + let fleetStableConfig = {} + let stableConfigWarnings = [] + + if (!isServerless) { + const result = this.#loadStableConfig() + if (result) { + localStableConfig = result.localEntries + fleetStableConfig = result.fleetEntries + stableConfigWarnings = result.warnings + } + } + + // Expose raw stable config on the instance + this.localStableConfig = localStableConfig + this.fleetStableConfig = fleetStableConfig + this.stableConfigWarnings = stableConfigWarnings + } + + #loadStableConfig () { + try { + const StableConfig = require('./config_stable') + const instance = new StableConfig() + return { + localEntries: instance.localEntries ?? {}, + fleetEntries: instance.fleetEntries ?? {}, + warnings: instance.warnings ?? [] + } + } catch { + // Stable config is optional, continue without it + return null + } + } +} + +function createConfigEnvSources () { + return new ConfigEnvSources() +} + +let configEnvSourcesInstance = null + +function getConfigEnvSources () { + if (!configEnvSourcesInstance) { + configEnvSourcesInstance = new ConfigEnvSources() + } + return configEnvSourcesInstance +} + +/** + * Reset the singleton instance (useful for testing) + */ +function resetConfigEnvSources () { + configEnvSourcesInstance = null +} + +/** + * Returns the resolved configuration value from ConfigEnvSources. Falls back to aliases if the + * canonical name is not set. Throws an error if the configuration is not supported. + * + * @param {string} name Environment variable name + * @returns {string|undefined} + * @throws {Error} if the configuration is not supported + */ +function getResolvedEnv (name) { + const config = getConfigEnvSources() + if (getValueFromEnvSource(name, config.fleetStableConfig) !== undefined) { + return getValueFromEnvSource(name, config.fleetStableConfig) + } + if (getEnvironmentVariable(name) !== undefined) { + return getEnvironmentVariable(name) + } + if (getValueFromEnvSource(name, config.localStableConfig) !== undefined) { + return getValueFromEnvSource(name, config.localStableConfig) + } +} + +module.exports = { + ConfigEnvSources, + createConfigEnvSources, + getConfigEnvSources, + resetConfigEnvSources, + getResolvedEnv +} diff --git a/packages/dd-trace/src/config-helper.js b/packages/dd-trace/src/config-helper.js index eb457fcc959..448c9b14e89 100644 --- a/packages/dd-trace/src/config-helper.js +++ b/packages/dd-trace/src/config-helper.js @@ -80,10 +80,9 @@ module.exports = { * @returns {string|undefined} * @throws {Error} if the configuration is not supported */ - // This method, and callers of this method, need to be updated to check for declarative config sources as well. getEnvironmentVariable (name) { if ((name.startsWith('DD_') || name.startsWith('OTEL_') || aliasToCanonical[name]) && - !supportedConfigurations[name]) { + !supportedConfigurations[name]) { throw new Error(`Missing ${name} env/configuration in "supported-configurations.json" file.`) } const config = process.env[name] @@ -95,5 +94,31 @@ module.exports = { } } return config + }, + + /** + * Returns the value stored at the given name, assumed to be in environment variable format, + * from the provided source. Falls back to aliases if the canonical name is not set. + * Used for stable config sources. + * + * @param {string} name Environment variable name + * @param {object} source Environment source + * @returns {string|undefined} + * @throws {Error} if the configuration is not supported + */ + getValueFromEnvSource (name, source) { + if ((name.startsWith('DD_') || name.startsWith('OTEL_') || aliasToCanonical[name]) && + !supportedConfigurations[name]) { + throw new Error(`Missing ${name} env/configuration in "supported-configurations.json" file.`) + } + const value = source[name] + if (value === undefined && aliases[name]) { + for (const alias of aliases[name]) { + if (source[alias] !== undefined) { + return source[alias] + } + } + } + return value } } diff --git a/packages/dd-trace/src/config.js b/packages/dd-trace/src/config.js index 898877e5f36..0c16716349e 100644 --- a/packages/dd-trace/src/config.js +++ b/packages/dd-trace/src/config.js @@ -18,6 +18,7 @@ const { isInServerlessEnvironment, getIsGCPFunction, getIsAzureFunction } = requ const { ORIGIN_KEY } = require('./constants') const { appendRules } = require('./payload-tagging/config') const { getEnvironmentVariable: getEnv, getEnvironmentVariables } = require('./config-helper') +const { getConfigEnvSources } = require('./config-env-sources') const defaults = require('./config_defaults') const path = require('path') const { DD_MAJOR } = require('../../../version') @@ -272,8 +273,12 @@ class Config { constructor (options = {}) { if (!isInServerlessEnvironment()) { // Bail out early if we're in a serverless environment, stable config isn't supported - const StableConfig = require('./config_stable') - this.stableConfig = new StableConfig() + const configEnvSources = getConfigEnvSources() + this.stableConfig = { + fleetEntries: configEnvSources.fleetStableConfig, + localEntries: configEnvSources.localStableConfig, + warnings: configEnvSources.stableConfigWarnings + } } const envs = getEnvironmentVariables() diff --git a/packages/dd-trace/src/debugger/devtools_client/send.js b/packages/dd-trace/src/debugger/devtools_client/send.js index b0a66c84737..99956c3f380 100644 --- a/packages/dd-trace/src/debugger/devtools_client/send.js +++ b/packages/dd-trace/src/debugger/devtools_client/send.js @@ -9,7 +9,7 @@ const request = require('../../exporters/common/request') const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags') const log = require('./log') const { version } = require('../../../../../package.json') -const { getEnvironmentVariable } = require('../../config-helper') +const { getResolvedEnv } = require('../../config-env-sources') module.exports = send @@ -22,8 +22,8 @@ const hostname = getHostname() const service = config.service const ddtags = [ - ['env', getEnvironmentVariable('DD_ENV')], - ['version', getEnvironmentVariable('DD_VERSION')], + ['env', getResolvedEnv('DD_ENV')], + ['version', getResolvedEnv('DD_VERSION')], ['debugger_version', version], ['host_name', hostname], [GIT_COMMIT_SHA, config.commitSHA], diff --git a/packages/dd-trace/src/encode/0.4.js b/packages/dd-trace/src/encode/0.4.js index b8f40f45e48..8272647e367 100644 --- a/packages/dd-trace/src/encode/0.4.js +++ b/packages/dd-trace/src/encode/0.4.js @@ -5,7 +5,7 @@ const { MsgpackChunk, MsgpackEncoder } = require('../msgpack') const log = require('../log') const { isTrue } = require('../util') const { memoize } = require('../log/utils') -const { getEnvironmentVariable } = require('../config-helper') +const { getResolvedEnv } = require('../config-env-sources') const SOFT_LIMIT = 8 * 1024 * 1024 // 8MB @@ -31,7 +31,7 @@ class AgentEncoder { this._stringBytes = new MsgpackChunk() this._writer = writer this._reset() - this._debugEncoding = isTrue(getEnvironmentVariable('DD_TRACE_ENCODING_DEBUG')) + this._debugEncoding = isTrue(getResolvedEnv('DD_TRACE_ENCODING_DEBUG')) this._config = this._writer?._config } diff --git a/packages/dd-trace/src/exporters/common/docker.js b/packages/dd-trace/src/exporters/common/docker.js index b7d14b353bb..26c7eab7de9 100644 --- a/packages/dd-trace/src/exporters/common/docker.js +++ b/packages/dd-trace/src/exporters/common/docker.js @@ -1,9 +1,9 @@ 'use strict' const fs = require('fs') -const { getEnvironmentVariable } = require('../../config-helper') +const { getResolvedEnv } = require('../../config-env-sources') -const DD_EXTERNAL_ENV = getEnvironmentVariable('DD_EXTERNAL_ENV') +const DD_EXTERNAL_ENV = getResolvedEnv('DD_EXTERNAL_ENV') // The second part is the PCF / Garden regexp. We currently assume no suffix($) to avoid matching pod UIDs // See https://github.com/DataDog/datadog-agent/blob/7.40.x/pkg/util/cgroups/reader.go#L50 diff --git a/packages/dd-trace/src/exporters/common/util.js b/packages/dd-trace/src/exporters/common/util.js index 5dd66c43726..d7f733e0d0d 100644 --- a/packages/dd-trace/src/exporters/common/util.js +++ b/packages/dd-trace/src/exporters/common/util.js @@ -1,12 +1,12 @@ 'use strict' -const { getEnvironmentVariable } = require('../../config-helper') +const { getResolvedEnv } = require('../../config-env-sources') function safeJSONStringify (value) { return JSON.stringify( value, (key, value) => key === 'dd-api-key' ? undefined : value, - getEnvironmentVariable('DD_TRACE_BEAUTIFUL_LOGS') ? 2 : undefined + getResolvedEnv('DD_TRACE_BEAUTIFUL_LOGS') ? 2 : undefined ) } diff --git a/packages/dd-trace/src/index.js b/packages/dd-trace/src/index.js index f83890f241c..af71db3ca37 100644 --- a/packages/dd-trace/src/index.js +++ b/packages/dd-trace/src/index.js @@ -1,14 +1,14 @@ 'use strict' const { isFalse } = require('./util') -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('./config-env-sources') // Global `jest` is only present in Jest workers. const inJestWorker = typeof jest !== 'undefined' -const ddTraceDisabled = getEnvironmentVariable('DD_TRACE_ENABLED') - ? isFalse(getEnvironmentVariable('DD_TRACE_ENABLED')) - : String(getEnvironmentVariable('OTEL_TRACES_EXPORTER')).toLowerCase() === 'none' +const ddTraceDisabled = getResolvedEnv('DD_TRACE_ENABLED') + ? isFalse(getResolvedEnv('DD_TRACE_ENABLED')) + : String(getResolvedEnv('OTEL_TRACES_EXPORTER')).toLowerCase() === 'none' module.exports = ddTraceDisabled || inJestWorker ? require('./noop/proxy') diff --git a/packages/dd-trace/src/lambda/handler.js b/packages/dd-trace/src/lambda/handler.js index 4a4f9fa653e..9c2626a00bf 100644 --- a/packages/dd-trace/src/lambda/handler.js +++ b/packages/dd-trace/src/lambda/handler.js @@ -4,7 +4,7 @@ const log = require('../log') const { channel } = require('../../../datadog-instrumentations/src/helpers/instrument') const { ERROR_MESSAGE, ERROR_TYPE } = require('../constants') const { ImpendingTimeout } = require('./runtime/errors') -const { getEnvironmentVariable } = require('../config-helper') +const { getResolvedEnv } = require('../config-env-sources') const globalTracer = global._ddtrace const tracer = globalTracer._tracer @@ -26,7 +26,7 @@ let __lambdaTimeout function checkTimeout (context) { const remainingTimeInMillis = context.getRemainingTimeInMillis() - let apmFlushDeadline = Number.parseInt(getEnvironmentVariable('DD_APM_FLUSH_DEADLINE_MILLISECONDS')) || 100 + let apmFlushDeadline = Number.parseInt(getResolvedEnv('DD_APM_FLUSH_DEADLINE_MILLISECONDS')) || 100 apmFlushDeadline = apmFlushDeadline < 0 ? 100 : apmFlushDeadline __lambdaTimeout = setTimeout(() => { diff --git a/packages/dd-trace/src/lambda/index.js b/packages/dd-trace/src/lambda/index.js index ce0a5d783c9..018af13340a 100644 --- a/packages/dd-trace/src/lambda/index.js +++ b/packages/dd-trace/src/lambda/index.js @@ -1,13 +1,13 @@ 'use strict' const { registerLambdaHook } = require('./runtime/ritm') -const { getEnvironmentVariable } = require('../config-helper') +const { getResolvedEnv } = require('../config-env-sources') /** * It is safe to do it this way, since customers will never be expected to disable * this specific instrumentation through the init config object. */ -const _DD_TRACE_DISABLED_INSTRUMENTATIONS = getEnvironmentVariable('DD_TRACE_DISABLED_INSTRUMENTATIONS') || '' +const _DD_TRACE_DISABLED_INSTRUMENTATIONS = getResolvedEnv('DD_TRACE_DISABLED_INSTRUMENTATIONS') || '' const _disabledInstrumentations = new Set( _DD_TRACE_DISABLED_INSTRUMENTATIONS ? _DD_TRACE_DISABLED_INSTRUMENTATIONS.split(',') : [] ) diff --git a/packages/dd-trace/src/llmobs/sdk.js b/packages/dd-trace/src/llmobs/sdk.js index 87cf98ea120..95f2f276944 100644 --- a/packages/dd-trace/src/llmobs/sdk.js +++ b/packages/dd-trace/src/llmobs/sdk.js @@ -14,7 +14,7 @@ const Span = require('../opentracing/span') const tracerVersion = require('../../../../package.json').version const logger = require('../log') -const { getEnvironmentVariable } = require('../config-helper') +const { getResolvedEnv } = require('../config-env-sources') const telemetry = require('./telemetry') const LLMObsTagger = require('./tagger') @@ -55,7 +55,7 @@ class LLMObs extends NoopLLMObs { const { mlApp, agentlessEnabled } = options - const DD_LLMOBS_ENABLED = getEnvironmentVariable('DD_LLMOBS_ENABLED') + const DD_LLMOBS_ENABLED = getResolvedEnv('DD_LLMOBS_ENABLED') const llmobsConfig = { mlApp, diff --git a/packages/dd-trace/src/opentracing/span.js b/packages/dd-trace/src/opentracing/span.js index 41c0988c82f..0c6a5afefcf 100644 --- a/packages/dd-trace/src/opentracing/span.js +++ b/packages/dd-trace/src/opentracing/span.js @@ -13,17 +13,17 @@ const { storage } = require('../../../datadog-core') const telemetryMetrics = require('../telemetry/metrics') const { channel } = require('dc-polyfill') const util = require('util') -const { getEnvironmentVariable } = require('../config-helper') +const { getResolvedEnv } = require('../config-env-sources') const tracerMetrics = telemetryMetrics.manager.namespace('tracers') -const DD_TRACE_EXPERIMENTAL_STATE_TRACKING = getEnvironmentVariable('DD_TRACE_EXPERIMENTAL_STATE_TRACKING') -const DD_TRACE_EXPERIMENTAL_SPAN_COUNTS = getEnvironmentVariable('DD_TRACE_EXPERIMENTAL_SPAN_COUNTS') +const DD_TRACE_EXPERIMENTAL_STATE_TRACKING = getResolvedEnv('DD_TRACE_EXPERIMENTAL_STATE_TRACKING') +const DD_TRACE_EXPERIMENTAL_SPAN_COUNTS = getResolvedEnv('DD_TRACE_EXPERIMENTAL_SPAN_COUNTS') const unfinishedRegistry = createRegistry('unfinished') const finishedRegistry = createRegistry('finished') -const OTEL_ENABLED = !!getEnvironmentVariable('DD_TRACE_OTEL_ENABLED') +const OTEL_ENABLED = !!getResolvedEnv('DD_TRACE_OTEL_ENABLED') const ALLOWED = new Set(['string', 'number', 'boolean']) const integrationCounters = { diff --git a/packages/dd-trace/src/plugin_manager.js b/packages/dd-trace/src/plugin_manager.js index 337330d4ba5..79fe8339b40 100644 --- a/packages/dd-trace/src/plugin_manager.js +++ b/packages/dd-trace/src/plugin_manager.js @@ -5,6 +5,7 @@ const { isFalse, isTrue, normalizePluginEnvName } = require('./util') const plugins = require('./plugins') const log = require('./log') const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('./config-env-sources') // Test optimization plugins that should only be enabled when isCiVisibility is true const TEST_OPTIMIZATION_PLUGINS = new Set([ @@ -24,7 +25,7 @@ if (getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') !== undefined) { require('./lambda') } -const DD_TRACE_DISABLED_PLUGINS = getEnvironmentVariable('DD_TRACE_DISABLED_PLUGINS') +const DD_TRACE_DISABLED_PLUGINS = getResolvedEnv('DD_TRACE_DISABLED_PLUGINS') const disabledPlugins = new Set( DD_TRACE_DISABLED_PLUGINS && DD_TRACE_DISABLED_PLUGINS.split(',').map(plugin => plugin.trim()) @@ -41,7 +42,7 @@ loadChannel.subscribe(({ name }) => { function maybeEnable (Plugin) { if (!Plugin || typeof Plugin !== 'function') return if (!pluginClasses[Plugin.id]) { - const enabled = getEnvEnabled(Plugin) + const enabled = getEnabled(Plugin) // TODO: remove the need to load the plugin class in order to disable the plugin if (isFalse(enabled) || disabledPlugins.has(Plugin.id)) { @@ -54,9 +55,9 @@ function maybeEnable (Plugin) { } } -function getEnvEnabled (Plugin) { +function getEnabled (Plugin) { const envName = `DD_TRACE_${Plugin.id.toUpperCase()}_ENABLED` - return getEnvironmentVariable(normalizePluginEnvName(envName)) + return getResolvedEnv(normalizePluginEnvName(envName)) } // TODO this must always be a singleton. @@ -94,7 +95,8 @@ module.exports = class PluginManager { this._pluginsByName[name] = new Plugin(this._tracer, this._tracerConfig) } const pluginConfig = this._configsByName[name] || { - enabled: this._tracerConfig.plugins !== false && (!Plugin.experimental || isTrue(getEnvEnabled(Plugin))) + enabled: this._tracerConfig.plugins !== false && + (!Plugin.experimental || isTrue(getEnabled(Plugin))) } // extracts predetermined configuration from tracer and combines it with plugin-specific config diff --git a/packages/dd-trace/src/plugins/util/git-cache.js b/packages/dd-trace/src/plugins/util/git-cache.js index 0dfc99d40da..324b9483dca 100644 --- a/packages/dd-trace/src/plugins/util/git-cache.js +++ b/packages/dd-trace/src/plugins/util/git-cache.js @@ -7,11 +7,11 @@ const crypto = require('crypto') const cp = require('child_process') const log = require('../../log') -const { getEnvironmentVariable } = require('../../config-helper') +const { getResolvedEnv } = require('../../config-env-sources') const { isTrue } = require('../../util') -let isGitEnabled = isTrue(getEnvironmentVariable('DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_ENABLED')) -const GIT_CACHE_DIR = getEnvironmentVariable('DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_DIR') || +let isGitEnabled = isTrue(getResolvedEnv('DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_ENABLED')) +const GIT_CACHE_DIR = getResolvedEnv('DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_DIR') || path.join(os.tmpdir(), 'dd-trace-git-cache') function ensureCacheDir () { diff --git a/packages/dd-trace/src/profiling/exporter_cli.js b/packages/dd-trace/src/profiling/exporter_cli.js index 564877aa319..0c3c44a9c98 100644 --- a/packages/dd-trace/src/profiling/exporter_cli.js +++ b/packages/dd-trace/src/profiling/exporter_cli.js @@ -8,7 +8,7 @@ const { ConsoleLogger } = require('./loggers/console') const { tagger } = require('./tagger') const fs = require('fs') const { fileURLToPath } = require('url') -const { getEnvironmentVariable } = require('../config-helper') +const { getResolvedEnv } = require('../config-env-sources') const logger = new ConsoleLogger() const timeoutMs = 15 * 1000 @@ -17,9 +17,9 @@ function exporterFromURL (url) { if (url.protocol === 'file:') { return new FileExporter({ pprofPrefix: fileURLToPath(url) }) } - const injectionEnabled = (getEnvironmentVariable('DD_INJECTION_ENABLED') ?? '').split(',') + const injectionEnabled = (getResolvedEnv('DD_INJECTION_ENABLED') ?? '').split(',') const libraryInjected = injectionEnabled.length > 0 - const profilingEnabled = (getEnvironmentVariable('DD_PROFILING_ENABLED') ?? '').toLowerCase() + const profilingEnabled = (getResolvedEnv('DD_PROFILING_ENABLED') ?? '').toLowerCase() const activation = ['true', '1'].includes(profilingEnabled) ? 'manual' : profilingEnabled === 'auto' diff --git a/packages/dd-trace/src/proxy.js b/packages/dd-trace/src/proxy.js index 321117f9fa7..7e7ef6bdd12 100644 --- a/packages/dd-trace/src/proxy.js +++ b/packages/dd-trace/src/proxy.js @@ -10,7 +10,7 @@ const telemetry = require('./telemetry') const nomenclature = require('./service-naming') const PluginManager = require('./plugin_manager') const NoopDogStatsDClient = require('./noop/dogstatsd') -const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper') +const { getResolvedEnv } = require('./config-env-sources') const { setBaggageItem, getBaggageItem, @@ -202,7 +202,7 @@ class Tracer extends NoopProxy { this._testApiManualPlugin.configure({ ...config, enabled: true }, false) } if (config.ciVisAgentlessLogSubmissionEnabled) { - if (getEnvironmentVariable('DD_API_KEY')) { + if (getResolvedEnv('DD_API_KEY')) { const LogSubmissionPlugin = require('./ci-visibility/log-submission/log-submission-plugin') const automaticLogPlugin = new LogSubmissionPlugin(this) automaticLogPlugin.configure({ ...config, enabled: true }) diff --git a/packages/dd-trace/src/runtime_metrics/runtime_metrics.js b/packages/dd-trace/src/runtime_metrics/runtime_metrics.js index fc9cb546adc..40471ce784e 100644 --- a/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +++ b/packages/dd-trace/src/runtime_metrics/runtime_metrics.js @@ -8,12 +8,12 @@ const process = require('process') const { DogStatsDClient, MetricsAggregationClient } = require('../dogstatsd') const log = require('../log') const { performance, PerformanceObserver, monitorEventLoopDelay } = require('perf_hooks') -const { getEnvironmentVariable } = require('../config-helper') +const { getResolvedEnv } = require('../config-env-sources') const { NODE_MAJOR } = require('../../../../version') // TODO: This environment variable may not be changed, since the agent expects a flush every ten seconds. // It is only a variable for testing. Think about alternatives. -const DD_RUNTIME_METRICS_FLUSH_INTERVAL = getEnvironmentVariable('DD_RUNTIME_METRICS_FLUSH_INTERVAL') ?? '10000' +const DD_RUNTIME_METRICS_FLUSH_INTERVAL = getResolvedEnv('DD_RUNTIME_METRICS_FLUSH_INTERVAL') ?? '10000' const INTERVAL = Number.parseInt(DD_RUNTIME_METRICS_FLUSH_INTERVAL, 10) const eventLoopDelayResolution = 4 diff --git a/packages/dd-trace/src/span_processor.js b/packages/dd-trace/src/span_processor.js index bc3231016ee..8aee2c1f187 100644 --- a/packages/dd-trace/src/span_processor.js +++ b/packages/dd-trace/src/span_processor.js @@ -4,7 +4,7 @@ const log = require('./log') const spanFormat = require('./span_format') const SpanSampler = require('./span_sampler') const GitMetadataTagger = require('./git_metadata_tagger') -const { getEnvironmentVariable } = require('./config-helper') +const { getResolvedEnv } = require('./config-env-sources') const startedSpans = new WeakSet() const finishedSpans = new WeakSet() @@ -83,7 +83,7 @@ class SpanProcessor { } _erase (trace, active) { - if (getEnvironmentVariable('DD_TRACE_EXPERIMENTAL_STATE_TRACKING') === 'true') { + if (getResolvedEnv('DD_TRACE_EXPERIMENTAL_STATE_TRACKING') === 'true') { const started = new Set() const startedIds = new Set() const finished = new Set() diff --git a/packages/dd-trace/src/telemetry/send-data.js b/packages/dd-trace/src/telemetry/send-data.js index 43851f63583..3cad7402d89 100644 --- a/packages/dd-trace/src/telemetry/send-data.js +++ b/packages/dd-trace/src/telemetry/send-data.js @@ -3,7 +3,7 @@ const request = require('../exporters/common/request') const log = require('../log') const { isTrue } = require('../util') -const { getEnvironmentVariable } = require('../config-helper') +const { getResolvedEnv } = require('../config-env-sources') let agentTelemetry = true @@ -54,7 +54,7 @@ function sendData (config, application, host, reqType, payload = {}, cb = () => let url = config.url const isCiVisibilityAgentlessMode = isCiVisibility && - isTrue(getEnvironmentVariable('DD_CIVISIBILITY_AGENTLESS_ENABLED')) + isTrue(getResolvedEnv('DD_CIVISIBILITY_AGENTLESS_ENABLED')) if (isCiVisibilityAgentlessMode) { try { @@ -88,14 +88,14 @@ function sendData (config, application, host, reqType, payload = {}, cb = () => }) request(data, options, (error) => { - if (error && getEnvironmentVariable('DD_API_KEY') && config.site) { + if (error && getResolvedEnv('DD_API_KEY') && config.site) { if (agentTelemetry) { log.warn('Agent telemetry failed, started agentless telemetry') agentTelemetry = false } // figure out which data center to send to const backendUrl = getAgentlessTelemetryEndpoint(config.site) - const backendHeader = { ...options.headers, 'DD-API-KEY': getEnvironmentVariable('DD_API_KEY') } + const backendHeader = { ...options.headers, 'DD-API-KEY': getResolvedEnv('DD_API_KEY') } const backendOptions = { ...options, url: backendUrl, diff --git a/packages/dd-trace/test/config-env-sources.spec.js b/packages/dd-trace/test/config-env-sources.spec.js new file mode 100644 index 00000000000..012c8e1acd4 --- /dev/null +++ b/packages/dd-trace/test/config-env-sources.spec.js @@ -0,0 +1,444 @@ +'use strict' + +const { expect } = require('chai') +const sinon = require('sinon') +const { it, describe, beforeEach, afterEach } = require('tap').mocha +const proxyquire = require('proxyquire') + +require('./setup/core') + +describe('ConfigEnvSources', () => { + let ConfigEnvSources + let createConfigEnvSources + let getConfigEnvSources + let resetConfigEnvSources + let isInServerlessEnvironmentStub + let StableConfigStub + + beforeEach(() => { + // Reset stubs + isInServerlessEnvironmentStub = sinon.stub() + StableConfigStub = sinon.stub() + + // Load module with stubs + const mod = proxyquire('../src/config-env-sources', { + './serverless': { + isInServerlessEnvironment: isInServerlessEnvironmentStub + }, + './config_stable': StableConfigStub + }) + + ConfigEnvSources = mod.ConfigEnvSources + createConfigEnvSources = mod.createConfigEnvSources + getConfigEnvSources = mod.getConfigEnvSources + resetConfigEnvSources = mod.resetConfigEnvSources + + // Reset singleton + resetConfigEnvSources() + }) + + afterEach(() => { + sinon.restore() + resetConfigEnvSources() + }) + + describe('constructor', () => { + it('should load stable config when not in serverless environment', () => { + isInServerlessEnvironmentStub.returns(false) + + // Mock stable config with local and fleet entries + StableConfigStub.callsFake(function () { + this.localEntries = { + DD_SERVICE: 'local-service', + DD_ENV: 'local-env', + DD_VERSION: 'local-version' + } + this.fleetEntries = { + DD_SERVICE: 'fleet-service', + DD_ENV: 'fleet-env' + } + this.warnings = [] + }) + + const sources = new ConfigEnvSources() + + expect(StableConfigStub.calledOnce).to.be.true + expect(sources.localStableConfig).to.deep.equal({ + DD_SERVICE: 'local-service', + DD_ENV: 'local-env', + DD_VERSION: 'local-version' + }) + expect(sources.fleetStableConfig).to.deep.equal({ + DD_SERVICE: 'fleet-service', + DD_ENV: 'fleet-env' + }) + }) + + it('should not load stable config in serverless environment', () => { + isInServerlessEnvironmentStub.returns(true) + + const sources = new ConfigEnvSources() + + // StableConfig should not be called + expect(StableConfigStub.called).to.be.false + expect(sources.localStableConfig).to.deep.equal({}) + expect(sources.fleetStableConfig).to.deep.equal({}) + }) + + it('should handle empty or missing stable config entries', () => { + isInServerlessEnvironmentStub.returns(false) + + StableConfigStub.callsFake(function () { + this.localEntries = null + this.fleetEntries = undefined + this.warnings = [] + }) + + const sources = new ConfigEnvSources() + + expect(sources.localStableConfig).to.deep.equal({}) + expect(sources.fleetStableConfig).to.deep.equal({}) + }) + }) + + describe('createConfigEnvSources', () => { + it('should create a new ConfigEnvSources instance', () => { + isInServerlessEnvironmentStub.returns(true) + + const sources1 = createConfigEnvSources() + const sources2 = createConfigEnvSources() + + expect(sources1).to.be.instanceof(ConfigEnvSources) + expect(sources2).to.be.instanceof(ConfigEnvSources) + expect(sources1).to.not.equal(sources2) + }) + }) + + describe('getConfigEnvSources', () => { + it('should return a singleton instance', () => { + isInServerlessEnvironmentStub.returns(true) + + const sources1 = getConfigEnvSources() + const sources2 = getConfigEnvSources() + + expect(sources1).to.be.instanceof(ConfigEnvSources) + expect(sources1).to.equal(sources2) + }) + + it('should create instance only once', () => { + isInServerlessEnvironmentStub.returns(false) + + StableConfigStub.callsFake(function () { + this.localEntries = {} + this.fleetEntries = {} + this.warnings = [] + }) + + getConfigEnvSources() + getConfigEnvSources() + getConfigEnvSources() + + // StableConfig should only be instantiated once + expect(StableConfigStub.callCount).to.equal(1) + }) + }) + + describe('resetConfigEnvSources', () => { + it('should reset the singleton instance', () => { + isInServerlessEnvironmentStub.returns(true) + + const sources1 = getConfigEnvSources() + resetConfigEnvSources() + const sources2 = getConfigEnvSources() + + expect(sources1).to.not.equal(sources2) + }) + + it('should allow fresh instance creation with updated values', () => { + isInServerlessEnvironmentStub.returns(false) + + StableConfigStub.onCall(0).callsFake(function () { + this.localEntries = { + DD_SERVICE: 'service-1' + } + this.fleetEntries = {} + this.warnings = [] + }) + + StableConfigStub.onCall(1).callsFake(function () { + this.localEntries = { + DD_SERVICE: 'service-2' + } + this.fleetEntries = {} + this.warnings = [] + }) + + const sources1 = getConfigEnvSources() + expect(sources1.localStableConfig.DD_SERVICE).to.equal('service-1') + + resetConfigEnvSources() + + const sources2 = getConfigEnvSources() + expect(sources2.localStableConfig.DD_SERVICE).to.equal('service-2') + }) + }) +}) + +describe('getResolvedEnv', () => { + let getResolvedEnv + let resetConfigEnvSources + let isInServerlessEnvironmentStub + let originalEnv + + beforeEach(() => { + isInServerlessEnvironmentStub = sinon.stub().returns(true) + originalEnv = process.env + process.env = { ...originalEnv } + + const configEnvSourcesMod = proxyquire('../src/config-env-sources', { + './serverless': { + isInServerlessEnvironment: isInServerlessEnvironmentStub + } + }) + + resetConfigEnvSources = configEnvSourcesMod.resetConfigEnvSources + getResolvedEnv = configEnvSourcesMod.getResolvedEnv + + // Reset singleton + resetConfigEnvSources() + }) + + afterEach(() => { + sinon.restore() + resetConfigEnvSources() + process.env = originalEnv + }) + + it('should return value from ConfigEnvSources for supported configuration', () => { + process.env.DD_SERVICE = 'my-service' + process.env.DD_ENV = 'production' + + const value = getResolvedEnv('DD_SERVICE') + + expect(value).to.equal('my-service') + }) + + it('should fall back to alias if canonical name is not set', () => { + process.env.DD_TRACE_AGENT_HOSTNAME = 'alias-hostname' + + // DD_AGENT_HOST is the canonical name, DD_TRACE_AGENT_HOSTNAME is an alias + const value = getResolvedEnv('DD_AGENT_HOST') + + expect(value).to.equal('alias-hostname') + }) + + it('should return undefined if neither canonical nor alias is set', () => { + process.env.DD_SERVICE = 'my-service' + + const value = getResolvedEnv('DD_ENV') + + expect(value).to.be.undefined + }) + + it('should prefer canonical name over alias', () => { + process.env.DD_AGENT_HOST = 'canonical-hostname' + process.env.DD_TRACE_AGENT_HOSTNAME = 'alias-hostname' + + const value = getResolvedEnv('DD_AGENT_HOST') + + expect(value).to.equal('canonical-hostname') + }) + + it('should throw error for unsupported DD_ configuration', () => { + expect(() => { + getResolvedEnv('DD_UNSUPPORTED_CONFIG') + }).to.throw('Missing DD_UNSUPPORTED_CONFIG env/configuration in "supported-configurations.json" file.') + }) + + it('should throw error for unsupported OTEL_ configuration', () => { + expect(() => { + getResolvedEnv('OTEL_UNSUPPORTED_CONFIG') + }).to.throw('Missing OTEL_UNSUPPORTED_CONFIG env/configuration in "supported-configurations.json" file.') + }) + + it('should return value for non-DD/OTEL environment variables', () => { + process.env.NODE_ENV = 'production' + process.env.PATH = '/usr/bin' + + const value = getResolvedEnv('NODE_ENV') + + expect(value).to.equal('production') + }) + + it('should use singleton ConfigEnvSources instance', () => { + isInServerlessEnvironmentStub.returns(true) + process.env.DD_SERVICE = 'my-service' + + getResolvedEnv('DD_SERVICE') + getResolvedEnv('DD_ENV') + + // ConfigEnvSources should only be instantiated once (isInServerlessEnvironment called once) + expect(isInServerlessEnvironmentStub.callCount).to.equal(1) + }) + + it('should work with merged values from stable config and env vars', () => { + const StableConfigStub = sinon.stub() + StableConfigStub.callsFake(function () { + this.localEntries = { + DD_SERVICE: 'local-service' + } + this.fleetEntries = { + DD_SERVICE: 'fleet-service' + } + this.warnings = [] + }) + + const isInServerlessStub = sinon.stub().returns(false) + process.env.DD_ENV = 'production' + + // Re-setup with stable config stub + resetConfigEnvSources() + const configEnvSourcesMod = proxyquire('../src/config-env-sources', { + './serverless': { + isInServerlessEnvironment: isInServerlessStub + }, + './config_stable': StableConfigStub + }) + + const getResolvedEnvFn = configEnvSourcesMod.getResolvedEnv + + // Fleet should win for DD_SERVICE + expect(getResolvedEnvFn('DD_SERVICE')).to.equal('fleet-service') + // Env var should be used for DD_ENV + expect(getResolvedEnvFn('DD_ENV')).to.equal('production') + }) + + describe('priority scenarios', () => { + it('should prioritize fleet over env over local', () => { + const StableConfigStub = sinon.stub() + StableConfigStub.callsFake(function () { + this.localEntries = { + DD_TRACE_SAMPLE_RATE: '0.1', + DD_TRACE_ENABLED: 'false', + DD_SERVICE: 'local' + } + this.fleetEntries = { + DD_TRACE_SAMPLE_RATE: '0.9', + DD_SERVICE: 'fleet' + } + this.warnings = [] + }) + + const isInServerlessStub = sinon.stub().returns(false) + + process.env.DD_TRACE_SAMPLE_RATE = '0.5' + process.env.DD_TRACE_ENABLED = 'true' + + resetConfigEnvSources() + const configEnvSourcesMod = proxyquire('../src/config-env-sources', { + './serverless': { + isInServerlessEnvironment: isInServerlessStub + }, + './config_stable': StableConfigStub + }) + + const getResolvedEnvFn = configEnvSourcesMod.getResolvedEnv + + // Fleet wins + expect(getResolvedEnvFn('DD_TRACE_SAMPLE_RATE')).to.equal('0.9') + expect(getResolvedEnvFn('DD_SERVICE')).to.equal('fleet') + // Env wins (not in fleet) + expect(getResolvedEnvFn('DD_TRACE_ENABLED')).to.equal('true') + }) + + it('should not override defined values with undefined', () => { + const StableConfigStub = sinon.stub() + StableConfigStub.callsFake(function () { + this.localEntries = { + DD_SERVICE: 'local-service' + } + this.fleetEntries = { + DD_SERVICE: undefined + } + this.warnings = [] + }) + + const isInServerlessStub = sinon.stub().returns(false) + + // Env var is not set (undefined) + + resetConfigEnvSources() + const configEnvSourcesMod = proxyquire('../src/config-env-sources', { + './serverless': { + isInServerlessEnvironment: isInServerlessStub + }, + './config_stable': StableConfigStub + }) + + const getResolvedEnvFn = configEnvSourcesMod.getResolvedEnv + + // Local value should remain since higher priorities are undefined + expect(getResolvedEnvFn('DD_SERVICE')).to.equal('local-service') + }) + }) + + describe('compatibility with getEnvironmentVariable', () => { + it('should return env var values when no stable config exists (serverless)', () => { + // Set up env without stable config (serverless mode) + isInServerlessEnvironmentStub.returns(true) + process.env.DD_SERVICE = 'my-service' + process.env.DD_ENV = 'production' + process.env.DD_TRACE_AGENT_PORT = '8126' + + resetConfigEnvSources() + const configEnvSourcesMod = proxyquire('../src/config-env-sources', { + './serverless': { + isInServerlessEnvironment: isInServerlessEnvironmentStub + } + }) + + const getResolvedEnvFn = configEnvSourcesMod.getResolvedEnv + + // Should return the env var values directly (no stable config involved) + expect(getResolvedEnvFn('DD_SERVICE')).to.equal('my-service') + expect(getResolvedEnvFn('DD_ENV')).to.equal('production') + expect(getResolvedEnvFn('DD_TRACE_AGENT_PORT')).to.equal('8126') + }) + + it('should return undefined for unset values', () => { + isInServerlessEnvironmentStub.returns(true) + process.env.DD_SERVICE = 'my-service' + + resetConfigEnvSources() + const configEnvSourcesMod = proxyquire('../src/config-env-sources', { + './serverless': { + isInServerlessEnvironment: isInServerlessEnvironmentStub + } + }) + + const getResolvedEnvFn = configEnvSourcesMod.getResolvedEnv + + // Should return undefined for unset supported config + expect(getResolvedEnvFn('DD_ENV')).to.be.undefined + expect(getResolvedEnvFn('DD_VERSION')).to.be.undefined + }) + + it('should throw same error for unsupported configuration', () => { + isInServerlessEnvironmentStub.returns(true) + + resetConfigEnvSources() + const configEnvSourcesMod = proxyquire('../src/config-env-sources', { + './serverless': { + isInServerlessEnvironment: isInServerlessEnvironmentStub + } + }) + + const getResolvedEnvFn = configEnvSourcesMod.getResolvedEnv + + // Both should throw for unsupported DD_ vars + expect(() => getResolvedEnvFn('DD_UNSUPPORTED_VAR')).to.throw( + 'Missing DD_UNSUPPORTED_VAR env/configuration in "supported-configurations.json" file.' + ) + }) + }) +}) diff --git a/packages/dd-trace/test/config.spec.js b/packages/dd-trace/test/config.spec.js index 42dd9ff9250..effb4a10951 100644 --- a/packages/dd-trace/test/config.spec.js +++ b/packages/dd-trace/test/config.spec.js @@ -14,6 +14,7 @@ require('./setup/core') const { GRPC_CLIENT_ERROR_STATUSES, GRPC_SERVER_ERROR_STATUSES } = require('../src/constants') const { getEnvironmentVariable, getEnvironmentVariables } = require('../src/config-helper') +const { resetConfigEnvSources } = require('../src/config-env-sources') const { assertObjectContains } = require('../../../integration-tests/helpers') const { DD_MAJOR } = require('../../../version') @@ -2819,6 +2820,7 @@ describe('Config', () => { tempDir = fs.mkdtempSync(path.join(baseTempDir, 'config-test-')) process.env.DD_TEST_LOCAL_CONFIG_PATH = path.join(tempDir, 'local.yaml') process.env.DD_TEST_FLEET_CONFIG_PATH = path.join(tempDir, 'fleet.yaml') + resetConfigEnvSources() }) afterEach(() => { @@ -2872,6 +2874,8 @@ rules: configuration: DD_SERVICE: service_local_stable `) + resetConfigEnvSources() + const config2 = getConfig() expect(config2).to.have.property( 'service', @@ -2881,6 +2885,8 @@ rules: // 3. Env > Local stable > Default process.env.DD_SERVICE = 'service_env' + resetConfigEnvSources() + const config3 = getConfig() expect(config3).to.have.property( 'service', @@ -2901,6 +2907,7 @@ rules: configuration: DD_SERVICE: service_fleet_stable `) + resetConfigEnvSources() const config4 = getConfig() expect(config4).to.have.property( 'service', @@ -3040,6 +3047,7 @@ apm_configuration_default: DD_TRACE_CLOUD_REQUEST_PAYLOAD_TAGGING: "all" DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH: 5 `) + resetConfigEnvSources() let config = getConfig() expect(config).to.have.property('apiKey', 'local-api-key') expect(config).to.have.property('appKey', 'local-app-key') @@ -3054,6 +3062,7 @@ apm_configuration_default: process.env.DD_APP_KEY = 'env-app-key' process.env.DD_INSTRUMENTATION_INSTALL_ID = 'env-install-id' process.env.DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH = '7' + resetConfigEnvSources() config = getConfig() expect(config).to.have.property('apiKey', 'env-api-key') expect(config).to.have.property('appKey', 'env-app-key') @@ -3080,6 +3089,7 @@ rules: DD_TRACE_CLOUD_RESPONSE_PAYLOAD_TAGGING: "all" DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH: 15 `) + resetConfigEnvSources() config = getConfig() expect(config).to.have.property('apiKey', 'fleet-api-key') expect(config).to.have.property('appKey', 'fleet-app-key') diff --git a/packages/dd-trace/test/plugin_manager.spec.js b/packages/dd-trace/test/plugin_manager.spec.js index 027ad218707..bb8335e1ab9 100644 --- a/packages/dd-trace/test/plugin_manager.spec.js +++ b/packages/dd-trace/test/plugin_manager.spec.js @@ -81,6 +81,11 @@ describe('Plugin Manager', () => { getEnvironmentVariable (name) { return process.env[name] } + }, + './config-env-sources': { + getResolvedEnv (name) { + return process.env[name] + } } }) pm = new PluginManager(tracer)