@vepler/logger
TypeScript icon, indicating that this package has built-in type declarations

3.0.0 • Public • Published

@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.

npm version TypeScript License: MIT

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.log but better

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'
});

// 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

  1. Initialization

    • Initialize the logger once at application startup
    • Configure appropriate log levels for different environments
  2. 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
  3. 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
  4. Consistency

    • Choose a consistent logging style throughout your application
    • For object-only logging, use descriptive property names
  5. 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:

  1. Push your changes
  2. 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.

Package Sidebar

Install

npm i @vepler/logger

Weekly Downloads

141

Version

3.0.0

License

MIT

Unpacked Size

29.9 kB

Total Files

6

Last publish

Collaborators

  • aashman016
  • nikic
  • andrei.hudovich