or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli-tool.mdcolorization.mdconfiguration.mdcustom-prettifiers.mdindex.mdmessage-formatting.mdprettifier-factory.mdstream-transport.md
tile.json

stream-transport.mddocs/

Stream and Transport Creation

The build function creates a Node.js Transform stream that prettifies Pino log lines. It supports both direct streaming usage and Pino v7+ transport protocol with automatic configuration detection.

Capabilities

Build Function

Creates a transform stream for prettifying logs with automatic Pino configuration handling.

/**
 * Constructs a prettifier and transform stream for prettifying logs
 * @param opts - Configuration options (extends PrettyOptions with destination)
 * @returns Transform stream with OnUnknown interface for handling non-JSON lines
 */
function build(opts?: BuildStreamOpts): PrettyStream;

interface BuildStreamOpts extends PrettyOptions {
  destination?: string | number | object | NodeJS.WritableStream;
  append?: boolean;
  mkdir?: boolean;
  sync?: boolean;
}

type PrettyStream = Transform & OnUnknown;

Usage Examples:

const pinoPretty = require('pino-pretty');

// Basic stream with default options
const stream = pinoPretty();

// Stream with custom options
const customStream = pinoPretty({
  colorize: true,
  translateTime: 'SYS:standard',
  ignore: 'pid,hostname',
  singleLine: false
});

// Stream writing to a file
const fileStream = pinoPretty({
  destination: './logs/pretty.log',
  mkdir: true,
  append: true,
  colorize: false
});

// Stream with sonic-boom instance for advanced control
const SonicBoom = require('sonic-boom');
const advancedStream = pinoPretty({
  destination: new SonicBoom({
    dest: './logs/app.log',
    mkdir: true,
    sync: false
  }),
  colorize: false
});

Pino Transport Integration

Use as a Pino v7+ transport with automatic configuration.

// Transport target usage (Pino automatically calls build)
const pino = require('pino');
const logger = pino({
  transport: {
    target: 'pino-pretty',
    options: {
      colorize: true,
      translateTime: 'HH:MM:ss',
      ignore: 'pid,hostname'
    }
  }
});

Usage Examples:

const pino = require('pino');

// Basic transport
const logger = pino({
  transport: {
    target: 'pino-pretty'
  }
});

// Transport with custom options
const customLogger = pino({
  transport: {
    target: 'pino-pretty',
    options: {
      colorize: true,
      levelFirst: true,
      translateTime: 'SYS:yyyy-mm-dd HH:MM:ss',
      messageFormat: '{levelLabel} - {pid} - {msg}',
      ignore: 'hostname'
    }
  }
});

// Multiple transports (pretty + file)
const multiLogger = pino({
  transport: {
    targets: [
      {
        target: 'pino-pretty',
        options: { colorize: true },
        level: 'info'
      },
      {
        target: 'pino/file',
        options: { destination: './app.log' },
        level: 'trace'
      }
    ]
  }
});

Direct Stream Usage

Use the stream directly with Pino logger instances.

// Create logger with pino-pretty stream
const pino = require('pino');
const pretty = require('pino-pretty');
const stream = pretty(options);
const logger = pino(stream);

// With pino options
const logger = pino(pinoOptions, stream);

Usage Examples:

const pino = require('pino');
const pretty = require('pino-pretty');

// Basic logger with pretty stream
const stream = pretty({ colorize: true });
const logger = pino(stream);
logger.info('Hello');

// Logger with pino options
const stream2 = pretty({
  colorize: true,
  translateTime: 'HH:MM:ss'
});
const logger2 = pino({ level: 'debug' }, stream2);
logger2.debug('Debug message');

// Synchronous stream for testing (e.g., with Jest)
const syncStream = pretty({
  sync: true,
  colorize: false
});
const testLogger = pino(syncStream);

Automatic PINO_CONFIG Handling

The stream automatically detects and responds to Pino configuration messages.

// When Pino sends PINO_CONFIG message, pino-pretty automatically updates:
// - messageKey from Pino's configuration
// - errorLikeObjectKeys (adds Pino's errorKey)
// - customLevels from Pino's level configuration

// This happens automatically - no code needed
// The stream listens for PINO_CONFIG and reconfigures itself

Behavior:

When used as a Pino transport or stream, pino-pretty listens for special PINO_CONFIG messages from Pino v8.21.0+. When received, it automatically synchronizes:

  • messageKey - Uses Pino's configured message key
  • errorLikeObjectKeys - Merges with Pino's error key
  • customLevels - Uses Pino's level configuration

This ensures pino-pretty stays synchronized with Pino's configuration without manual setup.

Output Destinations

The destination option supports multiple output types.

/**
 * Destination options for prettified output
 */
interface DestinationOptions {
  // File descriptor (1 = stdout, 2 = stderr)
  destination?: number;

  // File path
  destination?: string;

  // WritableStream instance
  destination?: NodeJS.WritableStream;

  // SonicBoom instance for advanced control
  destination?: object; // SonicBoom instance
}

Usage Examples:

const pinoPretty = require('pino-pretty');

// Write to stdout (default)
const stdout = pinoPretty({ destination: 1 });

// Write to stderr
const stderr = pinoPretty({ destination: 2 });

// Write to file path
const fileOut = pinoPretty({
  destination: './logs/app.log',
  mkdir: true,     // Create directory if needed
  append: true     // Append to existing file
});

// Write to custom writable stream
const fs = require('fs');
const customStream = fs.createWriteStream('./custom.log');
const customOut = pinoPretty({ destination: customStream });

// Async file writing (default)
const asyncFile = pinoPretty({
  destination: './logs/async.log',
  sync: false  // Default
});

// Sync file writing (useful for testing)
const syncFile = pinoPretty({
  destination: './logs/sync.log',
  sync: true
});

OnUnknown Handler

The stream handles non-JSON lines by passing them through unchanged.

/**
 * OnUnknown interface for handling non-JSON log lines
 * Non-JSON lines are written directly to destination with newline
 */
interface OnUnknown {
  // Event fired when non-JSON line is encountered
  on(event: 'unknown', handler: (line: string) => void): this;
}

Behavior:

When the stream encounters a line that:

  • Cannot be parsed as JSON
  • Is not a valid log object after parsing

The line is passed through unchanged with a newline appended, maintaining the original text in the output.

Usage Example:

const pinoPretty = require('pino-pretty');
const stream = pinoPretty({ colorize: true });

// Handle unknown lines manually if needed
stream.on('unknown', (line) => {
  console.error('Non-JSON line:', line);
});