import { pipeline, Transform } from 'node:stream'; import build from 'pino-abstract-transport'; /** * Pipeline-трансформ перед pino-opentelemetry-transport: приводит поле `time` * к числу (epoch ms), если оно пришло строкой (например, при дефолтном * LOG_TIMESTAMP_FORMAT=isoTime). OTLP ожидает числовой timestamp, иначе запись * молча отбрасывается. Трансформ применяется только к OTEL-ветке — stdout и * прочие транспорты сохраняют свой человекочитаемый формат времени. */ export default function buildOtelTimeTransform(): Promise { return build( (source) => { const transform = new Transform({ objectMode: true, autoDestroy: true, transform( chunk: Record, _encoding: BufferEncoding, callback: (error?: Error | null, data?: string) => void, ): void { if (typeof chunk.time === 'string') { const epochMs = Date.parse(chunk.time); if (!Number.isNaN(epochMs)) { chunk.time = epochMs; } } callback(null, `${JSON.stringify(chunk)}\n`); }, }); pipeline(source, transform, () => {}); return transform; }, { enablePipelining: true }, ) as unknown as Promise; }