1.1.0 • Published 4 months ago
@vepler/logger v1.1.0
@vepler/logger
A lightweight, type-safe logging wrapper around Pino built by vepler for its ecosystem. While primarily designed for vepler's internal use, this library is open for public use.
Features
- 🔒 Type-safe logging with TypeScript support
- 🌟 Singleton pattern for consistent logging across your application
- 🔄 Global context management
- 🛡️ Automatic sensitive data redaction
- 🎯 Structured logging with JSON output
- ⚡ High-performance (powered by Pino)
- 🔍 Comprehensive error object handling
- 🌊 Async flush support for graceful shutdowns
Installation
npm install @vepler/logger
# or
yarn add @vepler/logger
# or
pnpm add @vepler/logger
Quick Start
import PinoWrapper from '@vepler/logger';
// Initialize the logger (do this once at app startup)
PinoWrapper.initialize({
level: 'info',
// Optional: Add any Pino options here
});
// Set global context (e.g., in your main application setup)
PinoWrapper.setContext({
environment: process.env.NODE_ENV,
service: 'user-service'
});
// Basic logging
PinoWrapper.info('User logged in successfully', {
userId: '123',
loginMethod: 'oauth'
});
// Error logging
try {
// Some operation that might fail
} catch (err) {
PinoWrapper.error(err, 'Failed to process user request', {
userId: '123',
requestId: 'abc-xyz'
});
}
// Before application shutdown
await PinoWrapper.flush();
Features in Detail
Initialization
The logger can be initialized with custom options:
PinoWrapper.initialize({
level: 'debug',
formatters: {
level: (label) => ({ level: label.toUpperCase() })
},
timestamp: pino.stdTimeFunctions.isoTime,
redact: {
paths: ['password', 'token', 'authorization', 'secret'],
remove: true
}
});
Context Management
Set global context that will be included in all subsequent logs:
// Set context
PinoWrapper.setContext({
environment: 'production',
service: 'auth-service',
version: '1.0.0'
});
// Clear context when needed
PinoWrapper.clearContext();
Logging Methods
Available logging methods:
PinoWrapper.trace(message, context?);
PinoWrapper.debug(message, context?);
PinoWrapper.info(message, context?);
PinoWrapper.warn(message, context?);
PinoWrapper.error(error, message, context?);
PinoWrapper.fatal(error, message, context?);
Error Handling
The logger automatically handles different types of errors:
// Standard Error object
const error = new Error('Database connection failed');
PinoWrapper.error(error, 'Failed to connect');
// Custom error object
const customError = {
code: 'INVALID_INPUT',
details: { field: 'email' }
};
PinoWrapper.error(customError, 'Validation failed');
// String error
PinoWrapper.error('Something went wrong', 'Operation failed');
Child Loggers
Create child loggers with additional context:
const childLogger = PinoWrapper.child({
component: 'auth',
requestId: '123'
});
Multiple Output Streams
Configure multiple output streams during initialization:
PinoWrapper.initialize({
transport: {
targets: [
{
target: 'pino/file',
options: {
destination: './logs/info.log',
level: 'info'
}
},
{
target: 'pino/file',
options: {
destination: './logs/error.log',
level: 'error'
}
}
]
}
});
Best Practices
Initialization
- Initialize the logger once at application startup
- Configure appropriate log levels for different environments
Context Management
- Use global context for environment-wide properties
- Clear context when it's no longer needed
- Don't overuse context; keep it focused on essential properties
Error Logging
- Always include error objects in error/fatal logs
- Add relevant context to error logs
- Use appropriate log levels based on error severity
Performance
- Avoid expensive operations in log context
- Use child loggers for request-scoped logging
- Call
flush()
before application shutdown
Log Output Example
{
"level": "ERROR",
"time": "2024-02-19T12:34:56.789Z",
"environment": "production",
"service": "user-service",
"requestId": "abc-xyz",
"error": {
"type": "Error",
"message": "Database connection failed",
"stack": "Error: Database connection failed\n at ...",
"code": "ECONNREFUSED"
},
"msg": "Failed to process user request"
}
Contributing
We welcome contributions! Please feel free to submit a Pull Request.
Releasing
Releases are automated using GitHub Actions. To create a new release:
- Push your changes
- GitHub Action will automatically:
- Create a new version
- Create a GitHub Release
- Publish to npm
License
MIT © vepler
Credits
Built with ❤️ by vepler. Powered by Pino.