From 3f1fadb92b4beea8030f38009056cfb464f2b253 Mon Sep 17 00:00:00 2001 From: Brian Marks Date: Thu, 27 Aug 2026 17:28:47 -0400 Subject: [PATCH 1/2] fix(config): prefer stable OTel deployment environment --- packages/dd-trace/src/config/parsers.js | 4 +- packages/dd-trace/test/config/index.spec.js | 69 +++++++++++++++++---- 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/packages/dd-trace/src/config/parsers.js b/packages/dd-trace/src/config/parsers.js index 9e29d3b773d..be36c47c138 100644 --- a/packages/dd-trace/src/config/parsers.js +++ b/packages/dd-trace/src/config/parsers.js @@ -90,8 +90,10 @@ const transformers = { }, parseOtelTags (object) { const tags = {} + const environment = object['deployment.environment.name'] ?? object['deployment.environment'] for (const [key, value] of Object.entries(object)) { - tags[RENAMED_OTEL_TAGS.get(key) ?? key] = value + const renamedKey = RENAMED_OTEL_TAGS.get(key) + tags[renamedKey ?? key] = renamedKey === 'env' ? environment : value } return tags }, diff --git a/packages/dd-trace/test/config/index.spec.js b/packages/dd-trace/test/config/index.spec.js index 9c1084427e5..f906fdfd11d 100644 --- a/packages/dd-trace/test/config/index.spec.js +++ b/packages/dd-trace/test/config/index.spec.js @@ -651,19 +651,64 @@ describe('Config', () => { }) }) - it('should correctly map OTEL_RESOURCE_ATTRIBUTES', () => { - process.env.OTEL_RESOURCE_ATTRIBUTES = - 'deployment.environment=test1,service.name=test2,service.version=5,foo=bar1,baz=qux1' - const config = getConfig() - - assertObjectContains(config, { - env: 'test1', - service: 'test2', - version: '5', - tags: { - foo: 'bar1', - baz: 'qux1', + describe('OTEL_RESOURCE_ATTRIBUTES mapping', () => { + for (const { name, attributes, expectedEnv } of [ + { + name: 'maps deployment.environment as a fallback', + attributes: 'deployment.environment=legacy', + expectedEnv: 'legacy', }, + { + name: 'maps deployment.environment.name', + attributes: 'deployment.environment.name=stable', + expectedEnv: 'stable', + }, + { + name: 'prefers deployment.environment.name when it precedes deployment.environment', + attributes: 'deployment.environment.name=stable,deployment.environment=legacy', + expectedEnv: 'stable', + }, + { + name: 'prefers deployment.environment.name when it follows deployment.environment', + attributes: 'deployment.environment=legacy,deployment.environment.name=stable', + expectedEnv: 'stable', + }, + ]) { + it(name, () => { + process.env.OTEL_RESOURCE_ATTRIBUTES = + `${attributes},service.name=test2,service.version=5,foo=bar1,baz=qux1` + + const config = getConfig() + + assertObjectContains(config, { + env: expectedEnv, + service: 'test2', + version: '5', + tags: { + foo: 'bar1', + baz: 'qux1', + }, + }) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment')) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment.name')) + }) + } + + it('keeps DD_ENV precedence over deployment environment resource attributes', () => { + process.env.DD_ENV = 'datadog' + process.env.OTEL_RESOURCE_ATTRIBUTES = + 'deployment.environment=legacy,deployment.environment.name=stable,foo=bar1' + + const config = getConfig() + + assertObjectContains(config, { + env: 'datadog', + tags: { + foo: 'bar1', + }, + }) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment')) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment.name')) }) }) From 1f96b1be9d674bf0513aa52f90dc956719de5dab Mon Sep 17 00:00:00 2001 From: Brian Marks Date: Tue, 1 Sep 2026 17:51:45 -0400 Subject: [PATCH 2/2] test(config): unroll OTel resource attribute cases --- packages/dd-trace/test/config/index.spec.js | 112 +++++++++++++------- 1 file changed, 74 insertions(+), 38 deletions(-) diff --git a/packages/dd-trace/test/config/index.spec.js b/packages/dd-trace/test/config/index.spec.js index 45438ec3e1f..b40f3f6d22f 100644 --- a/packages/dd-trace/test/config/index.spec.js +++ b/packages/dd-trace/test/config/index.spec.js @@ -666,47 +666,83 @@ describe('Config', () => { }) describe('OTEL_RESOURCE_ATTRIBUTES mapping', () => { - for (const { name, attributes, expectedEnv } of [ - { - name: 'maps deployment.environment as a fallback', - attributes: 'deployment.environment=legacy', - expectedEnv: 'legacy', - }, - { - name: 'maps deployment.environment.name', - attributes: 'deployment.environment.name=stable', - expectedEnv: 'stable', - }, - { - name: 'prefers deployment.environment.name when it precedes deployment.environment', - attributes: 'deployment.environment.name=stable,deployment.environment=legacy', - expectedEnv: 'stable', - }, - { - name: 'prefers deployment.environment.name when it follows deployment.environment', - attributes: 'deployment.environment=legacy,deployment.environment.name=stable', - expectedEnv: 'stable', - }, - ]) { - it(name, () => { - process.env.OTEL_RESOURCE_ATTRIBUTES = - `${attributes},service.name=test2,service.version=5,foo=bar1,baz=qux1` + it('maps deployment.environment as a fallback', () => { + process.env.OTEL_RESOURCE_ATTRIBUTES = + 'deployment.environment=legacy,service.name=test2,service.version=5,foo=bar1,baz=qux1' - const config = getConfig() + const config = getConfig() - assertObjectContains(config, { - env: expectedEnv, - service: 'test2', - version: '5', - tags: { - foo: 'bar1', - baz: 'qux1', - }, - }) - assert.ok(!Object.hasOwn(config.tags, 'deployment.environment')) - assert.ok(!Object.hasOwn(config.tags, 'deployment.environment.name')) + assertObjectContains(config, { + env: 'legacy', + service: 'test2', + version: '5', + tags: { + foo: 'bar1', + baz: 'qux1', + }, }) - } + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment')) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment.name')) + }) + + it('maps deployment.environment.name', () => { + process.env.OTEL_RESOURCE_ATTRIBUTES = + 'deployment.environment.name=stable,service.name=test2,service.version=5,foo=bar1,baz=qux1' + + const config = getConfig() + + assertObjectContains(config, { + env: 'stable', + service: 'test2', + version: '5', + tags: { + foo: 'bar1', + baz: 'qux1', + }, + }) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment')) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment.name')) + }) + + it('prefers deployment.environment.name when it precedes deployment.environment', () => { + process.env.OTEL_RESOURCE_ATTRIBUTES = + 'deployment.environment.name=stable,deployment.environment=legacy,' + + 'service.name=test2,service.version=5,foo=bar1,baz=qux1' + + const config = getConfig() + + assertObjectContains(config, { + env: 'stable', + service: 'test2', + version: '5', + tags: { + foo: 'bar1', + baz: 'qux1', + }, + }) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment')) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment.name')) + }) + + it('prefers deployment.environment.name when it follows deployment.environment', () => { + process.env.OTEL_RESOURCE_ATTRIBUTES = + 'deployment.environment=legacy,deployment.environment.name=stable,' + + 'service.name=test2,service.version=5,foo=bar1,baz=qux1' + + const config = getConfig() + + assertObjectContains(config, { + env: 'stable', + service: 'test2', + version: '5', + tags: { + foo: 'bar1', + baz: 'qux1', + }, + }) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment')) + assert.ok(!Object.hasOwn(config.tags, 'deployment.environment.name')) + }) it('keeps DD_ENV precedence over deployment environment resource attributes', () => { process.env.DD_ENV = 'datadog'