Skip to content

Commit 3c9fc50

Browse files
authored
[DI] Support custom logger in worker thread (#6128)
If the tracer is configured with a custom logger, it should be used in the Dynamic Instrumentation/Live Debugging worker thread. This changes how logs are handled in the worker thread: Instead of logging them directly to STDOUT/STDERR, they are sent back to the main thread for processing in the main logger.
1 parent 669090c commit 3c9fc50

File tree

16 files changed

+178
-20
lines changed

16 files changed

+178
-20
lines changed

integration-tests/debugger/custom-logger.spec.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,26 @@ const assert = require('node:assert')
44
const { setup } = require('./utils')
55

66
describe('Dynamic Instrumentation', function () {
7-
const t = setup()
7+
const stdio = []
8+
const stderr = []
9+
const t = setup({
10+
env: {
11+
DD_TRACE_DEBUG: 'true'
12+
},
13+
silent: true,
14+
stdioHandler (data) {
15+
stdio.push(data.toString())
16+
},
17+
stderrHandler (data) {
18+
stderr.push(data.toString())
19+
},
20+
})
821

9-
it('should not abort if a custom logger is used', function (done) {
10-
t.agent.on('debugger-input', ({ payload: [payload] }) => {
11-
assert.strictEqual(payload.message, 'Hello World!')
22+
it('should log to the custom logger from the worker thread', function (done) {
23+
t.agent.on('debugger-input', () => {
24+
assert(stdio.some((line) => line.startsWith('[CUSTOM LOGGER][DEBUG]: [debugger]')))
25+
assert(stdio.some((line) => line.startsWith('[CUSTOM LOGGER][DEBUG]: [debugger:devtools_client]')))
26+
assert.strictEqual(stderr.length, 0)
1227
done()
1328
})
1429

integration-tests/debugger/target-app/custom-logger.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
require('dd-trace').init({
44
logger: {
5-
error: err => console.error(err), // eslint-disable-line no-console
6-
warn: message => console.warn(message), // eslint-disable-line no-console
7-
info: message => console.info(message), // eslint-disable-line no-console
8-
debug: message => console.debug(message) // eslint-disable-line no-console
5+
error: (...args) => console.log('[CUSTOM LOGGER][ERROR]:', ...args), // eslint-disable-line no-console
6+
warn: (...args) => console.log('[CUSTOM LOGGER][WARN]:', ...args), // eslint-disable-line no-console
7+
info: (...args) => console.log('[CUSTOM LOGGER][INFO]:', ...args), // eslint-disable-line no-console
8+
debug: (...args) => console.log('[CUSTOM LOGGER][DEBUG]:', ...args) // eslint-disable-line no-console
99
}
1010
})
1111

integration-tests/debugger/utils.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module.exports = {
1717
setup
1818
}
1919

20-
function setup ({ env, testApp, testAppSource, dependencies } = {}) {
20+
function setup ({ env, testApp, testAppSource, dependencies, silent, stdioHandler, stderrHandler } = {}) {
2121
let sandbox, cwd
2222

2323
const breakpoints = getBreakpointInfo({
@@ -101,8 +101,9 @@ function setup ({ env, testApp, testAppSource, dependencies } = {}) {
101101
DD_TRACE_DEBUG: process.env.DD_TRACE_DEBUG, // inherit to make debugging the sandbox easier
102102
DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS: pollInterval,
103103
...env
104-
}
105-
})
104+
},
105+
silent: silent ?? false
106+
}, stdioHandler, stderrHandler)
106107
t.axios = Axios.create({ baseURL: t.proc.url })
107108
})
108109

packages/dd-trace/src/debugger/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
module.exports = function getDebuggerConfig (config) {
44
return {
55
commitSHA: config.commitSHA,
6+
debug: config.debug,
67
dynamicInstrumentation: config.dynamicInstrumentation,
78
hostname: config.hostname,
9+
logLevel: config.logLevel,
810
port: config.port,
911
repositoryUrl: config.repositoryUrl,
1012
runtimeId: config.tags['runtime-id'],

packages/dd-trace/src/debugger/devtools_client/breakpoints.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const {
1212
breakpointToProbes,
1313
probeToLocation
1414
} = require('./state')
15-
const log = require('../../log')
15+
const log = require('./log')
1616

1717
let sessionStarted = false
1818
const probes = new Map()

packages/dd-trace/src/debugger/devtools_client/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const { workerData: { config: parentConfig, parentThreadId, configPort } } = require('node:worker_threads')
44
const { format } = require('node:url')
5-
const log = require('../../log')
5+
const log = require('./log')
66

77
const config = module.exports = {
88
...parentConfig,

packages/dd-trace/src/debugger/devtools_client/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const { getStackFromCallFrames } = require('./state')
99
const { ackEmitting } = require('./status')
1010
const { parentThreadId } = require('./config')
1111
const { MAX_SNAPSHOTS_PER_SECOND_GLOBALLY } = require('./defaults')
12-
const log = require('../../log')
12+
const log = require('./log')
1313
const { version } = require('../../../../../package.json')
1414
const { NODE_MAJOR } = require('../../../../../version')
1515

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict'
2+
3+
const { workerData } = require('node:worker_threads')
4+
5+
// For testing purposes, we allow `workerData` to be undefined and fallback to a default config
6+
const { config: { debug, logLevel }, logPort } = workerData ?? { config: { debug: false } }
7+
8+
const LEVELS = ['error', 'warn', 'info', 'debug']
9+
const on = (level, ...args) => {
10+
if (typeof args[0] === 'function') {
11+
args = [args[0]()]
12+
}
13+
logPort.postMessage({ level, args })
14+
}
15+
const off = () => {}
16+
17+
for (const level of LEVELS) {
18+
module.exports[level] = debug && LEVELS.indexOf(logLevel) >= LEVELS.indexOf(level) ? on.bind(null, level) : off
19+
}

packages/dd-trace/src/debugger/devtools_client/remote_config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const { workerData: { probePort } } = require('node:worker_threads')
44
const { addBreakpoint, removeBreakpoint, modifyBreakpoint } = require('./breakpoints')
55
const { ackReceived, ackInstalled, ackError } = require('./status')
6-
const log = require('../../log')
6+
const log = require('./log')
77

88
// Example log line probe (simplified):
99
// {

packages/dd-trace/src/debugger/devtools_client/send.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const config = require('./config')
77
const JSONBuffer = require('./json-buffer')
88
const request = require('../../exporters/common/request')
99
const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags')
10-
const log = require('../../log')
10+
const log = require('./log')
1111
const { version } = require('../../../../../package.json')
1212
const { getEnvironmentVariable } = require('../../config-helper')
1313

0 commit comments

Comments
 (0)