diff options
Diffstat (limited to 'std/log/handlers.ts')
m--------- | std | 0 | ||||
-rw-r--r-- | std/log/handlers.ts | 120 |
2 files changed, 120 insertions, 0 deletions
diff --git a/std b/std deleted file mode 160000 -Subproject 43aafbf33285753e7b42230f0eb7969b300f71c diff --git a/std/log/handlers.ts b/std/log/handlers.ts new file mode 100644 index 000000000..5dfd0caa4 --- /dev/null +++ b/std/log/handlers.ts @@ -0,0 +1,120 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +const { open } = Deno; +type File = Deno.File; +type Writer = Deno.Writer; +import { getLevelByName, LogLevel } from "./levels.ts"; +import { LogRecord } from "./logger.ts"; +import { red, yellow, blue, bold } from "../fmt/colors.ts"; + +const DEFAULT_FORMATTER = "{levelName} {msg}"; +type FormatterFunction = (logRecord: LogRecord) => string; + +interface HandlerOptions { + formatter?: string | FormatterFunction; +} + +export class BaseHandler { + level: number; + levelName: string; + formatter: string | FormatterFunction; + + constructor(levelName: string, options: HandlerOptions = {}) { + this.level = getLevelByName(levelName); + this.levelName = levelName; + + this.formatter = options.formatter || DEFAULT_FORMATTER; + } + + handle(logRecord: LogRecord): void { + if (this.level > logRecord.level) return; + + const msg = this.format(logRecord); + return this.log(msg); + } + + format(logRecord: LogRecord): string { + if (this.formatter instanceof Function) { + return this.formatter(logRecord); + } + + return this.formatter.replace( + /{(\S+)}/g, + (match, p1): string => { + const value = logRecord[p1 as keyof LogRecord]; + + // do not interpolate missing values + if (!value) { + return match; + } + + return String(value); + } + ); + } + + log(_msg: string): void {} + async setup(): Promise<void> {} + async destroy(): Promise<void> {} +} + +export class ConsoleHandler extends BaseHandler { + format(logRecord: LogRecord): string { + let msg = super.format(logRecord); + + switch (logRecord.level) { + case LogLevel.INFO: + msg = blue(msg); + break; + case LogLevel.WARNING: + msg = yellow(msg); + break; + case LogLevel.ERROR: + msg = red(msg); + break; + case LogLevel.CRITICAL: + msg = bold(red(msg)); + break; + default: + break; + } + + return msg; + } + + log(msg: string): void { + console.log(msg); + } +} + +export abstract class WriterHandler extends BaseHandler { + protected _writer!: Writer; + private _encoder = new TextEncoder(); + + log(msg: string): void { + this._writer.write(this._encoder.encode(msg + "\n")); + } +} + +interface FileHandlerOptions extends HandlerOptions { + filename: string; +} + +export class FileHandler extends WriterHandler { + private _file!: File; + private _filename: string; + + constructor(levelName: string, options: FileHandlerOptions) { + super(levelName, options); + this._filename = options.filename; + } + + async setup(): Promise<void> { + // open file in append mode - write only + this._file = await open(this._filename, "a"); + this._writer = this._file; + } + + async destroy(): Promise<void> { + await this._file.close(); + } +} |