Package Exports
- @vepler/logger
- @vepler/logger/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@vepler/logger) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@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
- 💫 Intuitive, flexible API that works like
console.logbut better
Installation
npm install @vepler/logger
# or
yarn add @vepler/logger
# or
pnpm add @vepler/loggerQuick 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'
});
// Object-only logging
PinoWrapper.info({
userId: '123',
action: 'login',
duration: 42,
success: true
});
// Error logging
try {
// Some operation that might fail
} catch (error) {
// Several equivalent ways to log errors:
// 1. Pass the error directly
PinoWrapper.error(error);
// 2. Pass error with a message
PinoWrapper.error(error, 'Failed to process user request');
// 3. Pass error, message, and context
PinoWrapper.error(error, 'Failed to process user request', {
userId: '123',
requestId: 'abc-xyz'
});
// 4. Pass message with context containing error
PinoWrapper.error('Failed to process user request', {
error,
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
All logging methods support multiple flexible calling patterns:
Standard Log Levels (info, debug, warn, trace)
// Message only
PinoWrapper.info('System started');
// Message with context
PinoWrapper.info('User action completed', { userId: '123', action: 'signup' });
// Object-only (no message)
PinoWrapper.info({ userId: '123', event: 'login', duration: 42 });Error Logging (error, fatal)
// Error object only
PinoWrapper.error(new Error('Database connection failed'));
// Error object with message
PinoWrapper.error(new Error('Connection timeout'), 'Database error');
// Error object, message, and context
PinoWrapper.error(
new Error('Connection timeout'),
'Database error',
{ db: 'users', operation: 'query' }
);
// Message with context containing error
PinoWrapper.error('Database error', {
error: new Error('Connection timeout'),
db: 'users',
operation: 'query'
});
// Message with string error in context
PinoWrapper.error('API error', {
error: 'Rate limit exceeded',
endpoint: '/users'
});
// Object-only with error property
PinoWrapper.error({
error: new Error('Authentication failed'),
userId: '123',
attempt: 3
});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
- Choose the error logging pattern that's most readable for your use case
- Add relevant context to error logs
- Use appropriate log levels based on error severity
Consistency
- Choose a consistent logging style throughout your application
- For object-only logging, use descriptive property names
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.