diff options
author | Paul Thompson <paul.thompson773@gmail.com> | 2020-07-06 13:57:31 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-05 23:57:31 -0400 |
commit | c3c13351a9f26f2209b51b8ded5e8f2a1ad86e94 (patch) | |
tree | 9e7439974e4383ae0f0b1868a1be53ef497fcf6d | |
parent | d1289db1c34b983126ce2e8e4758091e926b4630 (diff) |
std/log - Expose Logger type and improve public interface for get & set log levels (#6617)
-rw-r--r-- | std/log/logger.ts | 43 | ||||
-rw-r--r-- | std/log/mod.ts | 3 | ||||
-rw-r--r-- | std/log/mod_test.ts | 133 |
3 files changed, 166 insertions, 13 deletions
diff --git a/std/log/logger.ts b/std/log/logger.ts index 004088d9a..05e83dc77 100644 --- a/std/log/logger.ts +++ b/std/log/logger.ts @@ -43,22 +43,43 @@ export interface LoggerOptions { } export class Logger { - level: number; - levelName: LevelName; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - handlers: any[]; - loggerName: string; + #level: LogLevels; + #handlers: BaseHandler[]; + readonly #loggerName: string; constructor( loggerName: string, levelName: LevelName, options: LoggerOptions = {} ) { - this.loggerName = loggerName; - this.level = getLevelByName(levelName); - this.levelName = levelName; + this.#loggerName = loggerName; + this.#level = getLevelByName(levelName); + this.#handlers = options.handlers || []; + } + + get level(): LogLevels { + return this.#level; + } + set level(level: LogLevels) { + this.#level = level; + } - this.handlers = options.handlers || []; + get levelName(): LevelName { + return getLevelName(this.#level); + } + set levelName(levelName: LevelName) { + this.#level = getLevelByName(levelName); + } + + get loggerName(): string { + return this.#loggerName; + } + + set handlers(hndls: BaseHandler[]) { + this.#handlers = hndls; + } + get handlers(): BaseHandler[] { + return this.#handlers; } /** If the level of the logger is greater than the level to log, then nothing @@ -68,7 +89,7 @@ export class Logger { * 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>( + private _log<T>( level: number, msg: (T extends Function ? never : T) | (() => T), ...args: unknown[] @@ -92,7 +113,7 @@ export class Logger { loggerName: this.loggerName, }); - this.handlers.forEach((handler): void => { + this.#handlers.forEach((handler): void => { handler.handle(record); }); diff --git a/std/log/mod.ts b/std/log/mod.ts index a1a863d4a..ed94725c4 100644 --- a/std/log/mod.ts +++ b/std/log/mod.ts @@ -10,7 +10,8 @@ import { import { assert } from "../_util/assert.ts"; import { LevelName } from "./levels.ts"; -export { LogLevels } from "./levels.ts"; +export { LogLevels, LevelName } from "./levels.ts"; +export { Logger } from "./logger.ts"; export class LoggerConfig { level?: LevelName; diff --git a/std/log/mod_test.ts b/std/log/mod_test.ts index 9de5d76af..30c6b0914 100644 --- a/std/log/mod_test.ts +++ b/std/log/mod_test.ts @@ -8,8 +8,10 @@ import { error, critical, setup, + Logger, + LogLevels, + LevelName, } from "./mod.ts"; -import { Logger } from "./logger.ts"; import { BaseHandler } from "./handlers.ts"; class TestHandler extends BaseHandler { @@ -89,3 +91,132 @@ Deno.test({ assertEquals(anotherConsoleHandler.messages[0], "[tasks] ERROR world"); }, }); + +Deno.test({ + name: "Loggers have level and levelName to get/set loglevels", + async fn() { + const testHandler = new TestHandler("DEBUG"); + await setup({ + handlers: { + test: testHandler, + }, + + loggers: { + // configure default logger available via short-hand methods above + default: { + level: "DEBUG", + handlers: ["test"], + }, + }, + }); + const logger: Logger = getLogger(); + assertEquals(logger.levelName, "DEBUG"); + assertEquals(logger.level, LogLevels.DEBUG); + + logger.debug("debug"); + logger.error("error"); + logger.critical("critical"); + assertEquals(testHandler.messages.length, 3); + assertEquals(testHandler.messages[0], "DEBUG debug"); + assertEquals(testHandler.messages[1], "ERROR error"); + assertEquals(testHandler.messages[2], "CRITICAL critical"); + + testHandler.messages = []; + logger.level = LogLevels.WARNING; + assertEquals(logger.levelName, "WARNING"); + assertEquals(logger.level, LogLevels.WARNING); + + logger.debug("debug2"); + logger.error("error2"); + logger.critical("critical2"); + assertEquals(testHandler.messages.length, 2); + assertEquals(testHandler.messages[0], "ERROR error2"); + assertEquals(testHandler.messages[1], "CRITICAL critical2"); + + testHandler.messages = []; + const setLevelName: LevelName = "CRITICAL"; + logger.levelName = setLevelName; + assertEquals(logger.levelName, "CRITICAL"); + assertEquals(logger.level, LogLevels.CRITICAL); + + logger.debug("debug3"); + logger.error("error3"); + logger.critical("critical3"); + assertEquals(testHandler.messages.length, 1); + assertEquals(testHandler.messages[0], "CRITICAL critical3"); + }, +}); + +Deno.test({ + name: "Loggers have loggerName to get logger name", + async fn() { + const testHandler = new TestHandler("DEBUG"); + await setup({ + handlers: { + test: testHandler, + }, + + loggers: { + namedA: { + level: "DEBUG", + handlers: ["test"], + }, + namedB: { + level: "DEBUG", + handlers: ["test"], + }, + }, + }); + + assertEquals(getLogger("namedA").loggerName, "namedA"); + assertEquals(getLogger("namedB").loggerName, "namedB"); + assertEquals(getLogger().loggerName, "default"); + assertEquals(getLogger("nonsetupname").loggerName, "nonsetupname"); + }, +}); + +Deno.test({ + name: "Logger has mutable handlers", + async fn() { + const testHandlerA = new TestHandler("DEBUG"); + const testHandlerB = new TestHandler("DEBUG"); + await setup({ + handlers: { + testA: testHandlerA, + testB: testHandlerB, + }, + + loggers: { + default: { + level: "DEBUG", + handlers: ["testA"], + }, + }, + }); + const logger: Logger = getLogger(); + logger.info("msg1"); + assertEquals(testHandlerA.messages.length, 1); + assertEquals(testHandlerA.messages[0], "INFO msg1"); + assertEquals(testHandlerB.messages.length, 0); + + logger.handlers = [testHandlerA, testHandlerB]; + + logger.info("msg2"); + assertEquals(testHandlerA.messages.length, 2); + assertEquals(testHandlerA.messages[1], "INFO msg2"); + assertEquals(testHandlerB.messages.length, 1); + assertEquals(testHandlerB.messages[0], "INFO msg2"); + + logger.handlers = [testHandlerB]; + + logger.info("msg3"); + assertEquals(testHandlerA.messages.length, 2); + assertEquals(testHandlerB.messages.length, 2); + assertEquals(testHandlerB.messages[1], "INFO msg3"); + + logger.handlers = []; + logger.info("msg4"); + assertEquals(testHandlerA.messages.length, 2); + assertEquals(testHandlerB.messages.length, 2); + }, +}); |