Skip to content

Commit b223fd3

Browse files
authored
Add otel detection delay. (#1485)
1 parent bf99b69 commit b223fd3

3 files changed

Lines changed: 50 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Release History
22

3+
### 3.13.1 ()
4+
5+
#### Other Changes
6+
7+
- Update OTel global detection to wait for the customer app to initialize before detection.
8+
39
### 3.13.0 (2026-01-16)
410

511
#### Other Changes

src/agent/agentLoader.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useAzureMonitor } from "../main";
1212

1313

1414
const forceStart = process.env.APPLICATIONINSIGHTS_FORCE_START === "true";
15+
const OTEL_DETECTION_DELAY_MS = 60000; // 1 minute
1516
// Azure Connection String
1617
const ENV_connectionString = "APPLICATIONINSIGHTS_CONNECTION_STRING";
1718
const ENV_AZURE_PREFIX = "APPSETTING_"; // Azure adds this prefix to all environment variables
@@ -120,8 +121,12 @@ export class AgentLoader {
120121
console.log(msg);
121122
return;
122123
}
123-
// Detect and report OpenTelemetry globals before attempting to load the agent
124-
this._detectOpenTelemetryGlobals();
124+
// Schedule detection of OpenTelemetry globals after a delay to allow customer application to initialize
125+
const otelDetectionTimeout = setTimeout(() => {
126+
this._detectOpenTelemetryGlobals();
127+
}, OTEL_DETECTION_DELAY_MS);
128+
// Ensure the timeout doesn't prevent the process from exiting
129+
otelDetectionTimeout.unref();
125130
if (this._validate()) {
126131
try {
127132
// Set environment variable to auto attach so the distro is aware of the attach state

test/unitTests/agent/agentLoader.tests.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import { LoggerProvider } from "@opentelemetry/sdk-logs";
1616
describe("agent/agentLoader", () => {
1717
let originalEnv: NodeJS.ProcessEnv;
1818
let sandbox: sinon.SinonSandbox;
19+
let clock: sinon.SinonFakeTimers;
1920
let originalOtelGlobalV1: any;
2021
let originalOtelGlobalV2: any;
2122
let originalLogsGlobal: any;
23+
const OTEL_DETECTION_DELAY_MS = 60000; // 1 minute - matches the constant in agentLoader.ts
2224

2325
const defaultConfig = {
2426
azureMonitorExporterOptions: {
@@ -59,6 +61,7 @@ describe("agent/agentLoader", () => {
5961

6062
beforeEach(() => {
6163
originalEnv = process.env;
64+
clock = sandbox.useFakeTimers();
6265
const otelSymbolV1 = Symbol.for('opentelemetry.js.api.1');
6366
const otelSymbolV2 = Symbol.for('opentelemetry.js.api.2');
6467
const logsSymbol = Symbol.for('io.opentelemetry.js.api.logs');
@@ -69,6 +72,7 @@ describe("agent/agentLoader", () => {
6972

7073
afterEach(() => {
7174
process.env = originalEnv;
75+
clock.restore();
7276
sandbox.restore();
7377
const otelSymbolV1 = Symbol.for('opentelemetry.js.api.1');
7478
const otelSymbolV2 = Symbol.for('opentelemetry.js.api.2');
@@ -231,6 +235,39 @@ describe("agent/agentLoader", () => {
231235
assert.ok((logged.message as string).includes("MeterProvider"));
232236
});
233237

238+
it("should delay OpenTelemetry detection by 1 minute after initialize", () => {
239+
const env = {
240+
["APPLICATIONINSIGHTS_CONNECTION_STRING"]: "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333",
241+
};
242+
process.env = env;
243+
const tracerProvider = new BasicTracerProvider();
244+
trace.setGlobalTracerProvider(tracerProvider);
245+
246+
const agent = new AgentLoader();
247+
const detectGlobalsSpy = sandbox.spy(agent as any, "_detectOpenTelemetryGlobals");
248+
const diagnosticLoggerStub = sandbox.stub(agent["_diagnosticLogger"], "logMessage");
249+
sandbox.stub(agent["_statusLogger"], "logStatus");
250+
251+
agent.initialize();
252+
253+
// Detection should not have been called yet
254+
assert.strictEqual(detectGlobalsSpy.callCount, 0);
255+
// Only the initialization success message should be logged
256+
assert.ok(diagnosticLoggerStub.calledOnce);
257+
assert.strictEqual(diagnosticLoggerStub.args[0][0].messageId, DiagnosticMessageId.attachSuccessful);
258+
259+
// Advance time by less than the delay
260+
clock.tick(OTEL_DETECTION_DELAY_MS - 1);
261+
assert.strictEqual(detectGlobalsSpy.callCount, 0);
262+
263+
// Advance time to trigger the detection
264+
clock.tick(1);
265+
assert.strictEqual(detectGlobalsSpy.callCount, 1);
266+
// Now the conflict message should be logged
267+
assert.strictEqual(diagnosticLoggerStub.callCount, 2);
268+
assert.strictEqual(diagnosticLoggerStub.args[1][0].messageId, DiagnosticMessageId.openTelemetryConflict);
269+
});
270+
234271
it("should log detected OpenTelemetry logger provider via logs symbol getter", () => {
235272
const env = {
236273
["APPLICATIONINSIGHTS_CONNECTION_STRING"]: "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333",

0 commit comments

Comments
 (0)