@qlover/env-loader
Version:
A package for managing environment variables
1,510 lines (1,503 loc) • 42.6 kB
TypeScript
/**
* Represents a log event in the logging system
*
* This class encapsulates all information about a single log event,
* including the log level, message arguments, timestamp, logger name,
* and optional typed context data.
*
* Core features:
* - Automatic timestamp generation
* - Type-safe context support
* - Flexible argument handling
* - Logger identification
*
* @typeParam Ctx - Type of the context value, defaults to unknown
*
* @example Basic usage
* ```typescript
* const event = new LogEvent(
* 'info',
* ['Application started'],
* 'app'
* );
* // event.timestamp is automatically set
* console.log(event);
* ```
*
* @example With context
* ```typescript
* interface RequestContext {
* requestId: string;
* userId: string;
* path: string;
* }
*
* const event = new LogEvent<RequestContext>(
* 'info',
* ['Request processed', { duration: 150 }],
* 'http',
* new LogContext({
* requestId: 'req-123',
* userId: 'user-456',
* path: '/api/users'
* })
* );
* ```
*
* @example Error event
* ```typescript
* const error = new Error('Database connection failed');
* const event = new LogEvent(
* 'error',
* [
* 'Failed to connect to database',
* {
* error: error.message,
* stack: error.stack,
* code: 'DB_CONN_ERROR'
* }
* ],
* 'database'
* );
* ```
*
* @example Performance monitoring
* ```typescript
* interface PerformanceContext {
* operation: string;
* startTime: number;
* endTime: number;
* metadata: Record<string, unknown>;
* }
*
* const event = new LogEvent<PerformanceContext>(
* 'debug',
* ['Operation completed'],
* 'performance',
* new LogContext({
* operation: 'data-processing',
* startTime: 1679395845000,
* endTime: 1679395846000,
* metadata: {
* itemsProcessed: 1000,
* batchSize: 100,
* cacheHits: 850
* }
* })
* );
* ```
*/
declare class LogEvent<Ctx = unknown> {
/**
* Log level indicating the severity or importance
*
* Common values:
* - 'fatal': System is unusable
* - 'error': Error conditions
* - 'warn': Warning conditions
* - 'info': Informational messages
* - 'debug': Debug-level messages
* - 'trace': Trace-level messages
*
* @example
* ```typescript
* new LogEvent('error', ['Database connection failed'], 'db');
* ```
*/
level: string;
/**
* Array of log message arguments
*
* The first argument is typically the main message string,
* followed by optional data objects, error instances, or
* other relevant information.
*
* @example
* ```typescript
* // Simple message
* new LogEvent('info', ['User logged in'], 'auth');
*
* // Message with data
* new LogEvent('info', [
* 'User logged in',
* { userId: 123, role: 'admin' }
* ], 'auth');
*
* // Error with details
* new LogEvent('error', [
* 'Operation failed',
* new Error('Invalid input'),
* { operation: 'validate', input: data }
* ], 'validator');
* ```
*/
args: unknown[];
/**
* Name of the logger that created this event
*
* Used to identify the source or category of the log event.
* This can be a module name, service name, or any other
* identifier that helps categorize log events.
*
* @example
* ```typescript
* // Module-based names
* new LogEvent('info', ['Starting'], 'auth.service');
* new LogEvent('debug', ['Cache miss'], 'data.cache');
*
* // Component-based names
* new LogEvent('info', ['Render complete'], 'ui.dashboard');
* new LogEvent('error', ['API error'], 'api.users');
* ```
*/
loggerName: string;
/**
* Optional typed context data for the log event
*
* Provides additional structured data that can be used by
* formatters and handlers. The context type is controlled
* by the Ctx type parameter.
*
* @example
* ```typescript
* // Request context
* interface RequestContext {
* requestId: string;
* path: string;
* method: string;
* }
*
* new LogEvent<RequestContext>(
* 'info',
* ['Request received'],
* 'http',
* new LogContext({
* requestId: 'req-123',
* path: '/api/users',
* method: 'GET'
* })
* );
*
* // Performance context
* interface PerfContext {
* duration: number;
* memoryUsage: number;
* }
*
* new LogEvent<PerfContext>(
* 'debug',
* ['Operation completed'],
* 'perf',
* new LogContext({
* duration: 150,
* memoryUsage: process.memoryUsage().heapUsed
* })
* );
* ```
*/
context?: Ctx | undefined;
/**
* Timestamp when the log event was created
*
* Automatically set to the current time in milliseconds since the Unix epoch
* when the event is constructed. This ensures accurate timing information
* for each log entry.
*
* @example
* ```typescript
* const event = new LogEvent('info', ['message'], 'app');
* console.log(new Date(event.timestamp).toISOString());
* // Output: "2024-03-21T14:30:45.123Z"
* ```
*/
timestamp: number;
constructor(
/**
* Log level indicating the severity or importance
*
* Common values:
* - 'fatal': System is unusable
* - 'error': Error conditions
* - 'warn': Warning conditions
* - 'info': Informational messages
* - 'debug': Debug-level messages
* - 'trace': Trace-level messages
*
* @example
* ```typescript
* new LogEvent('error', ['Database connection failed'], 'db');
* ```
*/
level: string,
/**
* Array of log message arguments
*
* The first argument is typically the main message string,
* followed by optional data objects, error instances, or
* other relevant information.
*
* @example
* ```typescript
* // Simple message
* new LogEvent('info', ['User logged in'], 'auth');
*
* // Message with data
* new LogEvent('info', [
* 'User logged in',
* { userId: 123, role: 'admin' }
* ], 'auth');
*
* // Error with details
* new LogEvent('error', [
* 'Operation failed',
* new Error('Invalid input'),
* { operation: 'validate', input: data }
* ], 'validator');
* ```
*/
args: unknown[],
/**
* Name of the logger that created this event
*
* Used to identify the source or category of the log event.
* This can be a module name, service name, or any other
* identifier that helps categorize log events.
*
* @example
* ```typescript
* // Module-based names
* new LogEvent('info', ['Starting'], 'auth.service');
* new LogEvent('debug', ['Cache miss'], 'data.cache');
*
* // Component-based names
* new LogEvent('info', ['Render complete'], 'ui.dashboard');
* new LogEvent('error', ['API error'], 'api.users');
* ```
*/
loggerName: string,
/**
* Optional typed context data for the log event
*
* Provides additional structured data that can be used by
* formatters and handlers. The context type is controlled
* by the Ctx type parameter.
*
* @example
* ```typescript
* // Request context
* interface RequestContext {
* requestId: string;
* path: string;
* method: string;
* }
*
* new LogEvent<RequestContext>(
* 'info',
* ['Request received'],
* 'http',
* new LogContext({
* requestId: 'req-123',
* path: '/api/users',
* method: 'GET'
* })
* );
*
* // Performance context
* interface PerfContext {
* duration: number;
* memoryUsage: number;
* }
*
* new LogEvent<PerfContext>(
* 'debug',
* ['Operation completed'],
* 'perf',
* new LogContext({
* duration: 150,
* memoryUsage: process.memoryUsage().heapUsed
* })
* );
* ```
*/
context?: Ctx | undefined);
}
/**
* Interface for log event formatters
*
* Formatters are responsible for converting log events into specific output
* formats. They can transform the event data into strings, objects, or arrays
* suitable for the target output medium.
*
* Core responsibilities:
* - Format log events into desired output format
* - Support type-safe context handling
* - Maintain consistent formatting across log entries
* - Handle different log levels appropriately
*
* @typeParam Ctx - Type of the context value, defaults to unknown
*
* @example Basic string formatter
* ```typescript
* class SimpleFormatter implements FormatterInterface {
* format(event: LogEvent): string[] {
* const timestamp = new Date(event.timestamp).toISOString();
* const level = event.level.toUpperCase();
* const message = event.args.join(' ');
*
* return [`[${timestamp}] ${level}: ${message}`];
* }
* }
* ```
*
* @example JSON formatter
* ```typescript
* class JSONFormatter implements FormatterInterface {
* format(event: LogEvent): string {
* return JSON.stringify({
* timestamp: event.timestamp,
* level: event.level,
* message: event.args[0],
* data: event.args.slice(1),
* context: event.context?.value
* });
* }
* }
* ```
*
* @example Type-safe context formatter
* ```typescript
* interface RequestContext {
* requestId: string;
* userId?: string;
* path: string;
* method: string;
* }
*
* class RequestFormatter implements FormatterInterface<RequestContext> {
* format(event: LogEvent<RequestContext>): string[] {
* const ctx = event.context?.value;
* const prefix = ctx
* ? `[${ctx.method} ${ctx.path}] [${ctx.requestId}]`
* : '';
*
* return [
* prefix,
* event.level.toUpperCase(),
* ...event.args
* ];
* }
* }
* ```
*
* @example Colored console formatter
* ```typescript
* class ColoredFormatter implements FormatterInterface {
* private colors = {
* error: '\x1b[31m', // Red
* warn: '\x1b[33m', // Yellow
* info: '\x1b[36m', // Cyan
* debug: '\x1b[90m', // Gray
* reset: '\x1b[0m' // Reset
* };
*
* format(event: LogEvent): unknown[] {
* const color = this.colors[event.level] || this.colors.reset;
* const timestamp = new Date(event.timestamp).toISOString();
*
* return [
* `${color}[${timestamp}] ${event.level.toUpperCase()}:${this.colors.reset}`,
* ...event.args
* ];
* }
* }
* ```
*/
interface FormatterInterface<Ctx = unknown> {
/**
* Formats a log event into the desired output format
*
* This method transforms a log event into a format suitable for output.
* The return value can be:
* - A single value (string, object, etc.)
* - An array of values (for handlers that support multiple arguments)
*
* Implementation considerations:
* - Handle all log levels consistently
* - Process context data appropriately
* - Maintain type safety with generic context
* - Consider performance for high-volume logging
*
* @param event - The log event to format
* @returns Formatted output as a single value or array of values
*
* @example String output
* ```typescript
* format(event: LogEvent): string {
* const { timestamp, level, args } = event;
* return `[${new Date(timestamp).toISOString()}] ${
* level.toUpperCase()
* }: ${args.join(' ')}`;
* }
* ```
*
* @example Array output for console
* ```typescript
* format(event: LogEvent): unknown[] {
* const prefix = `[${event.level.toUpperCase()}]`;
* return [prefix, ...event.args];
* }
* ```
*
* @example Structured output
* ```typescript
* format(event: LogEvent): object {
* return {
* '@timestamp': event.timestamp,
* level: event.level,
* message: event.args[0],
* metadata: {
* args: event.args.slice(1),
* context: event.context?.value
* }
* };
* }
* ```
*
* @example Type-safe context handling
* ```typescript
* interface UserContext {
* userId: string;
* sessionId: string;
* }
*
* format(event: LogEvent<UserContext>): object {
* const ctx = event.context?.value;
* return {
* timestamp: event.timestamp,
* level: event.level,
* message: event.args[0],
* user: ctx ? {
* id: ctx.userId,
* session: ctx.sessionId
* } : undefined
* };
* }
* ```
*/
format(event: LogEvent<Ctx>): unknown | unknown[];
}
/**
* Interface for log event handlers (appenders)
*
* Handlers are responsible for processing and outputting log events to
* various destinations (console, file, network, etc.). They can optionally
* use formatters to customize the output format.
*
* Core responsibilities:
* - Process log events
* - Output logs to specific destinations
* - Support optional formatting
* - Handle different log levels
*
* @example Basic console handler
* ```typescript
* class ConsoleHandler implements HandlerInterface {
* private formatter: FormatterInterface | null = null;
*
* append(event: LogEvent): void {
* const args = this.formatter
* ? this.formatter.format(event)
* : event.args;
*
* console.log(...args);
* }
*
* setFormatter(formatter: FormatterInterface): void {
* this.formatter = formatter;
* }
* }
* ```
*
* @example File handler with rotation
* ```typescript
* class RotatingFileHandler implements HandlerInterface {
* constructor(
* private filename: string,
* private maxSize: number = 10 * 1024 * 1024
* ) {}
*
* append(event: LogEvent): void {
* const message = this.formatter
* ? this.formatter.format(event)
* : event.args.join(' ');
*
* if (this.shouldRotate()) {
* this.rotate();
* }
* fs.appendFileSync(this.filename, message + '\n');
* }
*
* setFormatter(formatter: FormatterInterface): void {
* this.formatter = formatter;
* }
*
* private shouldRotate(): boolean {
* return fs.statSync(this.filename).size > this.maxSize;
* }
*
* private rotate(): void {
* const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
* fs.renameSync(
* this.filename,
* `${this.filename}.${timestamp}.backup`
* );
* }
* }
* ```
*
* @example Network handler with buffering
* ```typescript
* class NetworkHandler implements HandlerInterface {
* private buffer: LogEvent[] = [];
* private timer: NodeJS.Timer | null = null;
*
* constructor(
* private endpoint: string,
* private batchSize: number = 100,
* private flushInterval: number = 5000
* ) {
* this.startTimer();
* }
*
* append(event: LogEvent): void {
* this.buffer.push(event);
* if (this.buffer.length >= this.batchSize) {
* this.flush();
* }
* }
*
* setFormatter(formatter: FormatterInterface): void {
* this.formatter = formatter;
* }
*
* private async flush(): Promise<void> {
* if (this.buffer.length === 0) return;
*
* const events = this.buffer.map(event => ({
* level: event.level,
* message: this.formatter
* ? this.formatter.format(event)
* : event.args.join(' '),
* timestamp: event.timestamp
* }));
*
* try {
* await fetch(this.endpoint, {
* method: 'POST',
* body: JSON.stringify(events)
* });
* this.buffer = [];
* } catch (error) {
* console.error('Failed to send logs:', error);
* }
* }
*
* private startTimer(): void {
* this.timer = setInterval(() => this.flush(), this.flushInterval);
* }
* }
* ```
*/
interface HandlerInterface<Ctx = unknown> {
/**
* Processes and outputs a log event
*
* This method is called by the logger for each log event that needs
* to be processed. The handler can format the event using its formatter
* (if set) and output it to its destination.
*
* Implementation considerations:
* - Handle all log levels appropriately
* - Apply formatting if a formatter is set
* - Handle errors gracefully
* - Consider performance implications
*
* @param event - The log event to process and output
*
* @example Basic implementation
* ```typescript
* append(event: LogEvent): void {
* const output = this.formatter
* ? this.formatter.format(event)
* : event.args;
*
* console.log(...output);
* }
* ```
*
* @example Advanced implementation with error handling
* ```typescript
* append(event: LogEvent): void {
* try {
* // Format the event
* const formatted = this.formatter
* ? this.formatter.format(event)
* : event.args;
*
* // Add timestamp and level
* const output = [
* new Date(event.timestamp).toISOString(),
* event.level.toUpperCase(),
* ...formatted
* ];
*
* // Write to file
* fs.appendFileSync(this.filename, output.join(' ') + '\n');
* } catch (error) {
* console.error('Failed to append log:', error);
* // Optionally write to fallback location
* fs.appendFileSync(
* 'error.log',
* `Failed to write log: ${error.message}\n`
* );
* }
* }
* ```
*
* @example Asynchronous implementation
* ```typescript
* async append(event: LogEvent): Promise<void> {
* // Format the event
* const message = this.formatter
* ? this.formatter.format(event)
* : event.args.join(' ');
*
* // Prepare log entry
* const entry = {
* timestamp: event.timestamp,
* level: event.level,
* message,
* metadata: event.context?.value
* };
*
* try {
* // Send to logging service
* await fetch('https://logging.example.com/ingest', {
* method: 'POST',
* headers: { 'Content-Type': 'application/json' },
* body: JSON.stringify(entry)
* });
* } catch (error) {
* // Handle failure
* console.error('Failed to send log:', error);
* // Add to retry queue
* this.retryQueue.push(entry);
* }
* }
* ```
*/
append(event: LogEvent<Ctx>): void;
/**
* Sets or updates the formatter for this handler
*
* The formatter is responsible for converting log events into
* the desired output format. This method allows changing the
* formatter at runtime.
*
* Implementation considerations:
* - Handle null formatters gracefully
* - Consider thread safety in async environments
* - Clean up old formatter resources if necessary
*
* @param formatter - The formatter instance to use
*
* @example Basic implementation
* ```typescript
* setFormatter(formatter: FormatterInterface): void {
* this.formatter = formatter;
* }
* ```
*
* @example Implementation with cleanup
* ```typescript
* setFormatter(formatter: FormatterInterface): void {
* if (this.formatter && 'dispose' in this.formatter) {
* // Clean up old formatter resources
* this.formatter.dispose();
* }
* this.formatter = formatter;
* }
* ```
*
* @example Thread-safe implementation
* ```typescript
* setFormatter(formatter: FormatterInterface): void {
* // Ensure atomic formatter update
* this.lock.acquire();
* try {
* const oldFormatter = this.formatter;
* this.formatter = formatter;
*
* // Flush any pending logs with old formatter
* if (oldFormatter) {
* this.flushBuffer(oldFormatter);
* }
* } finally {
* this.lock.release();
* }
* }
* ```
*/
setFormatter(formatter: FormatterInterface): void;
}
/**
* Type-safe container for log event context data
*
* This class provides a generic wrapper for additional context data
* that can be attached to log events. It ensures type safety through
* its generic type parameter and provides a consistent structure for
* context handling.
*
* Core features:
* - Generic type support
* - Optional value handling
* - Immutable context data
* - Type-safe access
*
* @typeParam Value - Type of the context value
*
* @example Basic usage
* ```typescript
* // Simple context
* const context = new LogContext({ userId: 123 });
* logger.info('User action', context);
* ```
*
* @example Type-safe context
* ```typescript
* interface RequestContext {
* requestId: string;
* path: string;
* method: string;
* userId?: string;
* }
*
* const context = new LogContext<RequestContext>({
* requestId: 'req-123',
* path: '/api/users',
* method: 'GET'
* });
*
* logger.info('Request received', context);
* ```
*
* @example Optional context
* ```typescript
* // Empty context
* const emptyContext = new LogContext();
*
* // Context with undefined value
* const context = new LogContext<string | undefined>(undefined);
*
* // Context with null value
* const nullContext = new LogContext<string | null>(null);
* ```
*
* @example Complex context
* ```typescript
* interface PerformanceContext {
* operation: string;
* metrics: {
* duration: number;
* memory: {
* before: number;
* after: number;
* };
* cpu: {
* user: number;
* system: number;
* };
* };
* metadata: Record<string, unknown>;
* }
*
* const context = new LogContext<PerformanceContext>({
* operation: 'data-processing',
* metrics: {
* duration: 1500,
* memory: {
* before: 100000,
* after: 150000
* },
* cpu: {
* user: 80,
* system: 20
* }
* },
* metadata: {
* batchSize: 1000,
* compression: true,
* priority: 'high'
* }
* });
*
* logger.debug('Operation metrics', context);
* ```
*
* @example Context in formatters
* ```typescript
* class DetailedFormatter implements FormatterInterface<RequestContext> {
* format(event: LogEvent<RequestContext>): string[] {
* const ctx = event.context?.value;
* if (ctx) {
* return [
* `[${ctx.method} ${ctx.path}]`,
* `[${ctx.requestId}]`,
* ...event.args
* ];
* }
* return event.args;
* }
* }
* ```
*/
declare class LogContext<Value> {
/**
* The context value that will be attached to log events
*
* This value is typed according to the Value type parameter
* and can be accessed safely through optional chaining.
*/
value?: Value | undefined;
/**
* Creates a new LogContext instance
*
* @param value - Optional context value of type Value
*
* The value parameter is marked as optional to support:
* - Empty contexts (no value provided)
* - Explicitly undefined values
* - Nullable types (Value | null)
*
* The value is stored as a public property to allow:
* - Direct access in formatters and handlers
* - Type-safe value extraction
* - Optional chaining support
*
* @example Basic construction
* ```typescript
* // With value
* const context = new LogContext({ userId: 123 });
* console.log(context.value?.userId); // 123
*
* // Empty context
* const empty = new LogContext();
* console.log(empty.value); // undefined
* ```
*
* @example Type-safe construction
* ```typescript
* interface UserContext {
* id: number;
* name: string;
* role?: string;
* }
*
* const context = new LogContext<UserContext>({
* id: 123,
* name: 'John',
* role: 'admin' // Optional property
* });
*
* // Type-safe access
* const userId = context.value?.id; // number | undefined
* const role = context.value?.role; // string | undefined
* ```
*
* @example Nullable context
* ```typescript
* type NullableContext = {
* sessionId: string;
* } | null;
*
* // With value
* const active = new LogContext<NullableContext>({
* sessionId: 'sess-123'
* });
*
* // With null
* const inactive = new LogContext<NullableContext>(null);
*
* // Type-safe null handling
* console.log(active.value?.sessionId); // 'sess-123'
* console.log(inactive.value?.sessionId); // undefined
* ```
*
* @example Context in logging
* ```typescript
* interface RequestContext {
* path: string;
* method: string;
* duration: number;
* }
*
* const context = new LogContext<RequestContext>({
* path: '/api/users',
* method: 'GET',
* duration: 150
* });
*
* // Using context in log messages
* logger.info('Request completed', context);
*
* // Accessing context in formatters
* class RequestFormatter implements FormatterInterface<RequestContext> {
* format(event: LogEvent<RequestContext>): string[] {
* const ctx = event.context?.value;
* return [
* ctx ? `${ctx.method} ${ctx.path} (${ctx.duration}ms)` : 'Unknown',
* ...event.args
* ];
* }
* }
* ```
*/
constructor(
/**
* The context value that will be attached to log events
*
* This value is typed according to the Value type parameter
* and can be accessed safely through optional chaining.
*/
value?: Value | undefined);
}
/**
* Core interface for logger implementations
*
* This interface defines the standard contract for logger implementations,
* providing methods for different log levels, handler management, and
* context creation.
*
* Core functionality:
* - Standard log level methods (fatal, error, warn, info, debug, trace)
* - Handler (appender) management
* - Context creation for structured logging
* - Type-safe logging with generic context support
*
* @example Basic usage
* ```typescript
* class MyLogger implements LoggerInterface {
* info(...args: unknown[]): void {
* console.log('[INFO]', ...args);
* }
* // ... implement other methods
* }
*
* const logger = new MyLogger();
* logger.info('Application started');
* ```
*
* @example With handlers and context
* ```typescript
* class AdvancedLogger implements LoggerInterface {
* private handlers: HandlerInterface[] = [];
*
* addAppender(handler: HandlerInterface): void {
* this.handlers.push(handler);
* }
*
* info(...args: unknown[]): void {
* const event = {
* level: 'info',
* args,
* timestamp: Date.now()
* };
*
* this.handlers.forEach(handler => handler.append(event));
* }
*
* context<T>(value?: T): LogContext<T> {
* return new LogContext(value);
* }
* // ... implement other methods
* }
*
* const logger = new AdvancedLogger();
* logger.addAppender(new ConsoleHandler());
* logger.info('User logged in', logger.context({ userId: 123 }));
* ```
*
* @example Type-safe context usage
* ```typescript
* interface UserContext {
* userId: number;
* username: string;
* role: string;
* }
*
* const logger: LoggerInterface = new Logger();
*
* // Type-safe context
* logger.info('User action', logger.context<UserContext>({
* userId: 123,
* username: 'john_doe',
* role: 'admin'
* }));
* ```
*/
interface LoggerInterface<Ctx = unknown> {
/**
* General purpose logging method (alias for info)
*
* @param args - Message content followed by optional context
*
* @example
* ```typescript
* logger.log('Application started');
* logger.log('User action', { userId: 123 });
* logger.log('Process completed', logger.context({ duration: 1500 }));
* ```
*/
log(...args: unknown[]): void;
/**
* Logs a critical error that causes application termination
*
* Use for severe errors that:
* - Cause immediate application shutdown
* - Require immediate administrator attention
* - Indicate system is unusable
*
* @param args - Message content followed by optional context
*
* @example
* ```typescript
* logger.fatal('Database connection permanently lost');
* logger.fatal('Out of memory', { memoryUsage: process.memoryUsage() });
* logger.fatal('System crash', logger.context({
* error: new Error('Unrecoverable error'),
* state: 'corrupted'
* }));
* ```
*/
fatal(...args: unknown[]): void;
/**
* Logs an error condition that doesn't cause termination
*
* Use for errors that:
* - Prevent normal operation but allow recovery
* - Require administrator attention
* - Need to be tracked for troubleshooting
*
* @param args - Message content followed by optional context
*
* @example
* ```typescript
* logger.error('Failed to process payment');
* logger.error('API request failed', { status: 500, path: '/api/users' });
* logger.error('Database query error', logger.context({
* query: 'SELECT * FROM users',
* error: new Error('Connection timeout')
* }));
* ```
*/
error(...args: unknown[]): void;
/**
* Logs a warning condition that might cause issues
*
* Use for situations that:
* - Are unusual but not errors
* - Might cause problems in the future
* - Indicate deprecated feature usage
*
* @param args - Message content followed by optional context
*
* @example
* ```typescript
* logger.warn('High memory usage detected');
* logger.warn('Deprecated API used', { api: 'oldMethod', alternative: 'newMethod' });
* logger.warn('Cache miss rate high', logger.context({
* rate: '85%',
* threshold: '75%'
* }));
* ```
*/
warn(...args: unknown[]): void;
/**
* Logs normal but significant events
*
* Use for events that:
* - Mark major application state changes
* - Track business process completion
* - Record user actions
*
* @param args - Message content followed by optional context
*
* @example
* ```typescript
* logger.info('Application started on port 3000');
* logger.info('User logged in', { userId: 123, role: 'admin' });
* logger.info('Order processed', logger.context({
* orderId: 'ORD-123',
* amount: 99.99,
* currency: 'USD'
* }));
* ```
*/
info(...args: unknown[]): void;
/**
* Logs detailed information for debugging
*
* Use for information that:
* - Helps diagnose problems
* - Shows detailed flow of execution
* - Exposes internal state
*
* @param args - Message content followed by optional context
*
* @example
* ```typescript
* logger.debug('Processing request payload');
* logger.debug('Cache state', { size: 1024, entries: 50 });
* logger.debug('Query execution plan', logger.context({
* sql: 'SELECT * FROM users WHERE role = ?',
* params: ['admin'],
* executionTime: 150
* }));
* ```
*/
debug(...args: unknown[]): void;
/**
* Logs the most detailed level of information
*
* Use for information that:
* - Shows step-by-step execution flow
* - Includes method entry/exit points
* - Contains variable state changes
*
* @param args - Message content followed by optional context
*
* @example
* ```typescript
* logger.trace('Entering method processUser');
* logger.trace('Variable state', { counter: 5, buffer: [1,2,3] });
* logger.trace('Method execution', logger.context({
* method: 'processUser',
* args: { id: 123 },
* stack: new Error().stack
* }));
* ```
*/
trace(...args: unknown[]): void;
/**
* Adds a new handler (appender) to the logger
*
* Handlers are responsible for processing and outputting log events.
* Multiple handlers can be added to send logs to different destinations
* or format them differently.
*
* @param appender - The handler instance to add
*
* @example Basic console handler
* ```typescript
* const logger = new Logger();
* logger.addAppender(new ConsoleHandler());
* ```
*
* @example Multiple handlers
* ```typescript
* const logger = new Logger();
*
* // Console output for development
* logger.addAppender(new ConsoleHandler(
* new TimestampFormatter({ locale: 'en-US' })
* ));
*
* // File output for errors
* logger.addAppender(new FileHandler('./logs/errors.log', {
* level: 'error',
* formatter: new JSONFormatter()
* }));
*
* // Metrics collection
* logger.addAppender(new MetricsHandler({
* service: 'user-api',
* endpoint: 'https://metrics.example.com'
* }));
* ```
*
* @example Conditional handlers
* ```typescript
* const logger = new Logger();
*
* // Development handlers
* if (process.env.NODE_ENV === 'development') {
* logger.addAppender(new ConsoleHandler(
* new PrettyFormatter({ colors: true })
* ));
* logger.addAppender(new FileHandler('./logs/dev.log'));
* }
*
* // Production handlers
* if (process.env.NODE_ENV === 'production') {
* logger.addAppender(new CloudWatchHandler({
* region: 'us-east-1',
* logGroupName: '/aws/api'
* }));
* logger.addAppender(new AlertHandler({
* level: 'error',
* webhook: 'https://alerts.example.com'
* }));
* }
* ```
*/
addAppender(appender: HandlerInterface<Ctx>): void;
/**
* Creates a new LogContext instance for structured logging
*
* Context objects allow adding structured data to log messages
* in a type-safe way. They can be used to add metadata,
* performance metrics, error details, or any other relevant
* information to log entries.
*
* @since 0.1.0
* @param value - Optional value to be stored in the context
* @returns A new LogContext instance with the provided value
*
* @example Basic context usage
* ```typescript
* logger.info('User logged in', logger.context({
* userId: 123,
* role: 'admin',
* loginTime: new Date()
* }));
* ```
*
* @example Type-safe context
* ```typescript
* interface RequestContext {
* method: string;
* path: string;
* duration: number;
* statusCode: number;
* }
*
* logger.info('Request completed', logger.context<RequestContext>({
* method: 'GET',
* path: '/api/users',
* duration: 150,
* statusCode: 200
* }));
* ```
*
* @example Error context
* ```typescript
* try {
* await processOrder(orderId);
* } catch (error) {
* logger.error('Order processing failed', logger.context({
* orderId,
* error: error instanceof Error ? error.message : String(error),
* stack: error instanceof Error ? error.stack : undefined
* }));
* }
* ```
*
* @example Performance monitoring
* ```typescript
* const startTime = Date.now();
* try {
* const result = await heavyOperation();
* logger.info('Operation completed', logger.context({
* duration: Date.now() - startTime,
* resultSize: result.length,
* memoryUsage: process.memoryUsage()
* }));
* } catch (error) {
* logger.error('Operation failed', logger.context({
* duration: Date.now() - startTime,
* error,
* memoryUsage: process.memoryUsage()
* }));
* }
* ```
*/
context<Value>(value?: Value): LogContext<Value>;
}
/**
* Environment configuration options interface
* @interface
* @description
* Significance: Defines initialization parameters for Env class
* Core idea: Configure environment variable management
* Main function: Type-safe environment configuration
* Main purpose: Initialize environment handler
* Example:
* ```typescript
* const options: EnvOptions = {
* rootPath: '/path/to/project',
* logger: new Logger()
* };
* ```
*/
interface EnvOptions {
/** Root path for environment files */
rootPath: string;
/** Logger instance */
logger?: LoggerInterface | typeof console;
}
/**
* Environment loading options interface
* @interface
* @description
* Significance: Defines options for loading environment variables
* Core idea: Control environment file loading behavior
* Main function: Configure environment loading process
* Main purpose: Customize environment loading
* Example:
* ```typescript
* const loadOptions: LoadOptions = {
* preloadList: ['.env', '.env.local'],
* rootPath: '/custom/path'
* };
* ```
*/
interface LoadOptions {
/** List of environment files to load */
preloadList: string[];
/** Optional root path override */
rootPath?: string;
}
/**
* Environment variable management class
* @class
* @description
* Significance: Manages environment variables and .env files
* Core idea: Centralize environment variable operations
* Main function: Load and manage environment variables
* Main purpose: Provide consistent environment variable access
* Example:
* ```typescript
* const env = new Env({
* rootPath: process.cwd(),
* logger: new Logger()
* });
* env.load({ preloadList: ['.env'] });
* ```
*/
declare class Env {
private options;
/**
* Creates an Env instance
* @param options - Environment configuration options
* @description
* Significance: Initializes environment management
* Core idea: Setup environment configuration
* Main function: Create environment handler
* Main purpose: Prepare for environment operations
* Example:
* ```typescript
* const env = new Env({
* rootPath: './project',
* logger: new Logger()
* });
* ```
*/
constructor(options: EnvOptions);
get rootPath(): string;
get logger(): LoggerInterface | typeof console | undefined;
/**
* from current directory to root directory, search and load .env file
* @param {object} options
* @param {string} [options.cwd] start search directory, default is process.cwd()
* @param {string[]} [options.preloadList] search file name list, default is ['.env.local', '.env']
* @param {Logger} [options.logger] logger
* @param {number} [options.maxDepth=5] maximum search depth
* @returns {Env} environment variable loader instance
*/
static searchEnv({ cwd, preloadList, logger, maxDepth }?: {
cwd?: string;
preloadList?: string[];
logger?: LoggerInterface;
maxDepth?: number;
}): Env;
/**
* Load environment variables from files
* @param options - Load configuration options
* @returns void
* @description
* Significance: Loads environment variables from files
* Core idea: Sequential environment file loading
* Main function: Process and load environment files
* Main purpose: Initialize environment variables
* Example:
* ```typescript
* env.load({
* preloadList: ['.env.local', '.env'],
* rootPath: './config'
* });
* ```
*/
load(options?: LoadOptions): void;
/**
* Remove environment variable
* @param variable - Environment variable name
* @returns void
* @description
* Significance: Removes specific environment variable
* Core idea: Safe environment variable deletion
* Main function: Delete environment variable
* Main purpose: Clean up environment state
* Example:
* ```typescript
* env.remove('API_KEY');
* ```
*/
remove(variable: string): void;
/**
* Get environment variable value
* @param variable - Environment variable name
* @returns Environment variable value or undefined
* @description
* Significance: Retrieves environment variable value
* Core idea: Safe environment variable access
* Main function: Get environment variable
* Main purpose: Access environment state
* Example:
* ```typescript
* const apiKey = env.get('API_KEY');
* ```
*/
get(variable: string): string | undefined;
/**
* Set environment variable
* @param variable - Environment variable name
* @param value - Value to set
* @returns void
* @description
* Significance: Sets environment variable value
* Core idea: Safe environment variable modification
* Main function: Update environment variable
* Main purpose: Modify environment state
* Example:
* ```typescript
* env.set('DEBUG', 'true');
* ```
*/
set(variable: string, value: string): void;
/**
* Get and remove environment variable
* @param variable - Environment variable name
* @returns Environment variable value or undefined
* @description
* Significance: Retrieves and removes environment variable
* Core idea: Atomic get and delete operation
* Main function: Access and clean up variable
* Main purpose: One-time environment variable access
* Example:
* ```typescript
* const tempKey = env.getDestroy('TEMP_API_KEY');
* ```
*/
getDestroy(variable: string): string | undefined;
}
export { Env };