Skip to content

Commit 5b1eef3

Browse files
committed
fix: use logRecordProcessors array and lazy-load OTEL logger
1 parent 0e96d29 commit 5b1eef3

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

src/instrumentation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ if (shouldEnableOtel) {
6060
exporter: metricExporter,
6161
exportIntervalMillis: 60000, // Export metrics every 60 seconds
6262
}),
63-
logRecordProcessor: new BatchLogRecordProcessor(logExporter),
63+
logRecordProcessors: [new BatchLogRecordProcessor(logExporter)],
6464
instrumentations: [
6565
getNodeAutoInstrumentations({
6666
// Automatic instrumentation for HTTP, gRPC, database clients, etc.

src/lib/logger.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ class Logger {
2121
private currentLogLevel: LogLevel;
2222
private serviceName: string;
2323
private serviceVersion: string;
24-
private otelLogger: ReturnType<ReturnType<typeof logs.getLoggerProvider>["getLogger"]> | null;
24+
private otelLogger: ReturnType<ReturnType<typeof logs.getLoggerProvider>["getLogger"]> | null =
25+
null;
26+
private otelLoggerInitialized: boolean = false;
2527

2628
constructor() {
2729
this.environment = process.env.NODE_ENV || "development";
@@ -32,15 +34,28 @@ class Logger {
3234
const logLevelName =
3335
process.env.LOG_LEVEL || (this.environment === "production" ? "info" : "debug");
3436
this.currentLogLevel = LOG_LEVELS[logLevelName] || LOG_LEVELS.info;
37+
}
38+
39+
// Lazy-load OpenTelemetry logger on first use (after OTEL SDK is initialized)
40+
private getOtelLogger(): ReturnType<
41+
ReturnType<typeof logs.getLoggerProvider>["getLogger"]
42+
> | null {
43+
if (this.otelLoggerInitialized) {
44+
return this.otelLogger;
45+
}
3546

36-
// Get OpenTelemetry logger if available
3747
try {
3848
const loggerProvider = logs.getLoggerProvider();
3949
this.otelLogger = loggerProvider.getLogger(this.serviceName, this.serviceVersion);
40-
} catch (error) {
50+
this.otelLoggerInitialized = true;
51+
console.log("✅ OpenTelemetry logger initialized for application logs");
52+
} catch {
4153
// OpenTelemetry not initialized, fall back to console logging
4254
this.otelLogger = null;
55+
this.otelLoggerInitialized = true;
4356
}
57+
58+
return this.otelLogger;
4459
}
4560

4661
private shouldLog(level: LogLevel): boolean {
@@ -78,7 +93,7 @@ class Logger {
7893
span_id: spanContext.spanId,
7994
};
8095
}
81-
} catch (error) {
96+
} catch {
8297
// OpenTelemetry not initialized or no active span
8398
}
8499
return {};
@@ -90,7 +105,7 @@ class Logger {
90105
const traceContext = this.getTraceContext();
91106

92107
// Grafana/Loki standardized log structure
93-
const logData: Record<string, any> = {
108+
const logData: Record<string, unknown> = {
94109
// Timestamps - ISO 8601 format
95110
timestamp: new Date().toISOString(),
96111
"@timestamp": new Date().toISOString(), // For Elasticsearch/Loki compatibility
@@ -130,9 +145,10 @@ class Logger {
130145
}
131146

132147
// Emit log via OpenTelemetry if available
133-
if (this.otelLogger) {
148+
const otelLogger = this.getOtelLogger();
149+
if (otelLogger) {
134150
try {
135-
this.otelLogger.emit({
151+
otelLogger.emit({
136152
severityNumber: level.severity,
137153
severityText: level.level.toUpperCase(),
138154
body: message,
@@ -150,7 +166,7 @@ class Logger {
150166
}),
151167
},
152168
});
153-
} catch (err) {
169+
} catch {
154170
// If OTEL logging fails, fall back to console
155171
}
156172
}

0 commit comments

Comments
 (0)