@triviality/logger
v1.1.6
Published
Typescript loggers with an interface that support composition
Downloads
23
Maintainers
Readme
Table of Contents
Installation
To install the stable version:
yarn add @triviality/logger
This assumes you are using yarn as your package manager.
or
npm install @triviality/logger
Triviality logger
Exposes TypeScript Logger interface compatible with:
- Web and node
- ts-log interface
- node-bunyan node-bunyan
- Compatible with triviality ServiceContainer. Pre-configured logger modules, ready to use in your Triviality modules.
- Add composition functionality for combing loggers
LoggerInterface
Besides the normal log functions each logger has it's log function. The log function that support logging based on LogLevel. Can be used for easy composition.
export enum LogLevel {
trace,
debug,
info,
warn,
error,
}
export interface LoggerInterface {
trace(message?: any, ...optionalParams: any[]): void;
debug(message?: any, ...optionalParams: any[]): void;
info(message?: any, ...optionalParams: any[]): void;
warn(message?: any, ...optionalParams: any[]): void;
error(message?: any, ...optionalParams: any[]): void;
log(level: LogLevel, message: any, ...optionalParams: any[]): void;
}
Example log level
import { ConsoleLogger } from '@triviality/logger';
import { LogLevel } from '@triviality/logger';
const logger = new ConsoleLogger(console);
logger.log(LogLevel.info, 'Hallo', 'World');
./node_modules/.bin/ts-node example/logLevel.ts
Hallo World
Loggers
console logger
import { ConsoleLogger } from '@triviality/logger';
const logger = new ConsoleLogger(console);
logger.info('Hallo', 'World');
logger.info('Bye %s', 'World');
./node_modules/.bin/ts-node example/consoleLogger.ts
Hallo World
Bye World
process logger
import { ProcessLogger } from '@triviality/logger';
const logger = new ProcessLogger(process);
logger.info('Hallo', 'World');
./node_modules/.bin/ts-node example/processLogger.ts
Hallo World
prefix logger
import { ConsoleLogger } from '@triviality/logger';
import { PrefixLogger } from '@triviality/logger';
const logger = new ConsoleLogger(console);
const withPrefix = new PrefixLogger(logger, 'Hallo: ');
withPrefix.info('World');
./node_modules/.bin/ts-node example/prefixLogger.ts
Hallo: World
log from LogLevel logger
import { ConsoleLogger } from '@triviality/logger';
import { FromLogLevelLogger } from '@triviality/logger';
import { LogLevel } from '@triviality/logger';
const logger = new ConsoleLogger(console);
const witPrefix = new FromLogLevelLogger(logger, LogLevel.info);
witPrefix.trace('This will be ignored');
witPrefix.info('Hallo!');
./node_modules/.bin/ts-node example/fromLogLevelLogger.ts
Hallo!
ts-log logger
With this you can also wrap node-bunyan
import { TsLogLogger } from '@triviality/logger';
import { Logger } from 'ts-log';
const tsLogger: Logger = console;
const logger = new TsLogLogger(tsLogger);
logger.info('Hallo', 'World');
./node_modules/.bin/ts-node example/tsLogLogger.ts
Hallo World
null logger
import { NullLogger } from '@triviality/logger';
const logger = new NullLogger();
logger.info('Hallo', 'Void');
collection of loggers
Combine loggers into a single one.
import { CollectionLogger } from '@triviality/logger';
import { ConsoleLogger } from '@triviality/logger';
import { PrefixLogger } from '@triviality/logger';
const consoleLogger = new ConsoleLogger(console);
const logger = new CollectionLogger([
new PrefixLogger(consoleLogger, 'Hallo '),
new PrefixLogger(consoleLogger, 'Bye '),
]);
logger.info('World');
./node_modules/.bin/ts-node example/collectionLogger.ts
Hallo World
Bye World
Abstract logger class
You can extends one of the abstract logger, so you only need to implement some of the log function.
import { LoggerInterface, LogLevel } from './LoggerInterface';
export abstract class AbstractLogLevelLogger implements LoggerInterface {
public trace(message?: any, ...optionalParams: any[]): void {
this.log(LogLevel.trace, message, ...optionalParams);
}
public debug(message?: any, ...optionalParams: any[]): void {
this.log(LogLevel.debug, message, ...optionalParams);
}
public info(message?: any, ...optionalParams: any[]): void {
this.log(LogLevel.info, message, ...optionalParams);
}
public warn(message?: any, ...optionalParams: any[]): void {
this.log(LogLevel.warn, message, ...optionalParams);
}
public error(message?: any, ...optionalParams: any[]): void {
this.log(LogLevel.error, message, ...optionalParams);
}
public abstract log(type: LogLevel, message?: any, ...optionalParams: any[]): void;
}
import { LoggerInterface, LogLevel } from './LoggerInterface';
export abstract class AbstractFunctionLogger implements LoggerInterface {
public abstract trace(message?: any, ...optionalParams: any[]): void;
public abstract debug(message?: any, ...optionalParams: any[]): void;
public abstract info(message?: any, ...optionalParams: any[]): void;
public abstract warn(message?: any, ...optionalParams: any[]): void;
public abstract error(message?: any, ...optionalParams: any[]): void;
public log(level: LogLevel, message?: any, ...optionalParams: any[]): void {
switch (level) {
case LogLevel.trace:
this.trace(message, ...optionalParams);
break;
case LogLevel.debug:
this.debug(message, ...optionalParams);
break;
case LogLevel.info:
this.info(message, ...optionalParams);
break;
case LogLevel.warn:
this.warn(message, ...optionalParams);
break;
case LogLevel.error:
this.error(message, ...optionalParams);
break;
default:
throw new Error(`Log level "${level}" not supported`);
}
}
}
Jest test logger
Logger with jest spies for each particular log function.
import { LoggerInterface } from './LoggerInterface';
import { AbstractFunctionLogger } from './AbstractFunctionLogger';
export class JestTestLogger extends AbstractFunctionLogger implements LoggerInterface {
public trace = jest.fn();
public info = jest.fn();
public warn = jest.fn();
public debug = jest.fn();
public error = jest.fn();
public mockReset() {
this.trace.mockReset();
this.info.mockReset();
this.warn.mockReset();
this.debug.mockReset();
this.error.mockReset();
}
}
triviality features
Logger reference module, so you can reference your module to a non-concrete implementation.
import { Feature } from '@triviality/core';
import { LoggerInterface } from '../LoggerInterface';
abstract class LoggerFeature implements Feature {
public abstract logger(): LoggerInterface;
}
export { LoggerFeature };
For example you reference the logger module like:
import { Container, Feature } from '@triviality/core';
import { LoggerFeature } from '@triviality/logger';
import { HalloService } from './HalloService';
export class MyFeature implements Feature {
constructor(private container: Container<LoggerFeature>) {
}
public halloService() {
return new HalloService(this.container.logger());
}
}
And build the container like:
import { ContainerFactory } from '@triviality/core';
import { DefaultLoggerFeature } from '@triviality/logger';
import { MyFeature } from './Feature/MyFeature';
ContainerFactory
.create()
.add(DefaultLoggerFeature)
.add(MyFeature)
.build()
.then((container) => {
container.halloService().printHallo('Jane');
});
./node_modules/.bin/ts-node example/defaultLoggerFeature.ts
03/11/2019 9:47:48 AM:Hallo Jane
Thanks
Special thanks to:
- Eric Pinxteren