UNPKG

autotel

Version:
236 lines (232 loc) 7.6 kB
'use strict'; var chunkESLWRGAG_cjs = require('./chunk-ESLWRGAG.cjs'); var api = require('@opentelemetry/api'); var LOG_LEVEL_KEY = api.createContextKey("autotel-log-level"); function getActiveLogLevel() { return api.context.active().getValue(LOG_LEVEL_KEY); } function runWithLogLevel(level, callback) { const ctx = api.context.active().setValue(LOG_LEVEL_KEY, level); return api.context.with(ctx, callback); } function getTraceContextInternal() { const span = api.trace.getActiveSpan(); if (!span) return null; const ctx = span.spanContext(); return { traceId: ctx.traceId, spanId: ctx.spanId, correlationId: ctx.traceId.slice(0, 16) // First 16 chars for grouping }; } function getTraceContext() { return getTraceContextInternal(); } function createBuiltinLogger(service, options) { const defaultLevel = options?.level || "info"; const pretty = options?.pretty || false; const levelPriority = { none: -1, debug: 0, info: 1, warn: 2, error: 3 }; const shouldLog = (level) => { const activeLevel = getActiveLogLevel() ?? defaultLevel; if (activeLevel === "none") return false; return levelPriority[level] >= levelPriority[activeLevel]; }; const log = (level, msg, attrs) => { if (!shouldLog(level)) return; const ctx = getTraceContextInternal(); const logEntry = { level, service, msg, ...attrs, ...ctx, // Auto-inject traceId, spanId, correlationId timestamp: (/* @__PURE__ */ new Date()).toISOString() }; if (pretty) { const traceInfo = ctx ? ` [${ctx.traceId.slice(0, 8)}.../${ctx.spanId.slice(0, 8)}...]` : ""; console.log( `[${level.toUpperCase()}]${traceInfo} ${service}: ${msg}`, attrs || "" ); } else { console.log(JSON.stringify(logEntry)); } }; const createLogMethod = (level) => { return (extraOrMessage, message) => { if (typeof extraOrMessage === "string") { if (message !== void 0 && typeof message === "object") { if (process.env.NODE_ENV !== "production") { console.warn( `[autotel] Legacy logger pattern detected: logger.${level}('message', metadata). Autotel recommends Pino signature: logger.${level}({ ...metadata }, 'message'). Auto-swapping arguments for compatibility.` ); } log(level, extraOrMessage, message); } else { log(level, extraOrMessage); } } else { log(level, message || "", extraOrMessage); } }; }; return { info: createLogMethod("info"), warn: createLogMethod("warn"), debug: createLogMethod("debug"), error: (extraOrMessage, message) => { if (typeof extraOrMessage === "string") { if (message instanceof Error) { if (process.env.NODE_ENV !== "production") { console.warn( `[autotel] Legacy logger pattern detected: logger.error('message', error). Autotel recommends Pino signature: logger.error({ err: error }, 'message'). Auto-swapping arguments for compatibility.` ); } log("error", extraOrMessage, { error: message.message, stack: message.stack, name: message.name }); return; } if (message !== void 0 && typeof message === "object") { if (process.env.NODE_ENV !== "production") { console.warn( `[autotel] Legacy logger pattern detected: logger.error('message', metadata). Autotel recommends Pino signature: logger.error({ ...metadata }, 'message'). Auto-swapping arguments for compatibility.` ); } const extra = message; const { err: err2, ...rest2 } = extra; let errorAttrs2 = rest2; if (err2 instanceof Error) { errorAttrs2 = { error: err2.message, stack: err2.stack, name: err2.name, ...rest2 }; } else if (err2 !== void 0) { errorAttrs2 = { err: err2, ...rest2 }; } log("error", extraOrMessage, errorAttrs2); return; } log("error", extraOrMessage); return; } const { err, ...rest } = extraOrMessage; let errorAttrs = rest; if (err instanceof Error) { errorAttrs = { error: err.message, stack: err.stack, name: err.name, ...rest }; } else if (err !== void 0) { errorAttrs = { err, ...rest }; } log("error", message || "", errorAttrs); } }; } function autotelLogger(options) { return createBuiltinLogger(options?.service || "app", { level: options?.level, pretty: options?.pretty }); } // src/logger.ts var LOG_LEVEL = { DEBUG: "debug", INFO: "info", WARN: "warn", ERROR: "error" }; function LoggedOperation(operationNameOrOptions) { const operationName = typeof operationNameOrOptions === "string" ? operationNameOrOptions : operationNameOrOptions.operationName; return function(originalMethod, context) { const methodName = String(context.name); return async function(...args) { const log = this.deps?.log; const startTime = performance.now(); const config = chunkESLWRGAG_cjs.getConfig(); const tracer = config.tracer; return tracer.startActiveSpan(operationName, async (span) => { try { log?.info( { operation: operationName, method: methodName, args }, "Operation started" ); const result = await originalMethod.apply(this, args); const duration = performance.now() - startTime; log?.info( { operation: operationName, method: methodName, duration }, "Operation completed" ); span.setStatus({ code: api.SpanStatusCode.OK }); span.setAttributes({ "operation.name": operationName, "operation.method": methodName, "operation.duration": duration, "operation.success": true }); return result; } catch (error) { const duration = performance.now() - startTime; log?.error( { err: error instanceof Error ? error : void 0, operation: operationName, method: methodName, duration }, "Operation failed" ); span.setStatus({ code: api.SpanStatusCode.ERROR, message: error instanceof Error ? error.message : "Unknown error" }); span.setAttributes({ "operation.name": operationName, "operation.method": methodName, "operation.duration": duration, "operation.success": false, "error.type": error instanceof Error ? error.constructor.name : "Unknown" }); throw error; } finally { span.end(); } }); }; }; } exports.LOG_LEVEL = LOG_LEVEL; exports.LoggedOperation = LoggedOperation; exports.autotelLogger = autotelLogger; exports.createBuiltinLogger = createBuiltinLogger; exports.getActiveLogLevel = getActiveLogLevel; exports.getTraceContext = getTraceContext; exports.runWithLogLevel = runWithLogLevel; //# sourceMappingURL=chunk-FU6R566Y.cjs.map //# sourceMappingURL=chunk-FU6R566Y.cjs.map