From 572d0d7d9d4a745757e52c27ad9d0d0c414c1b97 Mon Sep 17 00:00:00 2001 From: Ayan Khan Date: Mon, 30 Mar 2026 22:30:33 -0400 Subject: [PATCH 1/3] feat(telemetry): add DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL config Make the extended heartbeat interval configurable via the DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL environment variable (in seconds, default 86400 / 24h). Previously this was hardcoded to 24 hours. This aligns with the cross-SDK standardization of the app-extended-heartbeat telemetry event. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/dd-trace/src/config/index.js | 6 ++++++ .../src/config/supported-configurations.json | 10 ++++++++++ packages/dd-trace/src/telemetry/telemetry.js | 3 ++- .../dd-trace/test/telemetry/index.spec.js | 20 +++++++++---------- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/dd-trace/src/config/index.js b/packages/dd-trace/src/config/index.js index 797d983e644..f453070dcca 100644 --- a/packages/dd-trace/src/config/index.js +++ b/packages/dd-trace/src/config/index.js @@ -353,6 +353,7 @@ class Config { DD_TAGS, DD_TELEMETRY_DEBUG, DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED, + DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL, DD_TELEMETRY_HEARTBEAT_INTERVAL, DD_TELEMETRY_LOG_COLLECTION_ENABLED, DD_TELEMETRY_METRICS_ENABLED, @@ -761,6 +762,9 @@ class Config { setString(target, 'instrumentation_config_id', DD_INSTRUMENTATION_CONFIG_ID) setBoolean(target, 'telemetry.debug', DD_TELEMETRY_DEBUG) setBoolean(target, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED) + target['telemetry.extendedHeartbeatInterval'] = + maybeInt(Math.floor(DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL * 1000)) + unprocessedTarget['telemetry.extendedHeartbeatInterval'] = DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL target['telemetry.heartbeatInterval'] = maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000)) unprocessedTarget['telemetry.heartbeatInterval'] = DD_TELEMETRY_HEARTBEAT_INTERVAL setBoolean(target, 'telemetry.logCollection', DD_TELEMETRY_LOG_COLLECTION_ENABLED) @@ -1165,6 +1169,8 @@ class Config { calc.otelLogsUrl = `http://${agentHostname}:${DEFAULT_OTLP_PORT}` calc.otelMetricsUrl = `http://${agentHostname}:${DEFAULT_OTLP_PORT}/v1/metrics` calc.otelUrl = `http://${agentHostname}:${DEFAULT_OTLP_PORT}` + calc['telemetry.extendedHeartbeatInterval'] = + maybeInt(Math.floor(this.#defaults['telemetry.extendedHeartbeatInterval'] * 1000)) calc['telemetry.heartbeatInterval'] = maybeInt(Math.floor(this.#defaults['telemetry.heartbeatInterval'] * 1000)) setBoolean(calc, 'isGitUploadEnabled', diff --git a/packages/dd-trace/src/config/supported-configurations.json b/packages/dd-trace/src/config/supported-configurations.json index 5bca7736dc9..a862f5f47f8 100644 --- a/packages/dd-trace/src/config/supported-configurations.json +++ b/packages/dd-trace/src/config/supported-configurations.json @@ -1696,6 +1696,16 @@ "default": null } ], + "DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL": [ + { + "implementation": "B", + "type": "decimal", + "default": "86400.0", + "configurationNames": [ + "telemetry.extendedHeartbeatInterval" + ] + } + ], "DD_TELEMETRY_HEARTBEAT_INTERVAL": [ { "implementation": "B", diff --git a/packages/dd-trace/src/telemetry/telemetry.js b/packages/dd-trace/src/telemetry/telemetry.js index e113bb9e077..c5d02ca7945 100644 --- a/packages/dd-trace/src/telemetry/telemetry.js +++ b/packages/dd-trace/src/telemetry/telemetry.js @@ -60,6 +60,7 @@ const sessionPropagation = require('./session-propagation') * @typedef {{ * telemetry: { * enabled: boolean, + * extendedHeartbeatInterval: number, * heartbeatInterval: number, * debug?: boolean, * dependencyCollection?: boolean, @@ -348,7 +349,7 @@ function extendedHeartbeat (config) { heartbeatFailedDependencies = [] } sendData(config, application, host, 'app-extended-heartbeat', appPayload) - }, 1000 * 60 * 60 * 24).unref() + }, config.telemetry.extendedHeartbeatInterval).unref() } /** diff --git a/packages/dd-trace/test/telemetry/index.spec.js b/packages/dd-trace/test/telemetry/index.spec.js index 697a6b9583e..9b2a536eec7 100644 --- a/packages/dd-trace/test/telemetry/index.spec.js +++ b/packages/dd-trace/test/telemetry/index.spec.js @@ -123,7 +123,7 @@ describe('telemetry', () => { circularObject.child.parent = circularObject telemetry.start({ - telemetry: { enabled: true, heartbeatInterval: DEFAULT_HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: DEFAULT_HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: traceAgent.address().port, service: 'test service', @@ -324,7 +324,7 @@ describe('telemetry app-heartbeat', () => { }) telemetry.start({ - telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: 0, service: 'test service', @@ -391,7 +391,7 @@ describe('Telemetry extended heartbeat', () => { }) telemetry.start({ - telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: 0, service: 'test service', @@ -434,7 +434,7 @@ describe('Telemetry extended heartbeat', () => { }) const config = { - telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: 0, service: 'test service', @@ -579,7 +579,7 @@ describe('Telemetry retry', () => { }) telemetry.start({ - telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: 0, service: 'test service', @@ -668,7 +668,7 @@ describe('Telemetry retry', () => { }) telemetry.start({ - telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: 0, service: 'test service', @@ -739,7 +739,7 @@ describe('Telemetry retry', () => { }) telemetry.start({ - telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: 0, service: 'test service', @@ -801,7 +801,7 @@ describe('Telemetry retry', () => { // Start function sends 2 messages app-started & app-integrations-change telemetry.start({ - telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: 0, service: 'test service', @@ -885,7 +885,7 @@ describe('Telemetry retry', () => { // Start function sends 2 messages app-started & app-integrations-change telemetry.start({ - telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: 0, service: 'test service', @@ -979,7 +979,7 @@ describe('AVM OSS', () => { telemetry = require('../../src/telemetry/telemetry') telemetryConfig = { - telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL }, + telemetry: { enabled: true, heartbeatInterval: HEARTBEAT_INTERVAL, extendedHeartbeatInterval: 86400000 }, hostname: 'localhost', port: traceAgent.address().port, service: 'test service', From 076737f380970686bef8fb92118724f8c16b9b30 Mon Sep 17 00:00:00 2001 From: Ayan Khan Date: Mon, 30 Mar 2026 23:04:04 -0400 Subject: [PATCH 2/3] fix(telemetry): align DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL with config registry spec Change implementation from B to A and type from decimal to int per the config registry specification. Default updated from "86400.0" to "86400". Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/dd-trace/src/config/index.js | 2 +- packages/dd-trace/src/config/supported-configurations.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dd-trace/src/config/index.js b/packages/dd-trace/src/config/index.js index f453070dcca..ff57aef3d24 100644 --- a/packages/dd-trace/src/config/index.js +++ b/packages/dd-trace/src/config/index.js @@ -763,7 +763,7 @@ class Config { setBoolean(target, 'telemetry.debug', DD_TELEMETRY_DEBUG) setBoolean(target, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED) target['telemetry.extendedHeartbeatInterval'] = - maybeInt(Math.floor(DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL * 1000)) + maybeInt(parseInt(DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL) * 1000) unprocessedTarget['telemetry.extendedHeartbeatInterval'] = DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL target['telemetry.heartbeatInterval'] = maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000)) unprocessedTarget['telemetry.heartbeatInterval'] = DD_TELEMETRY_HEARTBEAT_INTERVAL diff --git a/packages/dd-trace/src/config/supported-configurations.json b/packages/dd-trace/src/config/supported-configurations.json index a862f5f47f8..e0abdf19c5a 100644 --- a/packages/dd-trace/src/config/supported-configurations.json +++ b/packages/dd-trace/src/config/supported-configurations.json @@ -1698,9 +1698,9 @@ ], "DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL": [ { - "implementation": "B", - "type": "decimal", - "default": "86400.0", + "implementation": "A", + "type": "int", + "default": "86400", "configurationNames": [ "telemetry.extendedHeartbeatInterval" ] From 553938e4898b16f3df3e1815768791895db84902 Mon Sep 17 00:00:00 2001 From: Ayan Khan Date: Mon, 30 Mar 2026 23:13:54 -0400 Subject: [PATCH 3/3] fix(telemetry): use Number.parseInt per lint rules Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/dd-trace/src/config/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dd-trace/src/config/index.js b/packages/dd-trace/src/config/index.js index ff57aef3d24..2f1a27195c6 100644 --- a/packages/dd-trace/src/config/index.js +++ b/packages/dd-trace/src/config/index.js @@ -763,7 +763,7 @@ class Config { setBoolean(target, 'telemetry.debug', DD_TELEMETRY_DEBUG) setBoolean(target, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED) target['telemetry.extendedHeartbeatInterval'] = - maybeInt(parseInt(DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL) * 1000) + maybeInt(Number.parseInt(DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL) * 1000) unprocessedTarget['telemetry.extendedHeartbeatInterval'] = DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL target['telemetry.heartbeatInterval'] = maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000)) unprocessedTarget['telemetry.heartbeatInterval'] = DD_TELEMETRY_HEARTBEAT_INTERVAL