Skip to content
File

Blob: src/worker/lib/logger.ts

typescript51 lines
1export type LogLevel = "debug" | "info" | "warn" | "error";
2 
3type Fields = Record<string, unknown>;
4 
5const LEVELS: Record<LogLevel, number> = { debug: 10, info: 20, warn: 30, error: 40 };
6 
7let minLevel: LogLevel = "info";
8 
9function parseLevel(input?: string | null): LogLevel {
10 const v = (input || "").toLowerCase();
11 if (v === "debug" || v === "info" || v === "warn" || v === "error") return v;
12 return "info";
13}
14 
15export function setLevel(input?: string) {
16 minLevel = parseLevel(input);
17}
18 
19export interface Logger {
20 debug: (event: string, fields?: Fields) => void;
21 info: (event: string, fields?: Fields) => void;
22 warn: (event: string, fields?: Fields) => void;
23 error: (event: string, fields?: Fields) => void;
24 child: (fields: Fields) => Logger;
25}
26 
27function write(level: LogLevel, component: string, base: Fields, event: string, fields: Fields) {
28 if (LEVELS[level] < LEVELS[minLevel]) return;
29 const entry = JSON.stringify({ ts: new Date().toISOString(), level, component, event, ...base, ...fields });
30 if (level === "error") return console.error(entry);
31 if (level === "warn") return console.warn(entry);
32 console.log(entry);
33}
34 
35export function createLogger(component: string, baseFields: Fields = {}): Logger {
36 return {
37 debug: (event, fields = {}) => write("debug", component, baseFields, event, fields),
38 info: (event, fields = {}) => write("info", component, baseFields, event, fields),
39 warn: (event, fields = {}) => write("warn", component, baseFields, event, fields),
40 error: (event, fields = {}) => write("error", component, baseFields, event, fields),
41 child: (fields) => createLogger(component, { ...baseFields, ...fields }),
42 };
43}
44 
45export function errorContext(error: unknown) {
46 if (error instanceof Error) {
47 return { errorName: error.name, errorMessage: error.message, errorStack: error.stack };
48 }
49 return { errorMessage: String(error) };
50}