Configure and manage multiple output streams with individual log levels, file outputs, log rotation, and custom stream handling for flexible log routing.
Configure multiple output streams with different types, levels, and destinations during logger creation.
interface StreamConfig {
type?: 'stream' | 'file' | 'rotating-file' | 'raw';
level?: string | number; // Minimum level for this stream
stream?: NodeJS.WritableStream; // For type 'stream'
path?: string; // For type 'file' or 'rotating-file'
period?: string; // For rotating files: '1d', '1h', '1w', '1m', '1y'
count?: number; // Number of rotated files to keep (default: 10)
closeOnExit?: boolean; // Close stream on process exit (default: true for files)
}
// Logger creation with multiple streams
const logger = bunyan.createLogger({
name: 'myapp',
streams: StreamConfig[]
});Add new streams to existing loggers at runtime.
class Logger {
/**
* Add a new stream to the logger
* @param stream - Stream configuration or stream object
* @param defaultLevel - Default level if not specified in stream config
*/
addStream(stream: StreamConfig | NodeJS.WritableStream,
defaultLevel?: string | number): void;
}Different stream types for various output destinations and behaviors.
Output to any Node.js writable stream (stdout, stderr, network, etc.).
interface StandardStreamConfig {
type: 'stream';
level?: string | number;
stream: NodeJS.WritableStream;
closeOnExit?: boolean;
}Output to a regular file with automatic creation and basic file handling.
interface FileStreamConfig {
type: 'file';
level?: string | number;
path: string;
closeOnExit?: boolean;
}Output to files with automatic rotation based on time periods or file size.
interface RotatingFileStreamConfig {
type: 'rotating-file';
level?: string | number;
path: string;
period?: string; // Rotation period: '1d', '1h', '1w', '1m', '1y'
count?: number; // Number of rotated files to keep (default: 10)
}
class RotatingFileStream {
constructor(options: RotatingFileStreamOptions);
/**
* Write data to the current log file
* @param data - String data to write
*/
write(data: string): void;
/**
* Manually trigger log rotation
*/
rotate(): void;
/**
* End the stream and close files
*/
end(): void;
/**
* Destroy the stream
*/
destroy(): void;
/**
* Destroy stream after pending writes complete
*/
destroySoon(): void;
}
interface RotatingFileStreamOptions {
path: string; // File path template (can include strftime patterns)
period?: string; // Rotation period
count?: number; // Number of files to keep
}Output raw log record objects instead of JSON strings for custom processing.
interface RawStreamConfig {
type: 'raw';
level?: string | number;
stream: RawStream;
}
interface RawStream {
write(record: LogRecord): void;
}
interface LogRecord {
v: number; // Log version
level: number; // Log level
name: string; // Logger name
hostname: string; // Machine hostname
pid: number; // Process ID
time: Date; // Timestamp
msg: string; // Log message
[key: string]: any; // Additional fields
}Manage stream lifecycle including reopening and closing streams.
class Logger {
/**
* Reopen all file streams (useful for log rotation via external tools)
*/
reopenFileStreams(): void;
/**
* Close all streams associated with this logger
*/
close(): void;
}Specialized stream implementations for common logging patterns.
In-memory circular buffer for keeping recent log records in memory.
class RingBuffer extends EventEmitter {
constructor(options?: {limit?: number});
limit: number; // Maximum records to keep (default: 100)
writable: boolean; // Stream writability flag
records: LogRecord[]; // Array of stored log records
/**
* Write a log record to the buffer
* @param record - Log record object
*/
write(record: LogRecord): void;
}Usage Examples:
const bunyan = require('bunyan');
// Multiple streams with different levels
const log = bunyan.createLogger({
name: 'multi-stream-app',
streams: [
{
level: 'info',
stream: process.stdout
},
{
level: 'error',
path: './error.log'
},
{
level: 'trace',
type: 'rotating-file',
path: './app.log',
period: '1d',
count: 7
}
]
});
// Add stream dynamically
log.addStream({
type: 'file',
path: './debug.log',
level: 'debug'
});
// Raw stream for custom processing
const customStream = {
write: function(record) {
// Custom processing of log records
console.log('Custom processing:', record.msg);
}
};
log.addStream({
type: 'raw',
stream: customStream,
level: 'warn'
});
// RingBuffer for in-memory log storage
const ringBuffer = new bunyan.RingBuffer({limit: 50});
log.addStream({
type: 'raw',
stream: ringBuffer,
level: 'debug'
});
// Access recent logs
console.log('Recent logs:', ringBuffer.records);
// Direct RotatingFileStream usage
const rotatingStream = new bunyan.RotatingFileStream({
path: './app-%Y-%m-%d.log',
period: '1d',
count: 30
});
log.addStream({
type: 'raw',
stream: rotatingStream
});
// Manual rotation
rotatingStream.rotate();
// Cleanup
log.close();Streams can emit error events that should be handled to prevent application crashes:
const log = bunyan.createLogger({
name: 'error-handling-app',
streams: [
{
type: 'file',
path: './app.log'
}
]
});
// Handle stream errors (automatically attached by bunyan)
log.on('error', function(err, stream) {
console.error('Logging error on stream:', err);
});