Skip to content

Commit df03f05

Browse files
authored
better logging for config state; release 4.10.0 (#4386)
This cherry-picks an improvement from the 3.x branch: > This adds a periodic (once per minute) dump of effective config changes > from the default, once per minute at 'trace'-level. > > This also fixes an issue where a central-config update of `log_level` > did not update the *child* logger on the APM client. Only the agent's > own logger's level was updated. > > This adds trans.sampled to some debug logging output. and prepares for a v4.10.0 release. Refs: #4291 (equivalent on 3.x branch)
1 parent 6453fff commit df03f05

File tree

8 files changed

+60
-5
lines changed

8 files changed

+60
-5
lines changed

CHANGELOG.asciidoc

+10-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ Notes:
3333
3434
See the <<upgrade-to-v4>> guide.
3535
36+
[[release-notes-4.10.0]]
37+
==== 4.10.0 - 2024/12/24
38+
39+
[float]
40+
===== Features
41+
42+
* Improve trace-level logging to better support debugging central config
43+
and transaction sampling issues. ({issues}4291[#4291])
44+
45+
3646
[[release-notes-4.9.0]]
3747
==== 4.9.0 - 2024/12/09
3848
@@ -50,8 +60,6 @@ See the <<upgrade-to-v4>> guide.
5060
resulting in the APM agent no longer sending tracing data.
5161
({pull}4359[#4359])
5262
53-
[float]
54-
===== Chores
5563
5664
5765
[[release-notes-4.8.1]]

lib/agent.js

+18
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const errors = require('./errors');
2424
const { InflightEventSet } = require('./InflightEventSet');
2525
const { Instrumentation } = require('./instrumentation');
2626
const { elasticApmAwsLambda } = require('./lambda');
27+
const logging = require('./logging');
2728
const Metrics = require('./metrics');
2829
const parsers = require('./parsers');
2930
const symbols = require('./symbols');
@@ -317,6 +318,23 @@ Agent.prototype.start = function (opts) {
317318

318319
this.logger.info(preambleData, 'Elastic APM Node.js Agent v%s', version);
319320

321+
if (!logging.isLoggerCustom(this.logger)) {
322+
// Periodically dump the current config (delta from defaults) when logging
323+
// at "trace"-level. This allows getting the effective config from a running
324+
// agent by setting trace-level logging and getting 1 minute of logs.
325+
// (Sometimes getting logs from application *start* is no possible.)
326+
setInterval(() => {
327+
if (this.logger.isLevelEnabled('trace')) {
328+
try {
329+
const currConfig = this._conf.getCurrConfig();
330+
this.logger.trace({ currConfig }, 'currConfig');
331+
} catch (err) {
332+
this.logger.trace({ err }, 'error calculating currConfig');
333+
}
334+
}
335+
}, 60 * 1000).unref();
336+
}
337+
320338
if (isPreviewVersion) {
321339
this.logger.warn(
322340
'Version %s is a pre-release and not intended for use in production environments',

lib/apm-client/apm-client.js

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ function createApmClient(config, agent) {
7070
!logging.isLoggerCustom(agent.logger)
7171
) {
7272
logging.setLogLevel(agent.logger, value);
73+
// Hackily also set the HttpApmClient._log level.
74+
logging.setLogLevel(client._log, value);
7375
agent.logger.info(
7476
`Central config success: updated logger with new logLevel: ${value}`,
7577
);

lib/config/config.js

+22
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const {
3434
setStartOptions,
3535
getPreambleData,
3636
readEnvOptions,
37+
CENTRAL_CONFIG_OPTS,
3738
} = require('./schema');
3839

3940
const {
@@ -244,6 +245,27 @@ class Config {
244245
}
245246
return loggable;
246247
}
248+
249+
// Returns an object showing the current config, excluding default values.
250+
getCurrConfig() {
251+
const currConfig = {};
252+
253+
// Start with the values from the logging preamble. This selected keys
254+
// that were specified, and handles redaction.
255+
for (let [k, v] of Object.entries(this.loggingPreambleData.config)) {
256+
currConfig[k] = v.value;
257+
}
258+
259+
// Then add the current value of any var possibly set by central config.
260+
currConfig.centralConfig = this.centralConfig;
261+
if (this.centralConfig) {
262+
for (let k of Object.values(CENTRAL_CONFIG_OPTS)) {
263+
currConfig[k] = this[k];
264+
}
265+
}
266+
267+
return currConfig;
268+
}
247269
}
248270

249271
function validateServiceName(s) {

lib/instrumentation/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,10 @@ Instrumentation.prototype.addEndedTransaction = function (transaction) {
745745
!transaction.sampled &&
746746
!agent._apmClient.supportsKeepingUnsampledTransaction()
747747
) {
748+
agent.logger.debug(
749+
{ trans: transaction.id, trace: transaction.traceId },
750+
'dropping unsampled transaction',
751+
);
748752
return;
749753
}
750754

lib/instrumentation/transaction.js

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ function Transaction(agent, name, ...args) {
8888
trans: this.id,
8989
parent: this.parentId,
9090
trace: this.traceId,
91+
sampled: this.sampled,
9192
name: this.name,
9293
type: this.type,
9394
});

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "elastic-apm-node",
3-
"version": "4.9.0",
3+
"version": "4.10.0",
44
"description": "The official Elastic APM agent for Node.js",
55
"type": "commonjs",
66
"main": "index.js",

0 commit comments

Comments
 (0)