UNPKG

@boost/log

Version:

Lightweight level based logging system.

105 lines (88 loc) 2.57 kB
import os from 'node:os'; import util from 'node:util'; import { Contract } from '@boost/common'; import type { Blueprint, Schemas } from '@boost/common/optimal'; import { env } from '@boost/internal'; import { DEFAULT_LABELS, LOG_LEVELS } from './constants'; import { debug } from './debug'; import { Transport } from './Transport'; import { ConsoleTransport } from './transports/ConsoleTransport'; import type { LoggerOptions, LogLevel, LogOptions, Transportable } from './types'; export class Logger extends Contract<LoggerOptions> { protected silent: boolean = false; constructor(options: LoggerOptions) { super(options); const defaultLevel = env('LOG_DEFAULT_LEVEL'); const maxLevel = env('LOG_MAX_LEVEL'); debug( 'New logger "%s" created: %s %s', this.options.name, defaultLevel ? `${defaultLevel} level` : 'all levels', maxLevel ? `(max ${maxLevel})` : '', ); } blueprint(schemas: Schemas): Blueprint<LoggerOptions> { const { array, instance, object, string } = schemas; return { labels: object().of(string()), metadata: object(), name: string().required().notEmpty(), transports: array([new ConsoleTransport()]).of( instance().of<Transportable>(Transport).notNullable(), ), }; } /** * Disable all logger messages from logging to the console. */ disable() { debug('Logger %s disabled', this.options.name); this.silent = true; } /** * Enable all logger messages to log the console. */ enable() { debug('Logger %s enabled', this.options.name); this.silent = false; } isAllowed(level: LogLevel, maxLevel?: LogLevel): boolean { if (!maxLevel) { return true; } for (const currentLevel of LOG_LEVELS) { if (currentLevel === level) { return true; } if (currentLevel === maxLevel) { break; } } return false; } log(options: LogOptions) { const { args = [], level, message, metadata = {} } = options; const logLevel = level ?? env('LOG_DEFAULT_LEVEL') ?? 'log'; if (this.silent || !this.isAllowed(logLevel, env('LOG_MAX_LEVEL'))) { return; } const item = { host: os.hostname(), label: this.options.labels[logLevel] ?? DEFAULT_LABELS[logLevel] ?? '', level: logLevel, message: util.format(message, ...args), metadata: { ...this.options.metadata, ...metadata, }, name: this.options.name, pid: process.pid, time: new Date(), }; this.options.transports.forEach((transport) => { if (transport.levels.includes(item.level)) { void transport.write(transport.format(item), item); } }); } }