summaryrefslogtreecommitdiff
path: root/std/log/logger.ts
diff options
context:
space:
mode:
Diffstat (limited to 'std/log/logger.ts')
-rw-r--r--std/log/logger.ts92
1 files changed, 79 insertions, 13 deletions
diff --git a/std/log/logger.ts b/std/log/logger.ts
index 6a12325e8..78599da91 100644
--- a/std/log/logger.ts
+++ b/std/log/logger.ts
@@ -42,33 +42,99 @@ export class Logger {
this.handlers = handlers || [];
}
- _log(level: number, msg: string, ...args: unknown[]): void {
- if (this.level > level) return;
+ /** If the level of the logger is greater than the level to log, then nothing
+ * is logged, otherwise a log record is passed to each log handler. `msg` data
+ * passed in is returned. If a function is passed in, it is only evaluated
+ * if the msg will be logged and the return value will be the result of the
+ * function, not the function itself, unless the function isn't called, in which
+ * case undefined is returned. All types are coerced to strings for logging.
+ */
+ _log<T>(
+ level: number,
+ msg: (T extends Function ? never : T) | (() => T),
+ ...args: unknown[]
+ ): T | undefined {
+ if (this.level > level) {
+ return msg instanceof Function ? undefined : msg;
+ }
- const record: LogRecord = new LogRecord(msg, args, level);
+ let fnResult: T | undefined;
+ let logMessage: string;
+ if (msg instanceof Function) {
+ fnResult = msg();
+ logMessage = this.asString(fnResult);
+ } else {
+ logMessage = this.asString(msg);
+ }
+ const record: LogRecord = new LogRecord(logMessage, args, level);
this.handlers.forEach((handler): void => {
handler.handle(record);
});
+
+ return msg instanceof Function ? fnResult : msg;
+ }
+
+ asString(data: unknown): string {
+ if (typeof data === "string") {
+ return data;
+ } else if (
+ data === null ||
+ typeof data === "number" ||
+ typeof data === "bigint" ||
+ typeof data === "boolean" ||
+ typeof data === "undefined" ||
+ typeof data === "symbol"
+ ) {
+ return String(data);
+ } else if (typeof data === "object") {
+ return JSON.stringify(data);
+ }
+ return "undefined";
}
- debug(msg: string, ...args: unknown[]): void {
- this._log(LogLevels.DEBUG, msg, ...args);
+ debug<T>(msg: () => T, ...args: unknown[]): T | undefined;
+ debug<T>(msg: T extends Function ? never : T, ...args: unknown[]): T;
+ debug<T>(
+ msg: (T extends Function ? never : T) | (() => T),
+ ...args: unknown[]
+ ): T | undefined {
+ return this._log(LogLevels.DEBUG, msg, ...args);
}
- info(msg: string, ...args: unknown[]): void {
- this._log(LogLevels.INFO, msg, ...args);
+ info<T>(msg: () => T, ...args: unknown[]): T | undefined;
+ info<T>(msg: T extends Function ? never : T, ...args: unknown[]): T;
+ info<T>(
+ msg: (T extends Function ? never : T) | (() => T),
+ ...args: unknown[]
+ ): T | undefined {
+ return this._log(LogLevels.INFO, msg, ...args);
}
- warning(msg: string, ...args: unknown[]): void {
- this._log(LogLevels.WARNING, msg, ...args);
+ warning<T>(msg: () => T, ...args: unknown[]): T | undefined;
+ warning<T>(msg: T extends Function ? never : T, ...args: unknown[]): T;
+ warning<T>(
+ msg: (T extends Function ? never : T) | (() => T),
+ ...args: unknown[]
+ ): T | undefined {
+ return this._log(LogLevels.WARNING, msg, ...args);
}
- error(msg: string, ...args: unknown[]): void {
- this._log(LogLevels.ERROR, msg, ...args);
+ error<T>(msg: () => T, ...args: unknown[]): T | undefined;
+ error<T>(msg: T extends Function ? never : T, ...args: unknown[]): T;
+ error<T>(
+ msg: (T extends Function ? never : T) | (() => T),
+ ...args: unknown[]
+ ): T | undefined {
+ return this._log(LogLevels.ERROR, msg, ...args);
}
- critical(msg: string, ...args: unknown[]): void {
- this._log(LogLevels.CRITICAL, msg, ...args);
+ critical<T>(msg: () => T, ...args: unknown[]): T | undefined;
+ critical<T>(msg: T extends Function ? never : T, ...args: unknown[]): T;
+ critical<T>(
+ msg: (T extends Function ? never : T) | (() => T),
+ ...args: unknown[]
+ ): T | undefined {
+ return this._log(LogLevels.CRITICAL, msg, ...args);
}
}