CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-winston-transport

Base stream implementations for winston@3 and up.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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
});
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/winston-transport@4.9.x
Publish Source
CLI
Badge
tessl/npm-winston-transport badge