2022-05-19 14:13:57 +02:00

140 lines
3.9 KiB
TypeScript

import cluster from 'cluster';
import process from 'process';
import type { LogLevel } from './LogLevel';
export interface LogMetadata {
/** Is the current process the Primary process */
isPrimary: boolean;
/** The process id of the current process */
pid: number;
}
/**
* Logs messages on a specific level.
*
* @see getLoggerFor on how to instantiate loggers.
*/
export interface SimpleLogger {
/**
* Log the given message at the given level.
* If the internal level is higher than the given level, the message may be voided.
* @param level - The level to log at.
* @param message - The message to log.
* @param meta - Optional metadata to include in the log message.
*/
log: (level: LogLevel, message: string, meta?: LogMetadata) => SimpleLogger;
}
/**
* Logs messages, with convenience methods to log on a specific level.
*
* @see getLoggerFor on how to instantiate loggers.
*/
export interface Logger extends SimpleLogger {
/**
* Log the given message at the given level.
* If the internal level is higher than the given level, the message may be voided.
* @param level - The level to log at.
* @param message - The message to log.
* @param meta - Optional metadata to include in the log message.
*/
log: (level: LogLevel, message: string, meta?: LogMetadata) => Logger;
/**
* Log a message at the 'error' level.
* @param message - The message to log.
* @param meta - Optional metadata to include in the log message.
*/
error: (message: string) => Logger;
/**
* Log a message at the 'warn' level.
* @param message - The message to log.
* @param meta - Optional metadata to include in the log message.
*/
warn: (message: string) => Logger;
/**
* Log a message at the 'info' level.
* @param message - The message to log.
* @param meta - Optional metadata to include in the log message.
*/
info: (message: string) => Logger;
/**
* Log a message at the 'verbose' level.
* @param message - The message to log.
* @param meta - Optional metadata to include in the log message.
*/
verbose: (message: string) => Logger;
/**
* Log a message at the 'debug' level.
* @param message - The message to log.
* @param meta - Optional metadata to include in the log message.
*/
debug: (message: string) => Logger;
/**
* Log a message at the 'silly' level.
* @param message - The message to log.
* @param meta - Optional metadata to include in the log message.
*/
silly: (message: string) => Logger;
}
/**
* Base class that implements all additional {@link BaseLogger} methods,
* leaving only the implementation of {@link SimpleLogger}.
*/
export abstract class BaseLogger implements Logger {
public abstract log(level: LogLevel, message: string, meta?: LogMetadata): Logger;
private readonly getMeta = (): LogMetadata => ({
pid: process.pid,
isPrimary: cluster.isMaster,
});
public error(message: string): Logger {
return this.log('error', message, this.getMeta());
}
public warn(message: string): Logger {
return this.log('warn', message, this.getMeta());
}
public info(message: string): Logger {
return this.log('info', message, this.getMeta());
}
public verbose(message: string): Logger {
return this.log('verbose', message, this.getMeta());
}
public debug(message: string): Logger {
return this.log('debug', message, this.getMeta());
}
public silly(message: string): Logger {
return this.log('silly', message, this.getMeta());
}
}
/**
* Implements {@link BaseLogger} around a {@link SimpleLogger},
* which can be swapped out a runtime.
*/
export class WrappingLogger extends BaseLogger {
public logger: SimpleLogger;
public constructor(logger: SimpleLogger) {
super();
this.logger = logger;
}
public log(level: LogLevel, message: string, meta?: LogMetadata): this {
this.logger.log(level, message, meta);
return this;
}
}