Skip to content

Commit 974cc39

Browse files
Update DD_TAGS Parsing to Meet Spec (#5213)
* Updates DD_TAGS Parsing to meet Spec --------- Co-authored-by: Ruben Bridgewater <ruben.bridgewater@datadoghq.com>
1 parent e9f4f11 commit 974cc39

File tree

12 files changed

+127
-54
lines changed

12 files changed

+127
-54
lines changed

packages/datadog-plugin-express/test/index.spec.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,9 +1350,7 @@ describe('Plugin', () => {
13501350
expect(spans[0].meta).to.have.property('http.status_code', '404')
13511351
expect(spans[0].meta).to.have.property('component', 'express')
13521352
expect(spans[0].meta).to.not.have.property('http.route')
1353-
1354-
done()
1355-
})
1353+
}).then(done).catch(done)
13561354

13571355
axios
13581356
.get(`http://localhost:${port}/does-not-exist`, {

packages/datadog-plugin-graphql/src/parse.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ class GraphQLParsePlugin extends TracingPlugin {
1010
this.startSpan('graphql.parse', {
1111
service: this.config.service,
1212
type: 'graphql',
13-
meta: {
14-
'graphql.source': ''
15-
}
13+
meta: {}
1614
})
1715
}
1816

packages/dd-trace/src/config.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -773,8 +773,8 @@ class Config {
773773
const env = setHiddenProperty(this, '_env', {})
774774
setHiddenProperty(this, '_envUnprocessed', {})
775775

776-
tagger.add(tags, OTEL_RESOURCE_ATTRIBUTES, true)
777-
tagger.add(tags, DD_TAGS)
776+
tagger.add(tags, parseSpaceSeparatedTags(handleOtel(OTEL_RESOURCE_ATTRIBUTES)))
777+
tagger.add(tags, parseSpaceSeparatedTags(DD_TAGS))
778778
tagger.add(tags, DD_TRACE_TAGS)
779779
tagger.add(tags, DD_TRACE_GLOBAL_TAGS)
780780

@@ -1473,6 +1473,21 @@ class Config {
14731473
}
14741474
}
14751475

1476+
function handleOtel (tagString) {
1477+
return tagString
1478+
?.replace(/(^|,)deployment\.environment=/, '$1env:')
1479+
.replace(/(^|,)service\.name=/, '$1service:')
1480+
.replace(/(^|,)service\.version=/, '$1version:')
1481+
.replace(/=/g, ':')
1482+
}
1483+
1484+
function parseSpaceSeparatedTags (tagString) {
1485+
if (tagString && !tagString.includes(',')) {
1486+
tagString = tagString.replace(/\s+/g, ',')
1487+
}
1488+
return tagString
1489+
}
1490+
14761491
function maybeInt (number) {
14771492
const parsed = parseInt(number)
14781493
return isNaN(parsed) ? undefined : parsed

packages/dd-trace/src/format.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ function extractError (trace, error) {
212212
function addTag (meta, metrics, key, value, nested) {
213213
switch (typeof value) {
214214
case 'string':
215-
if (!value) break
216215
meta[key] = value
217216
break
218217
case 'number':

packages/dd-trace/src/plugins/util/git.js

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -328,22 +328,34 @@ function getGitMetadata (ciMetadata) {
328328
committerDate
329329
] = sanitizedExec('git', ['show', '-s', '--format=%an,%ae,%aI,%cn,%ce,%cI']).split(',')
330330

331-
return {
332-
[GIT_REPOSITORY_URL]:
333-
filterSensitiveInfoFromRepository(repositoryUrl || sanitizedExec('git', ['ls-remote', '--get-url'])),
331+
const tags = {
334332
[GIT_COMMIT_MESSAGE]:
335333
commitMessage || sanitizedExec('git', ['show', '-s', '--format=%s']),
336-
[GIT_COMMIT_AUTHOR_DATE]: authorDate,
337-
[GIT_COMMIT_AUTHOR_NAME]: ciAuthorName || authorName,
338-
[GIT_COMMIT_AUTHOR_EMAIL]: ciAuthorEmail || authorEmail,
339-
[GIT_COMMIT_COMMITTER_DATE]: committerDate,
340-
[GIT_COMMIT_COMMITTER_NAME]: committerName,
341-
[GIT_COMMIT_COMMITTER_EMAIL]: committerEmail,
342334
[GIT_BRANCH]: branch || sanitizedExec('git', ['rev-parse', '--abbrev-ref', 'HEAD']),
343335
[GIT_COMMIT_SHA]: commitSHA || sanitizedExec('git', ['rev-parse', 'HEAD']),
344-
[GIT_TAG]: tag,
345336
[CI_WORKSPACE_PATH]: ciWorkspacePath || sanitizedExec('git', ['rev-parse', '--show-toplevel'])
346337
}
338+
339+
const entries = [
340+
GIT_REPOSITORY_URL,
341+
filterSensitiveInfoFromRepository(repositoryUrl || sanitizedExec('git', ['ls-remote', '--get-url'])),
342+
GIT_COMMIT_AUTHOR_DATE, authorDate,
343+
GIT_COMMIT_AUTHOR_NAME, ciAuthorName || authorName,
344+
GIT_COMMIT_AUTHOR_EMAIL, ciAuthorEmail || authorEmail,
345+
GIT_COMMIT_COMMITTER_DATE, committerDate,
346+
GIT_COMMIT_COMMITTER_NAME, committerName,
347+
GIT_COMMIT_COMMITTER_EMAIL, committerEmail,
348+
GIT_TAG, tag
349+
]
350+
351+
for (let i = 0; i < entries.length; i += 2) {
352+
const value = entries[i + 1]
353+
if (value) {
354+
tags[entries[i]] = value
355+
}
356+
}
357+
358+
return tags
347359
}
348360

349361
module.exports = {

packages/dd-trace/src/plugins/util/web.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,9 @@ function addRequestTags (context, spanType) {
475475
function addResponseTags (context) {
476476
const { req, res, paths, span, inferredProxySpan } = context
477477

478-
if (paths.length > 0) {
479-
span.setTag(HTTP_ROUTE, paths.join(''))
478+
const route = paths.join('')
479+
if (route) {
480+
span.setTag(HTTP_ROUTE, route)
480481
}
481482

482483
span.addTags({

packages/dd-trace/src/tagger.js

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,7 @@ const ERROR_MESSAGE = constants.ERROR_MESSAGE
66
const ERROR_STACK = constants.ERROR_STACK
77
const ERROR_TYPE = constants.ERROR_TYPE
88

9-
const otelTagMap = {
10-
'deployment.environment': 'env',
11-
'service.name': 'service',
12-
'service.version': 'version'
13-
}
14-
15-
function add (carrier, keyValuePairs, parseOtelTags = false) {
9+
function add (carrier, keyValuePairs) {
1610
if (!carrier || !keyValuePairs) return
1711

1812
if (Array.isArray(keyValuePairs)) {
@@ -22,14 +16,13 @@ function add (carrier, keyValuePairs, parseOtelTags = false) {
2216
if (typeof keyValuePairs === 'string') {
2317
const segments = keyValuePairs.split(',')
2418
for (const segment of segments) {
25-
const separatorIndex = parseOtelTags ? segment.indexOf('=') : segment.indexOf(':')
26-
if (separatorIndex === -1) continue
27-
28-
let key = segment.slice(0, separatorIndex)
29-
const value = segment.slice(separatorIndex + 1)
19+
const separatorIndex = segment.indexOf(':')
3020

31-
if (parseOtelTags && key in otelTagMap) {
32-
key = otelTagMap[key]
21+
let value = ''
22+
let key = segment
23+
if (separatorIndex !== -1) {
24+
key = segment.slice(0, separatorIndex)
25+
value = segment.slice(separatorIndex + 1)
3326
}
3427

3528
carrier[key.trim()] = value.trim()

packages/dd-trace/test/appsec/iast/code_injection.integration.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe('IAST - code_injection - integration', () => {
1010
let axios, sandbox, cwd, appPort, agent, proc
1111

1212
before(async function () {
13-
this.timeout(process.platform === 'win32' ? 90000 : 30000)
13+
this.timeout(process.platform === 'win32' ? 100000 : 30000)
1414

1515
sandbox = await createSandbox(
1616
['express'],
@@ -27,7 +27,7 @@ describe('IAST - code_injection - integration', () => {
2727

2828
after(async function () {
2929
this.timeout(60000)
30-
await sandbox.remove()
30+
await sandbox?.remove()
3131
})
3232

3333
beforeEach(async () => {

packages/dd-trace/test/config.spec.js

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,13 +730,57 @@ describe('Config', () => {
730730
it('should ignore empty strings', () => {
731731
process.env.DD_TAGS = 'service:,env:,version:'
732732

733-
const config = new Config()
733+
let config = new Config()
734+
735+
expect(config).to.have.property('service', 'node')
736+
expect(config).to.have.property('env', undefined)
737+
expect(config).to.have.property('version', '')
738+
739+
process.env.DD_TAGS = 'service: env: version:'
740+
741+
config = new Config()
734742

735743
expect(config).to.have.property('service', 'node')
736744
expect(config).to.have.property('env', undefined)
737745
expect(config).to.have.property('version', '')
738746
})
739747

748+
it('should support space separated tags when experimental mode enabled', () => {
749+
process.env.DD_TAGS = 'key1:value1 key2:value2'
750+
751+
let config = new Config()
752+
753+
expect(config.tags).to.include({ key1: 'value1', key2: 'value2' })
754+
755+
process.env.DD_TAGS = 'env:test aKey:aVal bKey:bVal cKey:'
756+
757+
config = new Config()
758+
759+
expect(config.tags).to.have.property('env', 'test')
760+
expect(config.tags).to.have.property('aKey', 'aVal')
761+
expect(config.tags).to.have.property('bKey', 'bVal')
762+
expect(config.tags).to.have.property('cKey', '')
763+
764+
process.env.DD_TAGS = 'env:test,aKey:aVal bKey:bVal cKey:'
765+
766+
config = new Config()
767+
expect(config.tags).to.have.property('env', 'test')
768+
expect(config.tags).to.have.property('aKey', 'aVal bKey:bVal cKey:')
769+
770+
process.env.DD_TAGS = 'a:b:c:d'
771+
772+
config = new Config()
773+
774+
expect(config.tags).to.have.property('a', 'b:c:d')
775+
776+
process.env.DD_TAGS = 'a,1'
777+
778+
config = new Config()
779+
780+
expect(config.tags).to.have.property('a', '')
781+
expect(config.tags).to.have.property('1', '')
782+
})
783+
740784
it('should read case-insensitive booleans from environment variables', () => {
741785
process.env.DD_TRACING_ENABLED = 'False'
742786
process.env.DD_TRACE_PROPAGATION_EXTRACT_FIRST = 'TRUE'

packages/dd-trace/test/format.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,23 @@ describe('format', () => {
299299
})
300300
})
301301

302+
it('should extract empty tags', () => {
303+
spanContext._trace.tags = {
304+
foo: '',
305+
count: 1
306+
}
307+
308+
trace = format(span)
309+
310+
expect(trace.meta).to.include({
311+
foo: ''
312+
})
313+
314+
expect(trace.metrics).to.include({
315+
count: 1
316+
})
317+
})
318+
302319
it('should discard user-defined tags with name HOSTNAME_KEY by default', () => {
303320
spanContext._tags[HOSTNAME_KEY] = 'some_hostname'
304321

0 commit comments

Comments
 (0)