| 271 | |
| 272 | class OpenTelemetryLogTransport extends Transport { |
| 273 | override log( |
| 274 | info: winston.Logform.TransformableInfo & { message: unknown }, |
| 275 | callback: () => void, |
| 276 | ): void { |
| 277 | setImmediate(() => this.emit("logged", info)); |
| 278 | |
| 279 | try { |
| 280 | const globalProvider = logs.getLoggerProvider(); |
| 281 | const otelLogger = globalProvider.getLogger("winston", "1.0.0"); |
| 282 | |
| 283 | const { level, message, ...rest } = info; |
| 284 | |
| 285 | const attributes: AnyValueMap = sanitizeAttributes(rest); |
| 286 | |
| 287 | const spanContext = trace.getActiveSpan()?.spanContext(); |
| 288 | if (spanContext) { |
| 289 | attributes.trace_id = spanContext.traceId as AnyValue; |
| 290 | attributes.span_id = spanContext.spanId as AnyValue; |
| 291 | } |
| 292 | |
| 293 | otelLogger.emit({ |
| 294 | body: toAnyValue(message), |
| 295 | severityText: level.toUpperCase(), |
| 296 | severityNumber: mapWinstonLevelToOtel(level), |
| 297 | attributes, |
| 298 | }); |
| 299 | } catch { |
| 300 | // best-effort: do not throw from logger |
| 301 | } |
| 302 | |
| 303 | callback(); |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | export class Logger { |