Super fast, all natural JSON logger with exceptional performance for structured logging applications.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive configuration system for customizing logger behavior, output format, and performance characteristics. The pino constructor accepts an options object to control all aspects of logging behavior.
Create a logger instance with optional configuration and destination stream.
/**
* Create a new logger instance
* @param options - Configuration options for the logger
* @param stream - Optional destination stream for log output
* @returns Configured logger instance
*/
function pino(options?: LoggerOptions): Logger;
function pino(options: LoggerOptions, stream?: DestinationStream): Logger;
function pino(stream?: DestinationStream): Logger;Usage Examples:
// Basic logger with defaults
const logger = pino();
// Logger with custom level
const logger = pino({ level: 'debug' });
// Logger with custom stream
const logger = pino(pino.destination('./logs/app.log'));
// Logger with options and stream
const logger = pino({
name: 'my-app',
level: 'info'
}, pino.destination('./logs/app.log'));Complete configuration interface for logger behavior.
interface LoggerOptions {
/** Minimum log level (default: 'info') */
level?: string;
/** Logger name to include in log records */
name?: string;
/** Timestamp configuration (default: epochTime) */
timestamp?: boolean | TimeFn;
/** Custom object serializers */
serializers?: { [key: string]: SerializerFn };
/** Data redaction configuration */
redact?: string[] | RedactOptions;
/** Transport configuration for log processing */
transport?: TransportSingleOptions | TransportMultiOptions | TransportPipelineOptions;
/** Output formatting functions */
formatters?: FormattersOptions;
/** Custom logging levels */
customLevels?: { [level: string]: number };
/** Use only custom levels, omit default levels */
useOnlyCustomLevels?: boolean;
/** Level comparison function for custom sorting */
levelComparison?: "ASC" | "DESC" | ((current: number, expected: number) => boolean);
/** Mixin function for adding dynamic data */
mixin?: MixinFn;
/** Mixin merge strategy function */
mixinMergeStrategy?: MixinMergeStrategyFn;
/** Message key name in log output (default: 'msg') */
messageKey?: string;
/** Error key name in log output (default: 'err') */
errorKey?: string;
/** Nested key for wrapping log data */
nestedKey?: string;
/** Enable/disable logging (default: true) */
enabled?: boolean;
/** Base properties added to all log records */
base?: { [key: string]: any } | null;
/** Hook functions for customization */
hooks?: HooksOptions;
/** Message prefix for all log messages */
msgPrefix?: string;
/** Use CRLF line endings instead of LF */
crlf?: boolean;
/** Object serialization depth limit (default: 5) */
depthLimit?: number;
/** Object serialization breadth limit (default: 100) */
edgeLimit?: number;
/** Child logger creation callback */
onChild?: OnChildCallback;
/** Browser-specific options */
browser?: BrowserOptions;
/** Avoid error causes by circular references (default: true) */
safe?: boolean;
/** Custom level numeric value when defining custom level via level */
levelVal?: number;
/** Output level as string instead of integer */
useLevelLabels?: boolean;
}Control which log messages are output based on severity level.
interface LoggerOptions {
/** Minimum log level: 'fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent' */
level?: string;
}Usage Examples:
// Development logging
const logger = pino({ level: 'debug' });
// Production logging
const logger = pino({ level: 'warn' });
// Disable all logging
const logger = pino({ level: 'silent' });Add a name field to all log records for identification.
interface LoggerOptions {
/** Logger name included in all log records */
name?: string;
}Usage Examples:
const logger = pino({ name: 'my-application' });
logger.info('Hello world');
// Output: {"level":30,"time":1531171074631,"name":"my-application","msg":"hello world",...}
const apiLogger = pino({ name: 'api-server' });
const dbLogger = pino({ name: 'database' });Control timestamp format and inclusion in log records.
interface LoggerOptions {
/** Timestamp configuration - boolean or custom function */
timestamp?: boolean | TimeFn;
}
type TimeFn = () => string;Usage Examples:
// Default epoch timestamp
const logger = pino({ timestamp: true });
// No timestamp
const logger = pino({ timestamp: false });
// Custom timestamp format
const logger = pino({
timestamp: () => `,"time":"${new Date().toISOString()}"`
});
// Use built-in time functions
const logger = pino({ timestamp: pino.stdTimeFunctions.isoTime });Default properties included in all log records.
interface LoggerOptions {
/** Base properties added to all log records (default includes pid and hostname) */
base?: { [key: string]: any } | null;
}Usage Examples:
// Custom base properties
const logger = pino({
base: {
service: 'user-api',
version: '1.2.3',
env: process.env.NODE_ENV
}
});
// No base properties
const logger = pino({ base: null });
// Add to default base properties
const logger = pino({
base: {
pid: process.pid,
hostname: os.hostname(),
service: 'my-app'
}
});Define custom logging levels with numeric priorities.
interface LoggerOptions {
/** Custom level definitions */
customLevels?: { [level: string]: number };
/** Use only custom levels, omit default pino levels */
useOnlyCustomLevels?: boolean;
/** Custom level comparison function */
levelComparison?: "ASC" | "DESC" | ((current: number, expected: number) => boolean);
}Usage Examples:
// Add custom levels
const logger = pino({
customLevels: {
foo: 35, // Between info (30) and warn (40)
bar: 45 // Between warn (40) and error (50)
}
});
logger.foo('Custom level message');
logger.bar({ data: 'example' }, 'Another custom level');
// Use only custom levels
const logger = pino({
level: 'foo',
customLevels: { foo: 30, bar: 40, baz: 50 },
useOnlyCustomLevels: true
});Add dynamic data to log records using mixin functions.
interface LoggerOptions {
/** Function called for each log method to add dynamic data */
mixin?: MixinFn;
/** Strategy for merging mixin data with log data */
mixinMergeStrategy?: MixinMergeStrategyFn;
}
type MixinFn = (mergeObject: object, level: number, logger: Logger) => object;
type MixinMergeStrategyFn = (mergeObject: object, mixinObject: object) => object;Usage Examples:
// Add request ID from async context
const logger = pino({
mixin() {
return {
requestId: getRequestId(), // From async local storage
memoryUsage: process.memoryUsage().heapUsed
};
}
});
// Custom merge strategy
const logger = pino({
mixin: () => ({ timestamp: Date.now() }),
mixinMergeStrategy: (mergeObject, mixinObject) => {
return Object.assign({}, mixinObject, mergeObject);
}
});Customize the shape of log output using formatter functions.
interface LoggerOptions {
/** Output formatting functions */
formatters?: FormattersOptions;
}
interface FormattersOptions {
/** Changes the shape of the log level in output */
level?: (label: string, number: number) => object;
/** Changes the shape of the bindings in output */
bindings?: (bindings: Bindings) => object;
/** Changes the shape of the log object */
log?: (object: Record<string, unknown>) => Record<string, unknown>;
}Usage Examples:
const logger = pino({
formatters: {
level: (label, number) => {
return { severity: label.toUpperCase() };
},
bindings: (bindings) => {
return { context: bindings };
},
log: (object) => {
const { req, res, ...rest } = object;
return rest; // Remove req/res from output
}
}
});Customize internal logger operations with hook functions.
interface LoggerOptions {
/** Hook functions for customizing logger behavior */
hooks?: HooksOptions;
}
interface HooksOptions {
/** Intercept and modify log method calls */
logMethod?: (this: Logger, args: Parameters<LogFn>, method: LogFn, level: number) => void;
/** Modify stringified JSON before writing to stream */
streamWrite?: (str: string) => string;
}Usage Examples:
const logger = pino({
hooks: {
logMethod(args, method, level) {
// Add timestamp to first argument if it's an object
if (typeof args[0] === 'object' && args[0] !== null) {
args[0].loggedAt = new Date().toISOString();
}
method.apply(this, args);
},
streamWrite(str) {
// Compress or encrypt log data before writing
return compress(str);
}
}
});Customize field names for messages and errors in log output.
interface LoggerOptions {
/** Key name for message field (default: 'msg') */
messageKey?: string;
/** Key name for error field (default: 'err') */
errorKey?: string;
/** Key name for nesting all log data */
nestedKey?: string;
}Usage Examples:
// Custom message key
const logger = pino({ messageKey: 'message' });
logger.info('Hello world');
// Output: {"level":30,"time":1531171074631,"message":"hello world",...}
// Custom error key
const logger = pino({ errorKey: 'error' });
logger.error(new Error('Failed'), 'Operation failed');
// Nested data
const logger = pino({ nestedKey: 'data' });
logger.info({ userId: 123 }, 'User action');
// Output: {"level":30,"time":1531171074631,"msg":"User action","data":{"userId":123},...}Control object serialization depth and breadth to prevent performance issues.
interface LoggerOptions {
/** Maximum object nesting depth (default: 5) */
depthLimit?: number;
/** Maximum number of properties per object (default: 100) */
edgeLimit?: number;
}Usage Examples:
// Increase limits for complex objects
const logger = pino({
depthLimit: 10,
edgeLimit: 200
});
// Decrease limits for performance
const logger = pino({
depthLimit: 3,
edgeLimit: 50
});Control whether logging is active without changing log levels.
interface LoggerOptions {
/** Enable or disable all logging (default: true) */
enabled?: boolean;
}Usage Examples:
// Disable logging entirely
const logger = pino({ enabled: false });
// Conditional logging
const logger = pino({
enabled: process.env.NODE_ENV !== 'test'
});Install with Tessl CLI
npx tessl i tessl/npm-pino