Files
lettersoup-online/002_source/cms/src/lib/logger.ts
louiscklaw 6c931c1fe8 build ok,
2025-04-14 09:26:24 +08:00

72 lines
1.9 KiB
TypeScript

/* eslint-disable no-console -- Allow */
// NOTE: A tracking system such as Sentry should replace the console
export const LogLevel = { NONE: 'NONE', ERROR: 'ERROR', WARN: 'WARN', DEBUG: 'DEBUG', ALL: 'ALL' } as const;
const LogLevelNumber = { NONE: 0, ERROR: 1, WARN: 2, DEBUG: 3, ALL: 4 } as const;
export interface LoggerOptions {
prefix?: string;
level?: keyof typeof LogLevel;
showLevel?: boolean;
}
export class Logger {
protected prefix: string;
protected level: keyof typeof LogLevel;
protected showLevel: boolean;
private levelNumber: number;
constructor({ prefix = '', level = LogLevel.ALL, showLevel = true }: LoggerOptions) {
this.prefix = prefix;
this.level = level;
this.levelNumber = LogLevelNumber[this.level];
this.showLevel = showLevel;
}
debug = (...args: unknown[]): void => {
if (this.canWrite(LogLevel.DEBUG)) {
this.write(LogLevel.DEBUG, ...args);
}
};
warn = (...args: unknown[]): void => {
if (this.canWrite(LogLevel.WARN)) {
this.write(LogLevel.WARN, ...args);
}
};
error = (...args: unknown[]): void => {
if (this.canWrite(LogLevel.ERROR)) {
this.write(LogLevel.ERROR, ...args);
}
};
private canWrite(level: keyof typeof LogLevel): boolean {
return this.levelNumber >= LogLevelNumber[level];
}
private write(level: keyof typeof LogLevel, ...args: unknown[]): void {
let prefix = this.prefix;
if (this.showLevel) {
prefix = `- ${level} ${prefix}`;
}
if (level === LogLevel.ERROR) {
console.error(prefix, ...args);
} else {
console.log(prefix, ...args);
}
}
}
// This can be extended to create context specific logger (Server Action, Router Handler, etc.)
// to add context information (IP, User-Agent, timestamp, etc.)
export function createLogger({ prefix, level }: LoggerOptions = {}): Logger {
return new Logger({ prefix, level });
}