autotel
Version:
Write Once, Observe Anywhere
236 lines (232 loc) • 7.6 kB
JavaScript
;
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