Skip to content

Commit 37b8ea4

Browse files
tlhunterclaude
andcommitted
feat(process-discovery): include process_tags and container_id, disable crashtracker ARM64 musl (#7816)
--------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5509e6d commit 37b8ea4

File tree

6 files changed

+146
-7
lines changed

6 files changed

+146
-7
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
"import-in-the-middle": "^3.0.0"
139139
},
140140
"optionalDependencies": {
141-
"@datadog/libdatadog": "0.8.1",
141+
"@datadog/libdatadog": "0.9.2",
142142
"@datadog/native-appsec": "11.0.1",
143143
"@datadog/native-iast-taint-tracking": "4.1.0",
144144
"@datadog/native-metrics": "3.1.1",

packages/dd-trace/src/crashtracking/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
'use strict'
22

3+
const { existsSync } = require('node:fs')
34
const { isMainThread } = require('worker_threads')
45
const log = require('../log')
56

6-
if (isMainThread) {
7+
// libdatadog v29 crashtracker segfaults during init on ARM64 musl (Alpine).
8+
// The segfault bypasses JS try/catch so we must avoid loading it entirely.
9+
// See: https://github.com/DataDog/libdatadog-nodejs/issues/114
10+
const isArm64Musl = process.arch === 'arm64' && existsSync('/etc/alpine-release')
11+
12+
if (isMainThread && !isArm64Musl) {
713
try {
814
module.exports = require('./crashtracker')
915
} catch (e) {

packages/dd-trace/src/exporters/common/docker.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ if (inodePath) {
3535
const entityId = containerId ? `ci-${containerId}` : inode && `in-${inode}`
3636

3737
module.exports = {
38+
containerId,
3839
entityId,
3940

4041
inject (carrier) {

packages/dd-trace/src/tracer_metadata.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,22 @@ function storeConfig (config) {
1111
return
1212
}
1313

14+
const { containerId } = require('./exporters/common/docker')
15+
const processTags = require('./process-tags')
16+
17+
const processTagsSerialized = config.propagateProcessTags?.enabled
18+
? (processTags.serialized || null)
19+
: null
20+
1421
const metadata = new processDiscovery.TracerMetadata(
1522
config.tags['runtime-id'],
1623
tracerVersion,
1724
config.hostname,
1825
config.service || null,
1926
config.env || null,
20-
config.version || null
27+
config.version || null,
28+
processTagsSerialized,
29+
containerId || null
2130
)
2231

2332
return processDiscovery.storeMetadata(metadata)
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
'use strict'
2+
3+
const assert = require('node:assert/strict')
4+
const { describe, it, beforeEach, afterEach } = require('mocha')
5+
const proxyquire = require('proxyquire')
6+
const sinon = require('sinon')
7+
8+
describe('tracer_metadata', () => {
9+
let storeConfig
10+
let storeMetadataStub
11+
let TracerMetadataStub
12+
let processDiscoveryStub
13+
let libdatadogStub
14+
let dockerStub
15+
let processTagsStub
16+
17+
const baseConfig = {
18+
tags: { 'runtime-id': 'test-runtime-id' },
19+
hostname: 'test-host',
20+
service: 'test-service',
21+
env: 'test-env',
22+
version: '1.0.0',
23+
propagateProcessTags: { enabled: false },
24+
}
25+
26+
beforeEach(() => {
27+
storeMetadataStub = sinon.stub().returns({ handle: 'mock-handle' })
28+
TracerMetadataStub = sinon.stub()
29+
30+
processDiscoveryStub = {
31+
TracerMetadata: TracerMetadataStub,
32+
storeMetadata: storeMetadataStub,
33+
}
34+
35+
libdatadogStub = {
36+
maybeLoad: sinon.stub().withArgs('process-discovery').returns(processDiscoveryStub),
37+
}
38+
39+
dockerStub = { containerId: undefined }
40+
processTagsStub = { serialized: 'tag1:val1,tag2:val2' }
41+
42+
storeConfig = proxyquire('../src/tracer_metadata', {
43+
'@datadog/libdatadog': libdatadogStub,
44+
'./exporters/common/docker': dockerStub,
45+
'./process-tags': processTagsStub,
46+
})
47+
})
48+
49+
afterEach(() => {
50+
sinon.restore()
51+
})
52+
53+
it('calls storeMetadata with correct base fields', () => {
54+
storeConfig(baseConfig)
55+
56+
sinon.assert.calledOnce(TracerMetadataStub)
57+
const args = TracerMetadataStub.firstCall.args
58+
assert.strictEqual(args[0], 'test-runtime-id')
59+
assert.strictEqual(args[2], 'test-host')
60+
assert.strictEqual(args[3], 'test-service')
61+
assert.strictEqual(args[4], 'test-env')
62+
assert.strictEqual(args[5], '1.0.0')
63+
64+
sinon.assert.calledOnce(storeMetadataStub)
65+
})
66+
67+
it('passes null for process_tags when propagateProcessTags is disabled', () => {
68+
storeConfig({ ...baseConfig, propagateProcessTags: { enabled: false } })
69+
70+
const args = TracerMetadataStub.firstCall.args
71+
assert.strictEqual(args[6], null)
72+
})
73+
74+
it('passes serialized process tags when propagateProcessTags is enabled', () => {
75+
storeConfig({ ...baseConfig, propagateProcessTags: { enabled: true } })
76+
77+
const args = TracerMetadataStub.firstCall.args
78+
assert.strictEqual(args[6], 'tag1:val1,tag2:val2')
79+
})
80+
81+
it('passes container_id when available', () => {
82+
dockerStub.containerId = 'abc123container'
83+
84+
storeConfig(baseConfig)
85+
86+
const args = TracerMetadataStub.firstCall.args
87+
assert.strictEqual(args[7], 'abc123container')
88+
})
89+
90+
it('passes null for container_id when not in a container', () => {
91+
dockerStub.containerId = undefined
92+
93+
storeConfig(baseConfig)
94+
95+
const args = TracerMetadataStub.firstCall.args
96+
assert.strictEqual(args[7], null)
97+
})
98+
99+
it('passes null for service when config.service is falsy', () => {
100+
storeConfig({ ...baseConfig, service: undefined })
101+
102+
const args = TracerMetadataStub.firstCall.args
103+
assert.strictEqual(args[3], null)
104+
})
105+
106+
it('returns undefined and does not throw when process-discovery is unavailable', () => {
107+
libdatadogStub.maybeLoad.returns(undefined)
108+
109+
const result = storeConfig(baseConfig)
110+
assert.strictEqual(result, undefined)
111+
})
112+
113+
it('returns undefined and does not throw when libdatadog throws', () => {
114+
const storeConfigWithThrow = proxyquire('../src/tracer_metadata', {
115+
'@datadog/libdatadog': { maybeLoad: () => { throw new Error('load error') } },
116+
'./exporters/common/docker': dockerStub,
117+
'./process-tags': processTagsStub,
118+
})
119+
120+
const result = storeConfigWithThrow(baseConfig)
121+
assert.strictEqual(result, undefined)
122+
})
123+
})

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,10 @@
197197
dependencies:
198198
spark-md5 "^3.0.2"
199199

200-
"@datadog/libdatadog@0.8.1":
201-
version "0.8.1"
202-
resolved "https://registry.yarnpkg.com/@datadog/libdatadog/-/libdatadog-0.8.1.tgz#370c7aaf03102399740dcdee52c118da41847c1f"
203-
integrity sha512-WeWPw24cVRmEWfRRw3+h4k7f8mf9vbWEq6MYg1eOd+FycG7q4LaV8/uKROWoKFoD6ScoNvZXxOjKHW3AdYgM+A==
200+
"@datadog/libdatadog@0.9.2":
201+
version "0.9.2"
202+
resolved "https://registry.yarnpkg.com/@datadog/libdatadog/-/libdatadog-0.9.2.tgz#d7a0193ab656bd9cc40649f300ef6c54d9bea52d"
203+
integrity sha512-grOerTYuU3wHuFIOBGg3jB144A3KEthEdVEL3meeiXYo7E7fBXXGRgAOwVE42VXFXfl0r8kDKCL7KupBc511tg==
204204

205205
"@datadog/native-appsec@11.0.1":
206206
version "11.0.1"

0 commit comments

Comments
 (0)