-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
279 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** | ||
* @typedef {enum} LogLevel Enum containing the different levels of | ||
* potential logger output. Each level represents itself and everything | ||
* above it in the enum. The default logger log level is `LogLevel.LOG` | ||
* ``` | ||
* enum LogLevel | ||
* { | ||
* NONE, | ||
* LOG, | ||
* INFO, | ||
* WARN, | ||
* ERROR. | ||
* DEBUG | ||
* } | ||
* ``` | ||
*/ | ||
export enum LogLevel | ||
{ | ||
NONE, | ||
LOG, | ||
INFO, | ||
WARN, | ||
ERROR, | ||
DEBUG | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import { LogLevel } from '../../types/LogLevel'; | ||
export { logger } from './LoggerDecorator'; | ||
import * as chalk from 'chalk'; | ||
|
||
/** | ||
* Singleton containing methods for asynchronous logging with clean, | ||
* configurable output | ||
* | ||
* Easiest manner of use is via the `@logger` parameter decorator | ||
* to attach the logger to a class property for use within that class. | ||
* Otherwise the singleton instance can be accessed via `Logger.instance()` | ||
* | ||
* Logging can be turned off by setting the logging level to `LogLevel.NONE` | ||
*/ | ||
export class Logger | ||
{ | ||
private static _instance: Logger; | ||
private _logLevel: LogLevel; | ||
private constructor() | ||
{ | ||
if (Logger._instance) | ||
throw new Error('Cannot create multiple instances of Logger singleton'); | ||
Logger._instance = this; | ||
this._logLevel = 1; | ||
} | ||
|
||
/** | ||
* `LogLevel.NONE` enum shortcut | ||
* @name Logger.NONE | ||
* @type {LogLevel} | ||
*/ | ||
public static readonly NONE: LogLevel = LogLevel.NONE; | ||
|
||
/** | ||
* `LogLevel.LOG` enum shortcut | ||
* @name Logger.LOG | ||
* @type {LogLevel} | ||
*/ | ||
public static readonly LOG: LogLevel = LogLevel.LOG; | ||
|
||
/** | ||
* `LogLevel.INFO` enum shortcut | ||
* @name Logger.INFO | ||
* @type LogLevel | ||
*/ | ||
public static readonly INFO: LogLevel = LogLevel.INFO; | ||
|
||
/** | ||
* `LogLevel.WARN` enum shortcut | ||
* @name Logger.WARN | ||
* @type {LogLevel} | ||
*/ | ||
public static readonly WARN: LogLevel = LogLevel.WARN; | ||
|
||
/** | ||
* `LogLevel.ERROR` enum shortcut | ||
* @name Logger.ERROR | ||
* @type {LogLevel} | ||
*/ | ||
public static readonly ERROR: LogLevel = LogLevel.ERROR; | ||
|
||
/** | ||
* `LogLevel.DEBUG` enum shortcut | ||
* @name Logger.DEBUG | ||
* @type LogLevel | ||
*/ | ||
public static readonly DEBUG: LogLevel = LogLevel.DEBUG; | ||
|
||
/** | ||
* Returns the Logger singleton instance | ||
* @method Logger.instance | ||
* @returns {Logger} | ||
*/ | ||
public static instance(): Logger | ||
{ | ||
if (!Logger._instance) return new Logger(); | ||
else return Logger._instance; | ||
} | ||
|
||
/** | ||
* Set the level of output that will be logged | ||
* @method Logger#setLogLevel | ||
* @param {LogLevel} level The level of logging to output | ||
*/ | ||
public setLogLevel(level: LogLevel): void | ||
{ | ||
this._logLevel = level; | ||
} | ||
|
||
/** | ||
* Log to the console. This is the base level of logging and is the default | ||
* log level, represented by `LogLevel.LOG`, when the logger singleton is created | ||
* @method Logger#log | ||
* @param {string} tag Tag to prefix the log with | ||
* @param {...string} text String(s) to log | ||
*/ | ||
public async log(tag: string, ...text: string[]): Promise<void> | ||
{ | ||
if (this._logLevel < LogLevel.LOG) return; | ||
this._write(chalk.green('LOG'), tag, text.join(' ')); | ||
} | ||
|
||
/** | ||
* Log information that doesn't need to be visible by default to the console. | ||
* Will not be logged unless the logging level is `LogLevel.INFO` or higher | ||
* @method Logger#info | ||
* @param {string} tag Tag to prefix the log with | ||
* @param {...string} text String(s) to log | ||
*/ | ||
public async info(tag: string, ...text: string[]): Promise<void> | ||
{ | ||
if (this._logLevel < LogLevel.INFO) return; | ||
this._write(chalk.blue('INFO'), tag, text.join(' ')); | ||
} | ||
|
||
/** | ||
* Log warning text to the console. | ||
* Will not be logged unless the logging level is `LogLevel.WARN` or higher | ||
* @method Logger#warn | ||
* @param {string} tag Tag to prefix the log with | ||
* @param {...string} text String(s) to log | ||
*/ | ||
public async warn(tag: string, ...text: string[]): Promise<void> | ||
{ | ||
if (this._logLevel < LogLevel.WARN) return; | ||
this._write(chalk.yellow('WARN'), tag, text.join(' ')); | ||
} | ||
|
||
/** | ||
* Log error text to the console. | ||
* Will not be logged unless the logging level is `LogLevel.ERROR` or higher | ||
* @method Logger#error | ||
* @param {string} tag Tag to prefix the log with | ||
* @param {...string} text String(s) to log | ||
*/ | ||
public async error(tag: string, ...text: string[]): Promise<void> | ||
{ | ||
if (this._logLevel < LogLevel.ERROR) return; | ||
this._write(chalk.red('ERROR'), tag, text.join(' ')); | ||
} | ||
|
||
/** | ||
* Log error text to the console. | ||
* Will not be logged unless the logging level is `LogLevel.ERROR` or higher | ||
* @method Logger#error | ||
* @param {string} tag Tag to prefix the log with | ||
* @param {...string} text String(s) to log | ||
*/ | ||
public async debug(tag: string, ...text: string[]): Promise<void> | ||
{ | ||
if (this._logLevel < LogLevel.DEBUG) return; | ||
this._write(chalk.magenta('DEBUG'), tag, text.join(' ')); | ||
} | ||
|
||
/** | ||
* Write to the console | ||
* @private | ||
*/ | ||
private _write(type: string, tag: string, text: string): void | ||
{ | ||
const d: Date = new Date(); | ||
const hours: number = d.getHours(); | ||
const minutes: number = d.getMinutes(); | ||
const seconds: number = d.getSeconds(); | ||
const timestamp: string = `${ | ||
hours < 10 ? `0${hours}` : hours}:${ | ||
minutes < 10 ? `0${minutes}` : minutes}:${ | ||
seconds < 10 ? `0${seconds}` : seconds}`; | ||
|
||
process.stdout.write(`[${chalk.grey(timestamp)}][${type}][${chalk.cyan(tag)}]: ${text}\n`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { Logger } from './Logger'; | ||
|
||
/** | ||
* Represents a type that has a `logger` property | ||
* containing the Logger singleton instance | ||
*/ | ||
// export type Loggable<T> = T & { logger: Logger }; | ||
|
||
/** | ||
* Class decorator that transforms a class to Loggable<T>. | ||
* Regrettably works but is not properly picked up by intellisense | ||
* at this point in time, meaning compiler errors when attempting | ||
* to access the `logger` property on the decorated class. | ||
* Maybe someday. | ||
* | ||
* Example: | ||
* ``` | ||
* @loggable | ||
* class Foo { } | ||
* ``` | ||
*/ | ||
// export function loggable<T extends Function>(target: T): Loggable<T> | ||
// { | ||
// Object.defineProperty(target.prototype, 'logger', | ||
// { value: Logger.instance }); | ||
// return <Loggable<T>> target; | ||
// } | ||
|
||
/** | ||
* Property decorator that will automatically assign | ||
* the Logger singleton instance to the decorated | ||
* class property | ||
* | ||
* Example: | ||
* ``` | ||
* class Foo { | ||
* @logger private logger: Logger; | ||
* ... | ||
* ``` | ||
* **Note:** This is a Typescript feature. If using the logger is desired | ||
* in Javascript you should simply retrieve the singleton instance via | ||
* `Logger.instance()` | ||
*/ | ||
export function logger<T>(target: T, key: string): void | ||
{ | ||
Object.defineProperty(target, 'logger', | ||
{ value: Logger.instance() }); | ||
} |
Oops, something went wrong.