WIP! A BB-style forum, on the ATmosphere! We're still working... we'll be back soon when we have something to show off!
node typescript hono htmx atproto
at main 91 lines 2.6 kB view raw
1import type { Logger as IOTelLogger } from "@opentelemetry/api-logs"; 2import { SeverityNumber } from "@opentelemetry/api-logs"; 3import type { LoggerProvider } from "@opentelemetry/sdk-logs"; 4import type { Attributes } from "@opentelemetry/api"; 5import type { Logger, LogAttributes, LogLevel } from "./types.js"; 6import { SEVERITY_MAP } from "./types.js"; 7 8/** 9 * Structured logger wrapping the OpenTelemetry Logs API. 10 * 11 * Provides an ergonomic interface (info/warn/error/etc.) over the 12 * lower-level OTel LogRecord emit API, with child logger support 13 * for adding persistent context (request ID, component name, etc.). 14 */ 15export class AppLogger implements Logger { 16 private otelLogger: IOTelLogger; 17 private provider: LoggerProvider; 18 private baseAttributes: LogAttributes; 19 private minSeverity: SeverityNumber; 20 21 constructor( 22 otelLogger: IOTelLogger, 23 provider: LoggerProvider, 24 baseAttributes: LogAttributes = {}, 25 minSeverity: SeverityNumber = SeverityNumber.INFO 26 ) { 27 this.otelLogger = otelLogger; 28 this.provider = provider; 29 this.baseAttributes = baseAttributes; 30 this.minSeverity = minSeverity; 31 } 32 33 debug(message: string, attributes?: LogAttributes): void { 34 this.emit(SeverityNumber.DEBUG, "debug", message, attributes); 35 } 36 37 info(message: string, attributes?: LogAttributes): void { 38 this.emit(SeverityNumber.INFO, "info", message, attributes); 39 } 40 41 warn(message: string, attributes?: LogAttributes): void { 42 this.emit(SeverityNumber.WARN, "warn", message, attributes); 43 } 44 45 error(message: string, attributes?: LogAttributes): void { 46 this.emit(SeverityNumber.ERROR, "error", message, attributes); 47 } 48 49 fatal(message: string, attributes?: LogAttributes): void { 50 this.emit(SeverityNumber.FATAL, "fatal", message, attributes); 51 } 52 53 child(attributes: LogAttributes): Logger { 54 return new AppLogger( 55 this.otelLogger, 56 this.provider, 57 { ...this.baseAttributes, ...attributes }, 58 this.minSeverity 59 ); 60 } 61 62 async shutdown(): Promise<void> { 63 await this.provider.shutdown(); 64 } 65 66 private emit( 67 severityNumber: SeverityNumber, 68 severityText: string, 69 message: string, 70 attributes?: LogAttributes 71 ): void { 72 if (severityNumber < this.minSeverity) { 73 return; 74 } 75 76 this.otelLogger.emit({ 77 severityNumber, 78 severityText, 79 body: message, 80 attributes: { 81 ...this.baseAttributes, 82 ...attributes, 83 } as Attributes, 84 }); 85 } 86} 87 88/** Resolve a LogLevel string to its OTel SeverityNumber. */ 89export function resolveLogLevel(level: LogLevel): SeverityNumber { 90 return SEVERITY_MAP[level]; 91}