lever-ui-logger
Version:
Zero-dependency logging library with optional EventBus integration. Built-in PII redaction, multiple transports, and comprehensive logging capabilities.
369 lines (368 loc) • 12.4 kB
TypeScript
/**
* EventBus transport for cross-library integration
*
* Publishes log events to the EventBus system to enable other parts of the
* application to subscribe to and react to logging events. Provides filtering
* to prevent infinite loops and error isolation to ensure transport failures
* don't break the main logging system.
*
* @example
* ```typescript
* import { EventBusTransport } from 'lever-ui-logger/transports';
*
* // Your EventBus implementation (must have 'post' method)
*
* const transport = new EventBusTransport(eventBus, {
* enableSelfLogging: false,
* filterComponents: ['eventbus-transport']
* });
*
* // Use with logger
* const logger = createLogger({
* transports: [transport]
* });
* ```
*/
import type { LogEventData } from '../logger/types.js';
import { BaseTransport } from './transport-interface.js';
import { LogEvent, MetricEvent, ErrorEvent } from '../logger/events.js';
/**
* Configuration options for EventBus transport
*
* @example
* ```typescript
* const config: EventBusTransportConfig = {
* name: 'custom-eventbus',
* enableSelfLogging: false,
* filterComponents: ['eventbus-transport', 'sensitive-component'],
* silentErrors: false,
* transformMetadata: {
* transportId: 'main-eventbus',
* version: '1.0.0'
* }
* };
* ```
*/
export interface EventBusTransportConfig {
/** Transport name (default: 'eventbus') */
name?: string;
/** Enable logging from the transport itself (default: false to prevent loops) */
enableSelfLogging?: boolean;
/** Component names to filter out (prevents infinite loops) */
filterComponents?: string[];
/** Suppress error logging when EventBus operations fail (default: false) */
silentErrors?: boolean;
/** Additional metadata to add to all published events */
transformMetadata?: Record<string, unknown>;
/** Custom event transformer function */
eventTransformer?: (_event: LogEventData, _metadata: EventTransformMetadata) => LogEvent | MetricEvent | ErrorEvent | null;
/** Enable publishing logger lifecycle events (default: true) */
enableLifecycleEvents?: boolean;
}
/**
* EventBus interface for dependency injection
*
* Defines the minimal EventBus interface needed by the transport.
* This allows for testing with mock EventBus instances.
*/
export interface EventBusInterface {
/** Post an event to all subscribers */
post<T>(_event: T): void | Promise<void>;
/** Optional: Check if EventBus is healthy/connected */
isConnected?(): boolean;
}
/**
* Metadata passed to event transformers
*/
export interface EventTransformMetadata {
/** Transport name */
transportName: string;
/** Transformation timestamp */
transformTimestamp: number;
/** Additional custom metadata */
metadata?: Record<string, unknown>;
}
/**
* EventBus transport for cross-library integration
*
* Transforms log events into EventBus events and publishes them for
* subscription by other systems. Includes comprehensive protection
* against infinite loops and robust error handling.
*
* Features:
* - Automatic event transformation (LogEvent, MetricEvent, ErrorEvent)
* - Logger lifecycle event publishing (LoggerCreatedEvent, LoggerDestroyedEvent, LoggerConfigChangedEvent)
* - Infinite loop prevention with component filtering
* - Error isolation - transport failures don't break logging
* - Configurable metadata enrichment
* - Custom event transformation support
* - Silent mode for production environments
*
* @example
* ```typescript
* const transport = new EventBusTransport(eventBus, {
* filterComponents: ['eventbus-transport', 'analytics'],
* transformMetadata: { source: 'main-app' },
* silentErrors: process.env.NODE_ENV === 'production'
* });
* ```
*/
export declare class EventBusTransport extends BaseTransport {
private readonly transportConfig;
private readonly eventTransformer?;
private readonly transformMetadata;
private readonly eventBus;
/**
* Create a new EventBus transport instance
*
* @param eventBus - EventBus instance to publish events to
* @param config - Transport configuration options
* @param config.name - Transport name (default: 'eventbus')
* @param config.enableSelfLogging - Allow transport to log about itself (default: false)
* @param config.filterComponents - Component names to ignore (default: ['eventbus-transport'])
* @param config.silentErrors - Suppress error logging (default: false)
* @param config.transformMetadata - Additional metadata for events (default: {})
* @param config.eventTransformer - Custom event transformation function (optional)
*
* @example
* ```typescript
* const transport = new EventBusTransport(eventBus, {
* enableSelfLogging: false,
* filterComponents: ['eventbus-transport', 'debug-panel'],
* transformMetadata: {
* appVersion: '2.1.0',
* environment: 'production'
* }
* });
* ```
*/
constructor(eventBus: EventBusInterface, config?: EventBusTransportConfig);
/**
* Write a log event to the EventBus
*
* Transforms the log event data into appropriate EventBus event objects
* and publishes them. Includes filtering to prevent infinite loops and
* error handling to ensure transport failures don't break logging.
*
* @param event - The log event data to publish
*
* @example
* ```typescript
* // This will create and publish a LogEvent to EventBus
* transport.write({
* level: 'info',
* message: 'User action completed',
* timestamp: Date.now(),
* component: 'user-service',
* context: { userId: '123', action: 'login' },
* args: []
* });
* ```
*/
write(event: LogEventData): void;
/**
* Flush any pending events (no-op for EventBus transport)
*
* EventBus transport publishes events immediately, so flushing
* is not necessary. This method is provided for transport interface
* compatibility.
*
* @returns Resolved promise
*/
flush(): Promise<void>;
/**
* Close the transport (no-op for EventBus transport)
*
* EventBus transport doesn't maintain persistent connections,
* so closing is not necessary. This method is provided for
* transport interface compatibility.
*
* Note: Use publishLifecycleEvent('destroyed') explicitly if you
* want to publish lifecycle events.
*
* @returns Resolved promise
*/
close(): Promise<void>;
/**
* Publish logger lifecycle events to EventBus
*
* Publishes lifecycle events (created, destroyed, config-changed) to the EventBus
* to allow other systems to track logger state changes.
*
* @param eventType - Type of lifecycle event
* @param config - Logger configuration (for created/config-changed events)
* @param loggerName - Name of the logger (optional)
*
* @example
* ```typescript
* // Publish logger created event
* transport.publishLifecycleEvent('created', { level: 'info' }, 'main-logger');
*
* // Publish config changed event
* transport.publishLifecycleEvent('config-changed', { level: 'debug' });
*
* // Publish destroyed event
* transport.publishLifecycleEvent('destroyed');
* ```
*/
publishLifecycleEvent(eventType: 'created' | 'destroyed' | 'config-changed', config?: Record<string, unknown>, loggerName?: string): void;
/**
* Check if an event should be processed (infinite loop prevention)
*
* Filters out events from components that might cause infinite loops,
* particularly events from the transport itself or other sensitive
* components specified in the configuration.
*
* @param event - Log event to check
* @returns True if event should be processed
*
* @internal
*/
private shouldProcessEvent;
/**
* Check if EventBus is ready to receive events
*
* Performs basic health checks on the EventBus instance to ensure
* it's safe to publish events. Handles cases where EventBus might
* be undefined or not connected.
*
* @returns True if EventBus is ready
*
* @internal
*/
private isEventBusReady;
/**
* Transform log event data into EventBus event objects
*
* Creates appropriate EventBus event instances (LogEvent, MetricEvent, ErrorEvent)
* based on the log event data. Supports custom transformation functions
* and adds transport metadata.
*
* @param event - Log event data to transform
* @returns Transformed EventBus event or null if transformation fails
*
* @internal
*/
private transformEvent;
/**
* Create default EventBus events from log data
*
* Applies intelligent event type detection based on log content:
* - Error events for error level logs or Error objects in context
* - Metric events for logs with numeric data or specific patterns
* - Log events for everything else
*
* @param event - Log event data
* @param metadata - Transform metadata
* @returns Appropriate EventBus event
*
* @internal
*/
private createDefaultEvent;
/**
* Detect if event should be treated as an error event
*
* @param event - Log event data
* @returns True if this should be an ErrorEvent
*
* @internal
*/
private isErrorEvent;
/**
* Detect if event should be treated as a metric event
*
* @param event - Log event data
* @returns True if this should be a MetricEvent
*
* @internal
*/
private isMetricEvent;
/**
* Create ErrorEvent from log data
*
* @param event - Log event data
* @param metadata - Transform metadata
* @returns ErrorEvent instance
*
* @internal
*/
private createErrorEvent;
/**
* Create MetricEvent from log data
*
* @param event - Log event data
* @param metadata - Transform metadata
* @returns MetricEvent instance
*
* @internal
*/
private createMetricEvent;
/**
* Create LogEvent from log data
*
* @param event - Log event data
* @param metadata - Transform metadata
* @returns LogEvent instance
*
* @internal
*/
private createLogEvent;
/**
* Publish event to EventBus
*
* Handles both synchronous and asynchronous EventBus post methods.
* Includes error handling for publish failures.
*
* @param event - EventBus event to publish
*
* @internal
*/
private publishEvent;
/**
* Handle EventBus post errors
*
* Provides error logging and graceful degradation when EventBus
* operations fail. Respects silent error configuration.
*
* @param error - Error that occurred
* @param originalEvent - Original log event (if available)
*
* @internal
*/
private handlePublishError;
}
/**
* Create an EventBus transport with default configuration
*
* Factory function that creates a new EventBus transport instance
* with the provided EventBus and configuration. Provides a convenient
* way to create transports without using the constructor directly.
*
* @param eventBus - EventBus instance to publish events to
* @param config - Transport configuration options
* @returns New EventBus transport instance
*
* @example
* ```typescript
* import { createEventBusTransport } from 'lever-ui-logger/transports';
*
* // Your EventBus implementation
* const eventBus = { post: (event) => console.log(event) };
*
* const transport = createEventBusTransport(eventBus, {
* filterComponents: ['eventbus-transport', 'analytics'],
* transformMetadata: {
* appVersion: '1.0.0',
* environment: process.env.NODE_ENV
* },
* silentErrors: process.env.NODE_ENV === 'production'
* });
*
* // Use with logger
* const logger = createLogger({
* transports: [transport]
* });
* ```
*/
export declare function createEventBusTransport(eventBus: EventBusInterface, config?: EventBusTransportConfig): EventBusTransport;
//# sourceMappingURL=eventbus-transport.d.ts.map