or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-winston-transport

Base stream implementations for winston@3 and up.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/winston-transport@4.9.x

To install, run

npx @tessl/cli install tessl/npm-winston-transport@4.9.0

index.mddocs/

winston-transport

winston-transport provides the base TransportStream implementation for winston logging library version 3 and above. It serves as the foundational building block for creating custom winston transports with a standardized stream-based interface.

Package Information

  • Package Name: winston-transport
  • Package Type: npm
  • Language: JavaScript (with TypeScript definitions)
  • Installation: npm install winston-transport

Core Imports

Default export (main TransportStream class):

const Transport = require('winston-transport');

Named exports (legacy transport):

const { LegacyTransportStream } = require('winston-transport');

TypeScript import patterns:

import TransportStream = require('winston-transport');
import { LegacyTransportStream } from 'winston-transport';

ESM imports (Node.js with "type": "module"):

import Transport from 'winston-transport';
import { LegacyTransportStream } from 'winston-transport';

Basic Usage

const Transport = require('winston-transport');

class CustomTransport extends Transport {
  constructor(opts) {
    super(opts);
    // Custom initialization
  }

  log(info, callback) {
    setImmediate(() => {
      this.emit('logged', info);
    });

    // Perform the writing to the remote service
    console.log(info.message);
    
    callback();
  }
}

module.exports = CustomTransport;

Architecture

winston-transport is designed around several key components:

  • TransportStream: Modern stream-based transport extending Node.js Writable
  • Stream Integration: Full winston v3+ logger pipe compatibility with level filtering
  • Format Support: Integration with logform formatting system
  • Exception Handling: Built-in support for exception and rejection handling
  • Legacy Compatibility: LegacyTransportStream wrapper for winston v2 transports

Types

/** Log information object structure */
interface LogInfo {
  /** Log level (error, warn, info, debug, etc.) */
  level: string;
  /** Log message content */
  message: string;
  /** Exception flag for error handling */
  exception?: boolean;
  /** Timestamp (added by format) */
  timestamp?: string;
  /** Additional metadata */
  [key: string]: any;
}

/** Logform format interface for log transformation */
interface LogformFormat {
  /** Transform log info object */
  transform: (info: LogInfo, options?: any) => LogInfo | false;
  /** Format options */
  options?: any;
}

/** Log levels mapping (set by winston logger) */
interface LogLevels {
  [level: string]: number;
}

/** Node.js stream namespace reference */
declare namespace stream {
  class Writable {
    constructor(options?: any);
    write(chunk: any, encoding?: string, callback?: Function): boolean;
    end(chunk?: any, encoding?: string, callback?: Function): void;
    on(event: string, listener: Function): this;
    emit(event: string, ...args: any[]): boolean;
  }
}

Capabilities

Transport Stream Implementation

Core transport functionality providing a stream-based interface that integrates with winston v3+ logging architecture. Handles log level filtering, formatting, and lifecycle management.

/**
 * Base class for winston v3+ transports extending readable-stream's Writable
 * @param {TransportStreamOptions} options - Configuration options
 */
class TransportStream extends stream.Writable {
  /** Log formatter instance */
  format?: LogformFormat;
  /** Current log level */
  level?: string;
  /** Silent mode flag */
  silent?: boolean;
  /** Exception handling flag */
  handleExceptions?: boolean;
  /** Rejection handling flag */
  handleRejections?: boolean;
  /** Log levels map (set when piped from logger) */
  levels?: LogLevels;
  /** Parent logger reference (set when piped from logger) */
  parent?: any;

  constructor(options?: TransportStreamOptions);

  /** Log single message - must be implemented by subclasses */
  log?(info: LogInfo, next: () => void): any;

  /** Log multiple messages in batch - optional optimization */
  logv?(info: LogInfo[], next: () => void): any;

  /** Cleanup on transport removal - optional */
  close?(): void;
}

interface TransportStreamOptions {
  /** Log formatter from logform */
  format?: LogformFormat;
  /** Log level filter (e.g., 'info', 'error') */
  level?: string;
  /** Suppress all log output */
  silent?: boolean;
  /** Handle exception logs */
  handleExceptions?: boolean;
  /** Handle rejection logs */
  handleRejections?: boolean;
  /** Stream buffer size */
  highWaterMark?: number;
  /** Custom log function for simple transport creation */
  log?(info: LogInfo, next: () => void): any;
  /** Custom batch log function */
  logv?(info: LogInfo[], next: () => void): any;
  /** Custom close function */
  close?(): void;
}

Internal Stream Methods

Advanced stream methods for customizing transport behavior. Generally not needed for basic transport implementations.

/**
 * Internal write method called by stream when log data is written
 * @param {LogInfo} info - Log information object
 * @param {string} enc - Encoding (usually ignored in object mode)
 * @param {Function} callback - Completion callback
 */
TransportStream.prototype._write = function(info, enc, callback) {
  // Internal implementation - handles format transformation and level filtering
};

/**
 * Internal batch write method for multiple log entries
 * @param {Array} chunks - Array of write requests with chunk and callback
 * @param {Function} callback - Completion callback
 */
TransportStream.prototype._writev = function(chunks, callback) {
  // Internal implementation - handles batch processing
};

/**
 * Filter predicate to determine if a write request should be accepted
 * @param {Object} write - Write request object with chunk property
 * @returns {boolean} - True if the write should be processed
 */
TransportStream.prototype._accept = function(write) {
  // Internal implementation - checks level, silent mode, and exception handling
};

Legacy Transport Compatibility

Wrapper functionality for winston v2 transports to work with winston v3+ logger infrastructure. Provides backward compatibility while encouraging migration to modern transport interface.

/**
 * Wrapper for winston v2 transports to work with winston v3+
 * @param {LegacyTransportStreamOptions} options - Configuration options
 */
class LegacyTransportStream extends TransportStream {
  /** The wrapped winston v2 transport instance */
  transport: LegacyTransport;

  constructor(options: LegacyTransportStreamOptions);

  /** Cleanup legacy transport and error handlers */
  close(): void;
}

interface LegacyTransportStreamOptions extends TransportStreamOptions {
  /** winston v2 transport instance with log method */
  transport: LegacyTransport;
}

/** Winston v2 transport interface */
interface LegacyTransport {
  /** Transport name for identification */
  name?: string;
  /** Log method with v2 signature */
  log: (level: string, message: string, meta: any, callback: () => void) => void;
  /** Optional cleanup method */
  close?: () => void;
  /** Optional log level */
  level?: string;
  /** Optional exception handling */
  handleExceptions?: boolean;
  /** Event emitter methods for error handling */
  on?: (event: string, listener: Function) => void;
  removeListener?: (event: string, listener: Function) => void;
}

Usage Examples

Creating a Custom Transport

const Transport = require('winston-transport');

class CustomTransport extends Transport {
  constructor(opts) {
    super(opts);
    
    // Initialize custom transport properties
    this.name = 'custom';
    this.filename = opts.filename;
  }

  log(info, callback) {
    setImmediate(() => {
      this.emit('logged', info);
    });

    // Write log to your custom destination
    // info object contains: { level, message, timestamp, ...metadata }
    const logLine = `${info.timestamp} [${info.level}]: ${info.message}\n`;
    
    // Perform actual writing (file, database, API, etc.)
    this.writeToDestination(logLine);
    
    callback();
  }

  close() {
    // Cleanup resources
    if (this.connection) {
      this.connection.close();
    }
  }
}

module.exports = CustomTransport;

Using with Winston Logger

const winston = require('winston');
const CustomTransport = require('./custom-transport');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new CustomTransport({
      filename: 'app.log',
      level: 'error'
    })
  ]
});

logger.error('This will be written by CustomTransport');
logger.info('This will be filtered out due to level');

Wrapping Legacy Transport

const { LegacyTransportStream } = require('winston-transport');
const OldTransport = require('winston-old-transport');

// Wrap a winston v2 transport for v3+ compatibility
const legacyTransport = new LegacyTransportStream({
  transport: new OldTransport({
    level: 'info',
    filename: 'legacy.log'
  })
});

// Use with winston v3+ logger
const logger = winston.createLogger({
  transports: [legacyTransport]
});

Error Handling

winston-transport provides comprehensive error handling through multiple mechanisms:

Stream Error Events

Transport errors bubble up through the standard Node.js stream error event system:

const transport = new CustomTransport();

transport.on('error', (err) => {
  console.error('Transport error:', err);
});

// Errors in log() method will emit 'error' event
transport.log({ level: 'info', message: 'test' }, (err) => {
  if (err) {
    // Handle callback errors
    console.error('Log callback error:', err);
  }
});

Exception and Rejection Handling

Control how the transport handles uncaught exceptions and unhandled promise rejections:

const transport = new CustomTransport({
  handleExceptions: true,   // Handle uncaught exceptions
  handleRejections: true    // Handle unhandled promise rejections
});

// These will be captured and logged by the transport:
// throw new Error('Uncaught exception');
// Promise.reject('Unhandled rejection');

Format Transformation Errors

Format transformation errors are trapped and re-thrown after callback invocation to ensure stream continuation:

const transport = new CustomTransport({
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.printf(info => {
      // If this throws an error, it will be caught and re-thrown
      // after the callback is invoked
      return `${info.timestamp} ${info.level}: ${info.message}`;
    })
  )
});

Legacy Transport Error Forwarding

Legacy transports have automatic error event forwarding with proper cleanup:

const legacyTransport = new LegacyTransportStream({
  transport: new OldTransport()
});

// Errors from the wrapped transport are automatically forwarded
legacyTransport.on('error', (err, transport) => {
  console.error('Legacy transport error:', err);
  console.error('From transport:', transport.name);
});

// Cleanup is automatic when transport is removed
logger.remove(legacyTransport); // Calls close() and removes error listeners

Silent Mode

Use silent mode to suppress all log output while maintaining error handling:

const transport = new CustomTransport({
  silent: true  // No logs will be written, but errors are still handled
});