feat(server/otel): integrate OpenTelemetry logging and emit logs with context
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
"@moeru/eventa": "catalog:",
|
||||
"@moeru/std": "catalog:",
|
||||
"@opentelemetry/api": "^1.9.1",
|
||||
"@opentelemetry/api-logs": "^0.214.0",
|
||||
"@opentelemetry/exporter-logs-otlp-proto": "^0.214.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.214.0",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.214.0",
|
||||
|
||||
@@ -16,7 +16,7 @@ import type { HonoEnv } from './types/hono'
|
||||
|
||||
import process from 'node:process'
|
||||
|
||||
import { initLogger, LoggerFormat, LoggerLevel, useLogger } from '@guiiai/logg'
|
||||
import { initLogger, LoggerFormat, LoggerLevel, setGlobalHookPostLog, useLogger } from '@guiiai/logg'
|
||||
import { serve } from '@hono/node-server'
|
||||
import { createNodeWebSocket } from '@hono/node-ws'
|
||||
import { Hono } from 'hono'
|
||||
@@ -29,7 +29,7 @@ import { createAuth } from './libs/auth'
|
||||
import { createDrizzle, migrateDatabase } from './libs/db'
|
||||
import { parsedEnv } from './libs/env'
|
||||
import { initializeExternalDependency } from './libs/external-dependency'
|
||||
import { initOtel } from './libs/otel'
|
||||
import { emitOtelLog, initOtel } from './libs/otel'
|
||||
import { createRedis } from './libs/redis'
|
||||
import { sessionMiddleware } from './middlewares/auth'
|
||||
import { otelMiddleware } from './middlewares/otel'
|
||||
@@ -190,6 +190,11 @@ export async function createApp() {
|
||||
injeca.setLogger(createLoggLogger(useLogger('injeca').useGlobalConfig()))
|
||||
const logger = useLogger('app').useGlobalConfig()
|
||||
|
||||
// Forward logg output to OpenTelemetry log exporter
|
||||
setGlobalHookPostLog((log) => {
|
||||
emitOtelLog(log.level, log.context, log.message, log.fields as Record<string, string | number | boolean>)
|
||||
})
|
||||
|
||||
const otel = injeca.provide('libs:otel', {
|
||||
dependsOn: { env: parsedEnv, lifecycle },
|
||||
build: ({ dependsOn }) => {
|
||||
|
||||
@@ -7,7 +7,8 @@ import type { Env } from './env'
|
||||
import { env as processEnv } from 'node:process'
|
||||
|
||||
import { useLogger } from '@guiiai/logg'
|
||||
import { diag, DiagConsoleLogger, DiagLogLevel, metrics } from '@opentelemetry/api'
|
||||
import { diag, DiagConsoleLogger, DiagLogLevel, metrics, trace } from '@opentelemetry/api'
|
||||
import { logs, SeverityNumber } from '@opentelemetry/api-logs'
|
||||
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-proto'
|
||||
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto'
|
||||
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'
|
||||
@@ -298,3 +299,39 @@ export function initOtel(env: Env): OtelInstance | undefined {
|
||||
shutdown,
|
||||
}
|
||||
}
|
||||
|
||||
const severityMap: Record<string, SeverityNumber> = {
|
||||
debug: SeverityNumber.DEBUG,
|
||||
verbose: SeverityNumber.TRACE,
|
||||
log: SeverityNumber.INFO,
|
||||
info: SeverityNumber.INFO,
|
||||
warn: SeverityNumber.WARN,
|
||||
error: SeverityNumber.ERROR,
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a log record to OpenTelemetry.
|
||||
* Automatically attaches the active span's traceId/spanId when available.
|
||||
*/
|
||||
export function emitOtelLog(
|
||||
level: string,
|
||||
context: string,
|
||||
message: string,
|
||||
attributes?: Record<string, string | number | boolean>,
|
||||
): void {
|
||||
const otelLogger = logs.getLogger(context)
|
||||
const spanContext = trace.getActiveSpan()?.spanContext()
|
||||
|
||||
otelLogger.emit({
|
||||
severityNumber: severityMap[level.toLowerCase()] ?? SeverityNumber.INFO,
|
||||
severityText: level.toUpperCase(),
|
||||
body: message,
|
||||
attributes: {
|
||||
...attributes,
|
||||
...(spanContext && {
|
||||
trace_id: spanContext.traceId,
|
||||
span_id: spanContext.spanId,
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
Generated
+3
@@ -530,6 +530,9 @@ importers:
|
||||
'@opentelemetry/api':
|
||||
specifier: ^1.9.1
|
||||
version: 1.9.1
|
||||
'@opentelemetry/api-logs':
|
||||
specifier: ^0.214.0
|
||||
version: 0.214.0
|
||||
'@opentelemetry/exporter-logs-otlp-proto':
|
||||
specifier: ^0.214.0
|
||||
version: 0.214.0(@opentelemetry/api@1.9.1)
|
||||
|
||||
Reference in New Issue
Block a user