diff --git a/packages/salesforcedx-utils-vscode/src/telemetry/reporters/o11yReporter.ts b/packages/salesforcedx-utils-vscode/src/telemetry/reporters/o11yReporter.ts index f00dbb69e02..a6b2468a25b 100755 --- a/packages/salesforcedx-utils-vscode/src/telemetry/reporters/o11yReporter.ts +++ b/packages/salesforcedx-utils-vscode/src/telemetry/reporters/o11yReporter.ts @@ -21,6 +21,7 @@ export class O11yReporter private o11yUploadEndpoint: string; private toDispose: Disposable[] = []; private readonly o11yService: O11yService; + private batchingCleanup: (() => void) | null = null; // user defined tag to add to properties that is defined via setting private telemetryTag: string | undefined; @@ -45,6 +46,12 @@ export class O11yReporter public async initialize(extensionName: string): Promise { await this.o11yService.initialize(extensionName, this.o11yUploadEndpoint); + + // Enable automatic batching with 30-second periodic flush + this.batchingCleanup = this.o11yService.enableAutoBatching({ + flushInterval: 30_000, // 30 seconds + enableShutdownHook: true, // Ensure events are flushed on shutdown + }); } private getUserProperties(): Record { @@ -88,7 +95,8 @@ export class O11yReporter measurements }); - void this.o11yService.upload(); + // Batching is enabled - no need to upload after each event + // Events will be automatically batched and uploaded based on threshold (50KB) or periodic flush (30s) } } @@ -121,12 +129,20 @@ export class O11yReporter measurements }); - void this.o11yService.upload(); + // Batching is enabled - no need to upload after each event + // Events will be automatically batched and uploaded based on threshold (50KB) or periodic flush (30s) } } public async dispose(): Promise { - await this.o11yService.upload(); + // Cleanup batching (removes timers and shutdown hooks) + if (this.batchingCleanup) { + this.batchingCleanup(); + this.batchingCleanup = null; + } + + // Force final flush of any remaining events + await this.o11yService.forceFlush(); } /** diff --git a/packages/salesforcedx-utils-vscode/test/jest/telemetry/reporters/o11yReporter.test.ts b/packages/salesforcedx-utils-vscode/test/jest/telemetry/reporters/o11yReporter.test.ts index b46af87af08..06d680d590c 100644 --- a/packages/salesforcedx-utils-vscode/test/jest/telemetry/reporters/o11yReporter.test.ts +++ b/packages/salesforcedx-utils-vscode/test/jest/telemetry/reporters/o11yReporter.test.ts @@ -19,6 +19,8 @@ describe('O11yReporter', () => { let sendMock: jest.Mock; let uploadMock: jest.Mock; + let forceFlushMock: jest.Mock; + let enableAutoBatchingMock: jest.Mock; let o11yReporter: O11yReporter; beforeEach(() => { @@ -32,10 +34,17 @@ describe('O11yReporter', () => { // Mock O11yService sendMock = jest.fn(); uploadMock = jest.fn(); + forceFlushMock = jest.fn().mockResolvedValue(undefined); + enableAutoBatchingMock = jest.fn().mockReturnValue(() => { + // Return a cleanup function + }); jest.spyOn(O11yService, 'getInstance').mockReturnValue({ - logEvent: sendMock, // Now mocks logEvent correctly - upload: uploadMock // Also mocks upload to prevent dispose failure + logEvent: sendMock, + upload: uploadMock, + forceFlush: forceFlushMock, + enableAutoBatching: enableAutoBatchingMock, + initialize: jest.fn().mockResolvedValue(undefined) } as any); // Mock workspace config for telemetry tag