@nowarajs/logger
Version:
Type-safe logging library for Bun with advanced TypeScript body intersection, modular sink pattern, transform streams, and immutable API design.
190 lines (189 loc) • 7.04 kB
TypeScript
import { TypedEventEmitter } from '@nowarajs/typed-event-emitter';
import type { LoggerEvent } from './events/logger-events';
import type { BodiesIntersection } from './types/bodies-intersection';
import type { LoggerSink } from './types/logger-sink';
import type { SinkMap } from './types/sink-map';
/**
* Logger provides a flexible, type-safe logging system that allows multiple sinks for log output.
* The logger uses a transform stream to process log entries and execute the logging sinks.
*
* Logger extends the TypedEventEmitter class to emit typed events when an error occurs or when the logger ends.
* The logger can log messages with different levels: error, warn, info, debug, and log.
*
* @template TSinks - The map of sink names to LoggerStrategy types.
*/
export declare class Logger<TSinks extends SinkMap = {}> extends TypedEventEmitter<LoggerEvent> {
/**
* The map of sinks.
*/
private readonly _sinks;
/**
* The transform stream for processing log entries.
*/
private readonly _logStream;
/**
* The queue of pending log entries.
*/
private readonly _pendingLogs;
/**
* The maximum number of pending logs.
* @defaultValue 10_000
*/
private readonly _maxPendingLogs;
/**
* Flag to indicate if the logger is currently writing logs.
*/
private _isWriting;
/**
* Construct a Logger.
*
* @template TStrategies - The map of sink names to LoggerStrategy types.
*
* @param sinks - Initial sinks map.
*
* @param maxPendingLogs - Maximum number of logs in the queue (default: 10_000)
*/
constructor(sinks?: TSinks, maxPendingLogs?: number);
/**
* Register a new logging sink.
*
* @template Key - The name of the sink.
* @template Sink - The sink type.
*
* @param name - The name of the sink.
* @param sink - The sink to add. It must implement {@link LoggerSink}.
*
* @throws ({@link BaseError}) - If the sink is already added.
*
* @returns A new Logger instance with the added sink.
*/
registerSink<Key extends string, Sink extends LoggerSink>(name: Key, sink: Sink): Logger<TSinks & Record<Key, Sink>>;
/**
* Unregister a logging sink.
*
* @template Key - The name of the sink.
*
* @param name - The name of the sink to remove.
*
* @throws ({@link BaseError}) - If the sink is not found.
*
* @returns A new Logger instance without the removed sink.
*/
unregisterSink<Key extends keyof TSinks>(name: Key): Logger<Omit<TSinks, Key>>;
/**
* Register multiple sinks at once.
*
* @template TNew - The new sinks to add.
*
* @param sinks - An array of tuples where each tuple contains the sink name and the sink instance.
*
* @throws ({@link BaseError}) - If any sink is already added.
*
* @returns A new Logger instance with the added sinks.
*/
registerSinks<TNew extends [string, LoggerSink][] = [string, LoggerSink][]>(sinks: TNew): Logger<TSinks & {
[K in TNew[number][0]]: Extract<TNew[number], [K, LoggerSink]>[1];
}>;
/**
* Unregister multiple sinks at once.
*
* @template Keys - The names of the sinks to remove.
*
* @param names - An array of sink names to remove.
*
* @throws ({@link BaseError}) - If any sink is not found.
*
* @returns A new Logger instance without the removed sinks.
*/
unregisterSinks<Keys extends Extract<keyof TSinks, string>>(names: Keys[]): Logger<Omit<TSinks, Keys>>;
/**
* Remove all sinks.
*
* @returns A new Logger instance without any sinks.
*/
clearSinks(): Logger;
/**
* Log an error message.
*
* @template SNames - The names of the sinks to use.
*
* @param object - The object to log.
* @param sinksNames - The names of the sinks to use. If not provided, all sinks will be used.
*
* @throws ({@link BaseError}) - If no sink is added.
*/
error<SNames extends (keyof TSinks)[] = (keyof TSinks)[]>(object: BodiesIntersection<TSinks, SNames[number]>, sinksNames?: SNames): void;
/**
* Log a warning message.
*
* @template SNames - The names of the sinks to use.
*
* @param object - The object to log.
* @param sinksNames - The names of the sinks to use. If not provided, all sinks will be used.
*
* @throws ({@link BaseError}) - If no sink is added.
*/
warn<SNames extends (keyof TSinks)[] = (keyof TSinks)[]>(object: BodiesIntersection<TSinks, SNames[number]>, sinksNames?: SNames): void;
/**
* Log an info message.
*
* @template SNames - The names of the sinks to use.
*
* @param object - The object to log.
* @param sinksNames - The names of the sinks to use. If not provided, all sinks will be used.
*
* @throws ({@link BaseError}) - If no sink is added.
*/
info<SNames extends (keyof TSinks)[] = (keyof TSinks)[]>(object: BodiesIntersection<TSinks, SNames[number]>, sinksNames?: SNames): void;
/**
* Log a debug message.
*
* @template SNames - The names of the sinks to use.
*
* @param object - The object to log.
* @param sinksNames - The names of the sinks to use. If not provided, all sinks will be used.
*
* @throws ({@link BaseError}) - If no sink is added.
*/
debug<SNames extends (keyof TSinks)[] = (keyof TSinks)[]>(object: BodiesIntersection<TSinks, SNames[number]>, sinksNames?: SNames): void;
/**
* Log a generic message.
*
* @template SNames - The names of the sinks to use.
*
* @param object - The object to log.
* @param sinksNames - The names of the sinks to use. If not provided, all sinks will be used.
*
* @throws ({@link BaseError}) - If no sink is added.
*/
log<SNames extends (keyof TSinks)[] = (keyof TSinks)[]>(object: BodiesIntersection<TSinks, SNames[number]>, sinksNames?: SNames): void;
/**
* Internal: execute all sinks for a log event.
*
* @template TLogObject - The type of the log object.
*
* @param level - The log level.
* @param date - The date of the log event.
* @param object - The object to log.
* @param sinksNames - The names of the sinks to use. If not provided, all sinks will be used.
*
* @throws ({@link BaseError}) - If a sink throws.
*/
private _executeStrategies;
/**
* Internal: queue a log event and start writing if not already.
*
* @template TLogObject - The type of the log object.
*
* @param level - The log level.
* @param object - The object to log.
* @param sinksNames - The names of the sinks to use. If not provided, all sinks will be used.
*
* @throws ({@link BaseError}) - If no sink is added.
*/
private _out;
/**
* Internal: process the log queue and emit 'end' when done.
*/
private _writeLog;
}