src/configured-logger.tsTypeScript
@@ -0,0 +1,49 @@
1+
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "off";2+
3+
const RANK: Record<LogLevel, number> = {4+
trace: 0,5+
debug: 1,6+
info: 2,7+
warn: 3,8+
error: 4,9+
off: 5,10+
};11+
12+
export interface LogSink {13+
write(record: { level: LogLevel; message: string }): void;14+
}15+
16+
export function parseLogLevel(raw: string | undefined): LogLevel {17+
const candidate = (raw || "info").trim().toLowerCase();18+
if (!(candidate in RANK)) {19+
return "info";20+
}21+
return candidate as LogLevel;22+
}23+
24+
export class ConfiguredLogger {25+
constructor(26+
private readonly readLevel: () => string | undefined,27+
private readonly sink: LogSink,28+
) {}29+
30+
log(level: Exclude<LogLevel, "off">, message: string): void {31+
const configured = parseLogLevel(this.readLevel());32+
33+
if (!this.isEnabled(configured, level)) {34+
return;35+
}36+
37+
this.sink.write({38+
level: configured,39+
message,40+
});41+
}42+
43+
private isEnabled(44+
configured: LogLevel,45+
eventLevel: Exclude<LogLevel, "off">,46+
): boolean {47+
return RANK[configured] >= RANK[eventLevel];48+
}49+
}