Spaces:
Running
Running
File size: 2,857 Bytes
aa89cb5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | import { readTelemetryStartupConfiguration, telemetryStartupMessage, telemetryNotice } from '../core/telemetry-startup';
import type { RuntimeTelemetry } from '../core/telemetry';
import type { QueueHealth, TelemetrySignal } from './export-health';
export interface StandardTelemetryHealth {
readonly traceSpansFailed: number;
readonly logRecordsFailed: number;
readonly metricDataObjectsFailed: number;
readonly responses: Readonly<Record<TelemetrySignal, Readonly<{
rejected: number; partialSuccess: number; warnings: number; invalidResponses: number;
}>>>;
readonly queues: Readonly<Record<'traces' | 'logs', QueueHealth>>;
}
export interface StandardTelemetryHandle {
readonly telemetry: RuntimeTelemetry;
flush(): Promise<void>;
release(): Promise<void>;
health?(): StandardTelemetryHealth;
}
type Pipeline = { telemetry: RuntimeTelemetry; flush(): Promise<void>; shutdown(): Promise<void>; health?(): StandardTelemetryHealth };
const pipelines = new Map<string, { references: number; ready: Promise<Pipeline> }>();
const announcements = new Set<string>();
/** Node entry point; importing it does not import or initialize any OTel SDK. */
export function startStandardNodeTelemetry(): Promise<StandardTelemetryHandle | undefined> {
const configuration = readTelemetryStartupConfiguration(process.env);
const message = telemetryStartupMessage(configuration);
if (!announcements.has(message)) {
announcements.add(message);
telemetryNotice(message);
}
if (!configuration.enabled) return Promise.resolve(undefined);
const key = `${configuration.serviceName}|${configuration.endpoint}`;
let entry = pipelines.get(key);
if (!entry) {
entry = { references: 0, ready: import('./standard-node-sdk').then(module =>
module.createStandardNodePipeline(configuration.serviceName!, configuration.endpoint!)) };
pipelines.set(key, entry);
}
const ownedEntry = entry;
ownedEntry.references++;
return ownedEntry.ready.then(pipeline => {
let released = false;
return {
telemetry: pipeline.telemetry,
flush: () => pipeline.flush(),
health: pipeline.health ? () => pipeline.health!() : undefined,
release: async () => {
if (released) return;
released = true;
ownedEntry.references--;
if (ownedEntry.references !== 0) return;
if (pipelines.get(key) === ownedEntry) pipelines.delete(key);
try { await pipeline.shutdown(); }
catch { telemetryNotice('TeaQL telemetry: owned pipeline shutdown failed; business outcome unchanged.', true); }
},
};
}).catch(() => {
if (pipelines.get(key) === ownedEntry) pipelines.delete(key);
telemetryNotice('TeaQL telemetry: standard module unavailable; check installed SDK dependencies. Business continues without export.', true);
return undefined;
});
}
|