Skip to content

Commit b7fbc2d

Browse files
bm1549claude
andauthored
fix(startup-log): emit config early at init, integrations on first ag… (#7643)
* fix(startup-log): emit config early at init, integrations on first agent payload Split startupLog into three independent functions so config is logged immediately at init (via proxy.js) while integrations are logged later on first agent payload (via writer.js). This gives users config info faster without losing the integrations_loaded field that was regressed in #7470. Also fixes broken agent error logging introduced in #7212 where `startupLog({ agentError: err })` didn't match the expected `{ status, message }` shape. Co-Authored-By: Claude Opus 4.6 <[email protected]> * ci: re-run CI --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
1 parent 94c9de4 commit b7fbc2d

File tree

4 files changed

+222
-73
lines changed

4 files changed

+222
-73
lines changed

packages/dd-trace/src/exporters/agent/writer.js

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

3+
const { inspect } = require('node:util')
34
const request = require('../common/request')
4-
const { startupLog } = require('../../startup-log')
5+
const { logIntegrations, logAgentError } = require('../../startup-log')
56
const runtimeMetrics = require('../../runtime_metrics')
67
const log = require('../../log')
78
const tracerVersion = require('../../../../../package.json').version
@@ -28,7 +29,7 @@ class AgentWriter extends BaseWriter {
2829
runtimeMetrics.increment(`${METRIC_PREFIX}.requests`, true)
2930

3031
const { _headers, _lookup, _protocolVersion, _url } = this
31-
makeRequest(_protocolVersion, data, count, _url, _headers, _lookup, true, (err, res, status, headers) => {
32+
makeRequest(_protocolVersion, data, count, _url, _headers, _lookup, (err, res, status, headers) => {
3233
if (status) {
3334
runtimeMetrics.increment(`${METRIC_PREFIX}.responses`, true)
3435
runtimeMetrics.increment(`${METRIC_PREFIX}.responses.by.status`, `status:${status}`, true)
@@ -78,7 +79,7 @@ function getEncoder (protocolVersion) {
7879
: require('../../encode/0.4').AgentEncoder
7980
}
8081

81-
function makeRequest (version, data, count, url, headers, lookup, needsStartupLog, cb) {
82+
function makeRequest (version, data, count, url, headers, lookup, cb) {
8283
const options = {
8384
path: `/v${version}/traces`,
8485
method: 'PUT',
@@ -98,11 +99,9 @@ function makeRequest (version, data, count, url, headers, lookup, needsStartupLo
9899
log.debug('Request to the agent: %j', options)
99100

100101
request(data, options, (err, res, status, headers) => {
101-
if (needsStartupLog) {
102-
// Note that logging will only happen once, regardless of how many times this is called.
103-
startupLog({
104-
agentError: status !== 404 && status !== 200 ? err : undefined,
105-
})
102+
logIntegrations()
103+
if (status !== 404 && status !== 200 && err) {
104+
logAgentError({ status, message: err.message ?? inspect(err) })
106105
}
107106
cb(err, res, status, headers)
108107
})

packages/dd-trace/src/proxy.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const DatadogTracer = require('./tracer')
66
const getConfig = require('./config')
77
const runtimeMetrics = require('./runtime_metrics')
88
const log = require('./log')
9-
const { setStartupLogPluginManager } = require('./startup-log')
9+
const { setStartupLogPluginManager, startupLog } = require('./startup-log')
1010
const DynamicInstrumentation = require('./debugger')
1111
const telemetry = require('./telemetry')
1212
const nomenclature = require('./service-naming')
@@ -292,6 +292,7 @@ class Tracer extends NoopProxy {
292292
this._pluginManager.configure(config)
293293
DynamicInstrumentation.configure(config)
294294
setStartupLogPluginManager(this._pluginManager)
295+
startupLog()
295296
}
296297
}
297298

packages/dd-trace/src/startup-log.js

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,66 @@ let config
1111
let pluginManager
1212
/** @type {import('./sampling_rule')[]} */
1313
let samplingRules = []
14-
let alreadyRan = false
14+
let configAlreadyRan = false
15+
let integrationsAlreadyRan = false
16+
let agentErrorAlreadyRan = false
1517

1618
/**
17-
* @param {{ status: number, message: string } } [agentError]
19+
* Logs DATADOG TRACER CONFIGURATION immediately at init time.
20+
* Excludes integrations_loaded since plugins haven't loaded yet.
1821
*/
19-
function startupLog (agentError) {
20-
if (alreadyRan || !config || !config.startupLogs || !pluginManager) {
22+
function startupLog () {
23+
if (configAlreadyRan || !config || !config.startupLogs) {
2124
return
2225
}
2326

24-
alreadyRan = true
27+
configAlreadyRan = true
2528

26-
const out = tracerInfo()
29+
const out = configInfo()
2730

28-
if (agentError) {
29-
out.agent_error = agentError.message
31+
warn('DATADOG TRACER CONFIGURATION - ' + out)
32+
}
33+
34+
/**
35+
* Logs loaded integrations. Called from writer.js on first agent payload,
36+
* by which time the app has loaded its dependencies.
37+
*/
38+
function logIntegrations () {
39+
if (integrationsAlreadyRan || !config || !config.startupLogs || !pluginManager) {
40+
return
3041
}
3142

32-
warn('DATADOG TRACER CONFIGURATION - ' + out)
33-
if (agentError) {
34-
warn('DATADOG TRACER DIAGNOSTIC - Agent Error: ' + agentError.message)
35-
errors.agentError = {
36-
code: agentError.status,
37-
message: `Agent Error: ${agentError.message}`,
38-
}
43+
integrationsAlreadyRan = true
44+
45+
warn('DATADOG TRACER INTEGRATIONS LOADED - ' + JSON.stringify(Object.keys(pluginManager._pluginsByName)))
46+
}
47+
48+
/**
49+
* Logs agent error diagnostic.
50+
* @param {{ status: number, message: string }} agentError
51+
*/
52+
function logAgentError (agentError) {
53+
if (agentErrorAlreadyRan || !config || !config.startupLogs) {
54+
return
55+
}
56+
57+
agentErrorAlreadyRan = true
58+
59+
warn('DATADOG TRACER DIAGNOSTIC - Agent Error: ' + agentError.message)
60+
errors.agentError = {
61+
code: agentError.status,
62+
message: `Agent Error: ${agentError.message}`,
3963
}
4064
}
4165

4266
/**
67+
* Returns config info without integrations (used by startupLog).
4368
* @returns {Record<string, unknown>}
4469
*/
45-
function tracerInfo () {
70+
function configInfo () {
4671
const url = getAgentUrl(config)
4772

48-
const out = {
73+
return {
4974
[inspect.custom] () {
5075
return String(this)
5176
},
@@ -73,11 +98,18 @@ function tracerInfo () {
7398
log_injection_enabled: !!config.logInjection,
7499
runtime_metrics_enabled: !!config.runtimeMetrics,
75100
profiling_enabled: config.profiling?.enabled === 'true' || config.profiling?.enabled === 'auto',
76-
integrations_loaded: Object.keys(pluginManager._pluginsByName),
77101
appsec_enabled: config.appsec.enabled,
78102
data_streams_enabled: !!config.dsmEnabled,
79103
}
104+
}
80105

106+
/**
107+
* Returns full tracer info including integrations (used by flare module).
108+
* @returns {Record<string, unknown>}
109+
*/
110+
function tracerInfo () {
111+
const out = configInfo()
112+
out.integrations_loaded = Object.keys(pluginManager._pluginsByName)
81113
return out
82114
}
83115

@@ -104,6 +136,8 @@ function setSamplingRules (theRules) {
104136

105137
module.exports = {
106138
startupLog,
139+
logIntegrations,
140+
logAgentError,
107141
setStartupLogConfig,
108142
setStartupLogPluginManager,
109143
setSamplingRules,

0 commit comments

Comments
 (0)