magiclogger - v0.1.0
    Preparing search index...

    Class FileTransport

    High-performance asynchronous file transport using sonic-boom.

    This transport provides enterprise-grade file logging with:

    • Non-blocking I/O that doesn't slow down your application
    • Automatic buffering and batching for optimal throughput
    • Graceful error handling and recovery
    • Support for log rotation via reopen()

    Technical Implementation:

    • Uses sonic-boom for high-performance async I/O
    • Buffers writes in memory, flushes automatically
    • No worker threads - runs in main thread for zero IPC overhead
    • Implements synchronous logSync() method to avoid Promise overhead
    • Handles backpressure automatically when buffers fill
    • Provides detailed statistics for monitoring

    Performance vs Previous Implementation:

    • Previous (Worker Threads): ~45-85k ops/sec
    • Current (sonic-boom): ~300k+ ops/sec
    • 3-6x performance improvement

    AsyncFileTransport

    const transport = new AsyncFileTransport({
    filepath: './logs/app.log'
    });
    await transport.init();
    const transport = new AsyncFileTransport({
    filepath: './logs/app.log',
    minLength: 4096, // 4KB buffer before flush
    maxWrite: 16384, // 16KB max write size
    mkdir: true, // Create directory if needed
    retryEAGAIN: true, // Retry on EAGAIN errors
    mode: 0o644, // File permissions
    append: true // Append to existing file
    });
    // Rotate logs at midnight
    setInterval(async () => {
    await transport.reopen();
    }, 24 * 60 * 60 * 1000);

    Hierarchy

    • Transport
      • FileTransport
    Index

    Constructors

    Properties

    closing: boolean = false

    Flag to track if transport is currently closing.

    enabled: boolean

    Whether this transport is currently active and processing logs. Can be toggled at runtime to enable/disable specific transports.

    excludeTags?: string[]

    Tags that exclude logs from being processed.

    filter?: (entry: LogEntry) => boolean

    Custom filter function for advanced filtering.

    format: "json" | "plain" | "custom"

    Output format for this transport.

    formatter?: (entry: LogEntry) => string | Buffer<ArrayBufferLike>

    Custom formatter function.

    initialized: boolean = false

    Flag to track if transport has been initialized.

    level: string

    Minimum log level for this transport.

    levels?: string[]

    Specific levels this transport handles (if specified).

    name: string

    Unique identifier for this transport instance. Used for managing multiple transports and debugging.

    options: Required<FileTransportOptions>

    Transport configuration options.

    silent: boolean

    Whether to suppress errors from this transport.

    stats: TransportStats = ...

    Statistics tracking for this transport.

    tags?: string[]

    Tags that must be present for logs to be processed.

    timeout: number

    Operation timeout in milliseconds.

    Methods

    • Close the transport and clean up resources.

      Returns Promise<void>

      Resolves when the transport is fully closed

      If cleanup fails

    • Protected

      Close the transport gracefully.

      Performs a clean shutdown:

      1. Sets closing flag to prevent new logs
      2. Flushes all pending data to disk
      3. Destroys the sonic-boom instance
      4. Releases file handles

      Returns Promise<void>

      Resolves when fully closed

    • Protected

      Initialize the transport with sonic-boom.

      Creates the sonic-boom instance and sets up event handlers for:

      • Error handling and recovery
      • Write tracking for statistics
      • Ready state management

      This method is called automatically by the Transport base class when the transport is first used or explicitly via init().

      sonic-boom provides:

      • Internal buffering with configurable size
      • Async fs.write() operations (non-blocking)
      • Automatic flushing when buffer reaches minLength
      • No worker threads - runs in main thread

      Returns Promise<void>

    • Protected

      Legacy async doLog for compatibility with Transport base class.

      This method is not used when log() and logSync() are overridden, but is kept for compatibility with the Transport interface.

      Parameters

      Returns Promise<void>

      Internal use only - use log() or logSync() instead

    • Protected

      Optional method for transport-specific batch logging. Subclasses can implement this for efficient batch processing.

      Parameters

      • entries: LogEntry[]

        Array of log entries to process

      Returns Promise<void>

      Resolves when all logs have been processed

    • Synchronously calls each of the listeners registered for the event namedeventName, in the order they were registered, passing the supplied arguments to each.

      Returns true if the event had listeners, false otherwise.

      import EventEmitter from 'node:events';
      const myEmitter = new EventEmitter();

      // First listener
      myEmitter.on('event', function firstListener() {
      console.log('Helloooo! first listener');
      });
      // Second listener
      myEmitter.on('event', function secondListener(arg1, arg2) {
      console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
      });
      // Third listener
      myEmitter.on('event', function thirdListener(...args) {
      const parameters = args.join(', ');
      console.log(`event with parameters ${parameters} in third listener`);
      });

      console.log(myEmitter.listeners('event'));

      myEmitter.emit('event', 1, 2, 3, 4, 5);

      // Prints:
      // [
      // [Function: firstListener],
      // [Function: secondListener],
      // [Function: thirdListener]
      // ]
      // Helloooo! first listener
      // event with parameters 1, 2 in second listener
      // event with parameters 1, 2, 3, 4, 5 in third listener

      Parameters

      Returns boolean

      v0.1.26

    • Flush any buffered data to disk.

      Forces all pending log entries to be written immediately. This is useful for:

      • Ensuring critical logs are persisted
      • Graceful shutdown sequences
      • Before log rotation

      Returns Promise<void>

      Resolves when all data is written

      If flush fails

      // Ensure all logs are written before shutdown
      process.on('SIGTERM', async () => {
      await transport.flush();
      await transport.close();
      process.exit(0);
      });
    • Protected

      Format log entry for output.

      Converts log entries to JSON string format for file storage. Optimized for minimal overhead with direct JSON serialization.

      Supports both:

      • MinimalLogEntry: Optimized format from high-performance Logger
      • LogEntry: Full format with all metadata

      Parameters

      • entry: LogEntry | MinimalLogEntry

        The log entry to format

      Returns string

      JSON string representation

    • Protected

      Format a log entry as plain text.

      Parameters

      Returns string

      Plain text formatted log entry

    • Protected

      Generate a unique ID for tracking purposes.

      Returns string

      A unique identifier

    • Get transport statistics including buffer status.

      Provides detailed metrics for monitoring and debugging:

      • Basic transport statistics (processed, succeeded, failed, queued)
      • File path and buffer configuration
      • Current buffer usage
      • Custom metrics (bytes written, backpressure events, etc.)

      Returns {
          bufferLength: number;
          custom?: Record<string, unknown>;
          failed: number;
          filepath: string;
          implementation: string;
          isClosing: boolean;
          isInitialized: boolean;
          lastError?: { count: number; message: string; timestamp: Date };
          lastSuccess?: Date;
          logged?: number;
          maxWrite: number;
          minLength: number;
          name?: string;
          processed: number;
          queued?: number;
          sent?: number;
          succeeded: number;
      }

      Statistics object with buffer info

      • bufferLength: number
      • Optionalcustom?: Record<string, unknown>

        Transport-specific metrics.

      • failed: number

        Total logs that failed to send.

      • filepath: string
      • implementation: string
      • isClosing: boolean
      • isInitialized: boolean
      • OptionallastError?: { count: number; message: string; timestamp: Date }

        Last error that occurred.

      • OptionallastSuccess?: Date

        Last successful log timestamp.

      • Optionallogged?: number

        Alias for succeeded count, provided for readability in some consumers/tests.

      • maxWrite: number
      • minLength: number
      • Optionalname?: string

        Optional transport identifier for convenience in tests/metrics.

      • processed: number

        Total logs processed by this transport.

      • Optionalqueued?: number

        Current number of logs in queue (if applicable).

      • Optionalsent?: number

        Additional alias for succeeded count expected by some tests/consumers.

      • succeeded: number

        Total logs successfully sent.

      const stats = transport.getStats();
      console.log(`Processed: ${stats.processed}`);
      console.log(`Buffer usage: ${stats.bufferLength}/${stats.minLength}`);
      console.log(`Bytes written: ${stats.custom?.bytesWritten || 0}`);
    • Protected

      Handle errors according to the transport's configuration.

      Parameters

      • error: Error

        The error that occurred

      • Optionalentry: LogEntry

        The log entry that caused the error (if applicable)

      Returns void

    • Initialize the transport.

      Returns Promise<void>

      Resolves when initialization is complete

      If initialization fails

    • Check if the transport is currently enabled.

      Returns boolean

      True if transport is enabled

    • Check if transport is healthy.

      Returns Promise<boolean>

      True if transport is healthy

    • Protected

      Check if a log level is enabled based on minimum level.

      Parameters

      • level: string

        The level to check

      Returns boolean

      True if the level is enabled

    • Async log method for compatibility with base Transport interface.

      This method delegates to logSync() for performance, then returns an immediately resolved Promise for API compatibility. When called directly (not via TransportManager), this still provides async behavior but with some Promise overhead.

      Parameters

      • entry: LogEntry

        The log entry to process

      Returns Promise<void>

      Immediately resolved promise

    • Synchronous log method with application-level batching for maximum performance.

      This method implements a two-level batching strategy:

      1. Application-level batching: Collects entries in memory
      2. sonic-boom batching: Internal buffering for file I/O

      Benefits of application-level batching:

      • Reduces calls to sonic-boom (less overhead)
      • Minimizes string concatenation operations
      • Amortizes the cost of buffer management
      • Improves cache locality

      How it works:

      1. Entry is formatted and added to batch buffer
      2. When batch reaches batchSize (100) or batchInterval (10ms) expires:
        • All entries are sent to sonic-boom in one operation
        • sonic-boom handles the actual async file write
      3. No Promises created, no async context switching

      Performance improvements:

      • Before: ~130,000 ops/sec (individual writes)
      • After: ~250,000+ ops/sec (batched writes)
      • 1.9x performance improvement

      Parameters

      • entry: LogEntry | MinimalLogEntry

        The log entry to process

      Returns void

      2.1.0

    • Reopen the log file.

      Useful for log rotation scenarios where you want to:

      • Start writing to a new file after renaming the old one
      • Recover from file system errors
      • Implement time-based or size-based rotation

      Note: This doesn't rename the file - you need to handle that externally.

      Returns Promise<void>

      Resolves when file is reopened

      // Rotate logs daily
      async function rotateLogs(transport: AsyncFileTransport) {
      const oldPath = './logs/app.log';
      const newPath = `./logs/app-${Date.now()}.log`;

      // Flush pending writes
      await transport.flush();

      // Rename the current file
      fs.renameSync(oldPath, newPath);

      // Reopen to create new file
      await transport.reopen();
      }
    • Check if this transport should handle a given log entry.

      Parameters

      Returns boolean

      True if the entry should be logged by this transport

    • Protected

      Whether this transport should rethrow errors encountered during log operations. Network-based transports typically want propagation so callers/tests can assert failures. Base transports default to swallowing errors after emitting events and updating stats.

      Returns boolean

    • Check if transport supports batching.

      Returns boolean

      True if batching is supported

    • Protected

      Apply a timeout to an async operation.

      Type Parameters

      • T

      Parameters

      • promise: Promise<T>

        The promise to apply timeout to

      • ms: number

        Timeout in milliseconds

      Returns Promise<T>

      The original promise with timeout applied

      If operation times out