Skip to content
File

Blob: src/worker/common/logger.ts

typescript65 lines
1export type LogLevel = "debug" | "info" | "warn" | "error";
2 
3const levelValue: Record<LogLevel, number> = {
4 debug: 10,
5 info: 20,
6 warn: 30,
7 error: 40,
8};
9 
10function parseLevel(input?: string | null): LogLevel {
11 const v = (input || "").toLowerCase();
12 if (v === "debug" || v === "info" || v === "warn" || v === "error") return v;
13 return "info";
14}
15 
16export interface LoggerContext {
17 service: string;
18 repoId?: string;
19 doId?: string;
20 requestId?: string;
21}
22 
23export interface Logger {
24 debug: (msg: string, extra?: Record<string, unknown>) => void;
25 info: (msg: string, extra?: Record<string, unknown>) => void;
26 warn: (msg: string, extra?: Record<string, unknown>) => void;
27 error: (msg: string, extra?: Record<string, unknown>) => void;
28}
29 
30function emit(
31 level: LogLevel,
32 ctx: LoggerContext,
33 enabled: LogLevel,
34 msg: string,
35 extra?: Record<string, unknown>
36) {
37 if (levelValue[level] < levelValue[enabled]) return;
38 const entry: Record<string, unknown> = {
39 level,
40 service: ctx.service,
41 };
42 if (ctx.repoId) entry.repoId = ctx.repoId;
43 if (ctx.doId) entry.doId = ctx.doId;
44 if (ctx.requestId) entry.requestId = ctx.requestId;
45 entry.msg = msg;
46 if (extra) {
47 for (const [k, v] of Object.entries(extra)) entry[k] = v;
48 }
49 const line = JSON.stringify(entry);
50 if (level === "debug") console.info(line);
51 else if (level === "info") console.info(line);
52 else if (level === "warn") console.info(line);
53 else console.error(line);
54}
55 
56export function createLogger(level: string | undefined, base: LoggerContext): Logger {
57 const enabled = parseLevel(level);
58 return {
59 debug: (msg, extra) => emit("debug", base, enabled, msg, extra),
60 info: (msg, extra) => emit("info", base, enabled, msg, extra),
61 warn: (msg, extra) => emit("warn", base, enabled, msg, extra),
62 error: (msg, extra) => emit("error", base, enabled, msg, extra),
63 };
64}