pkgs/core/src/logger.ts (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
export interface LogEntry {
level: LogLevel;
msg: string;
time: number;
[key: string]: unknown;
}
export interface LoggerOptions {
level?: LogLevel;
name?: string;
base?: Record<string, unknown>;
transport?: (entry: LogEntry) => void;
}
export interface KittenLogger {
trace(msg: string, data?: Record<string, unknown>): void;
debug(msg: string, data?: Record<string, unknown>): void;
info(msg: string, data?: Record<string, unknown>): void;
warn(msg: string, data?: Record<string, unknown>): void;
error(msg: string, data?: Record<string, unknown>): void;
fatal(msg: string, data?: Record<string, unknown>): void;
child(bindings: Record<string, unknown>): KittenLogger;
}
const LEVELS: Record<LogLevel, number> = {
trace: 10,
debug: 20,
info: 30,
warn: 40,
error: 50,
fatal: 60,
};
const defaultTransport = (entry: LogEntry) => {
const out = JSON.stringify(entry);
if (entry.level === "error" || entry.level === "fatal") console.error(out);
else console.log(out);
};
export class Logger implements KittenLogger {
private readonly minLevel: number;
private readonly base: Record<string, unknown>;
private readonly transport: (entry: LogEntry) => void;
constructor(private readonly options: LoggerOptions = {}) {
this.minLevel = LEVELS[options.level ?? "info"];
this.base = {
...(options.name ? { name: options.name } : {}),
...options.base,
};
this.transport = options.transport ?? defaultTransport;
}
private write(level: LogLevel, msg: string, data?: Record<string, unknown>) {
if (LEVELS[level] < this.minLevel) return;
this.transport({
level,
msg,
time: Date.now(),
...this.base,
...data,
});
}
trace(msg: string, data?: Record<string, unknown>) {
this.write("trace", msg, data);
}
debug(msg: string, data?: Record<string, unknown>) {
this.write("debug", msg, data);
}
info(msg: string, data?: Record<string, unknown>) {
this.write("info", msg, data);
}
warn(msg: string, data?: Record<string, unknown>) {
this.write("warn", msg, data);
}
error(msg: string, data?: Record<string, unknown>) {
this.write("error", msg, data);
}
fatal(msg: string, data?: Record<string, unknown>) {
this.write("fatal", msg, data);
}
child(bindings: Record<string, unknown>): KittenLogger {
return new Logger({
...this.options,
base: { ...this.base, ...bindings },
});
}
}
const baseLogger = new Logger();
export { baseLogger };
|