pinito
v0.0.2
Published
Pinito extends the high-performance capabilities of `pino` with critical features required for enterprise systems, including automated log rotation, graceful shutdown handling, and a sophisticated adaptive rate-limiting system that responds dynamically to
Downloads
28
Readme
Pinito Logger
A Node.js logging library built as a high-level wrapper around pino, providing a robust and configurable framework for high-performance server environments.
Overview
Pinito enhances pino with features including automated log rotation, graceful shutdown handling, and adaptive rate-limiting that responds dynamically to server load. Designed as a plug-and-play solution, it enforces logging best practices by default.
Features
- High-Performance Core: Built on pino for minimal overhead and optimal performance in high-throughput applications.
- Structured JSON Logging: Enforces structured, machine-readable JSON logging in production environments, while providing human-readable, colorized output during development via
pino-pretty. - Adaptive Rate Limiting: The core innovation of this logger. It actively monitors Node.js event loop utilization (ELU) and dynamically throttles log output when the server is under high load. This prevents the logging system from contributing to performance degradation during critical periods, ensuring application stability.
- Configurable Rate Limiting: Provides granular, per-level rate limiting (
maxLogsPerMinute) to prevent log flooding from misbehaving application components. Includes a warning threshold to signal when limits are being approached. - Automated Log Rotation: Integrates
pino-rollfor robust, time- and size-based file rotation, with configurable frequency (daily,hourly), file size limits, and automatic archiving. - Graceful Shutdown: Guarantees log buffer flushing on process termination signals (
SIGINT,SIGTERM), preventing log loss during deployments, restarts, or application crashes. - Singleton Access Pattern: Exposes a static
Logger.getInstance()method to ensure a single, consistently configured logger instance is used throughout the application lifecycle. - Dynamic Level Control: Supports runtime log level changes via a
setLevel()method, allowing for dynamic verbosity adjustments in live environments without requiring a service restart. - Automatic Redaction: Ships with a default set of redaction paths to automatically censor sensitive information (e.g., passwords, API keys, tokens) from log output.
Installation
pnpm install pinitoQuick Start
Initialize and use the logger singleton.
import { Logger } from 'pinito';
// Get the singleton instance (initialization happens on first call)
const logger = Logger.getInstance({
level: 'info',
serviceName: 'my-application',
});
logger.info('Service has started successfully.');
logger.warn({ message: 'Configuration value is deprecated.' });
try {
throw new Error('Something went wrong.');
} catch (error) {
logger.error('An unexpected error occurred.', error as Error);
}Configuration
The logger can be configured on the first call to Logger.getInstance(options). All subsequent calls will return the already configured instance.
| Option | Type | Default | Description |
|-----------------------|------------------|------------------------|--------------------------------------------------------------------------|
| level | LogLevel | 'info' | The minimum log level to output. |
| serviceName | string | 'PinitoLogger' | Identifier for the service generating the logs. |
| enableFileLogging | boolean | false | If true, enables logging to a rotating file transport. |
| logDirectory | string | 'logs' | The directory to store log files. Required if enableFileLogging is true. |
| filename | string | 'pinito-log' | The base name for log files. |
| fileRotationFrequency | string | 'daily' | Frequency of log rotation ('daily' or 'hourly'). |
| maxFileSize | number | 10 | Maximum size of a log file in megabytes before rotation. |
| fileRotationLimit | number | 7 | Number of rotated log files to retain. |
| redactFields | string[] | [...] | An array of object keys to redact from logs. Supports dot notation. |
| rateLimit | RateLimitOptions | See default-options.ts | Configuration for the standard and adaptive rate limiters. |
Adaptive Rate Limiter Configuration
The adaptive rate limiter is enabled by default and can be configured via the rateLimit.adaptive object.
| Option | Type | Default | Description |
| ---------------------------- | ------- | ------- | -------------------------------------------------------------------------------------------- |
| enabled | boolean | true | Toggles the adaptive rate limiting feature. |
| targetEventLoopUtilization | number | 0.7 | The target ELU. The system will throttle logs if the actual ELU exceeds this value. |
| minMultiplier | number | 0.1 | The minimum multiplier to apply to the rate limit (e.g., 0.1 = 10% of the configured rate). |
| maxMultiplier | number | 2.0 | The maximum multiplier to apply to the rate limit (e.g., 2.0 = 200% of the configured rate). |
Architecture
The logger is composed of three primary components:
- Logger: The main class and public interface. It manages the pino instance, handles configuration, and orchestrates the other components.
- RateLimiter: A high-throughput counter that tracks log entries on a per-level, per-minute basis. It applies a dynamic multiplier to its configured limits.
- AdaptiveController: A background controller that monitors performance.eventLoopUtilization at a regular interval. It calculates and applies a new multiplier to the RateLimiter based on a smoothed algorithm to increase or decrease the log throughput in response to server load.
This modular design ensures a clean separation of concerns and allows for robust, independent testing of each component.
