import { redactSecrets, formatMessage, safeJsonStringify } from "./utils/strings.js";
export type LogLevel = "debug" | "info" | "warn" | "error";
export interface Logger {
debug: (message: string, ...args: unknown[]) => void;
info: (message: string, ...args: unknown[]) => void;
warn: (message: string, ...args: unknown[]) => void;
error: (message: string, ...args: unknown[]) => void;
audit: (event: string, payload: unknown) => void;
}
function log(level: LogLevel, message: string, args: unknown[]): void {
const timestamp = new Date().toISOString();
const formatted = formatMessage(message, args);
const line = `[${timestamp}] ${level.toUpperCase()} ${formatted}`;
process.stderr.write(`${line}\n`);
}
/**
* Create a structured logger with secret scrubbing for audit events.
*/
export function createLogger(): Logger {
return {
debug: (message, ...args) => log("debug", message, args),
info: (message, ...args) => log("info", message, args),
warn: (message, ...args) => log("warn", message, args),
error: (message, ...args) => log("error", message, args),
audit: (event, payload) => {
const scrubbed = redactSecrets(payload);
log("info", "audit %s %s", [event, safeJsonStringify(scrubbed)]);
},
};
}
/**
* Create a no-op logger that emits nothing to stdio.
*/