npm.io
1.0.5 • Published yesterdayCLI

@libster/loggy

Licence
MIT
Version
1.0.5
Deps
2
Size
55 kB
Vulns
0
Weekly
0

Loggy

A clean and formatted logging library for Node.js applications with automatic redaction, Express middleware support, and CLI tools.

Features

  • Beautiful formatting - Colored, human-readable logs with timestamps and icons
  • Automatic redaction - Sensitive data like passwords and tokens are automatically redacted
  • Multiple output modes - Pretty format for development, JSON for production
  • Express middleware - Built-in request logging middleware
  • CLI tool - Format and clean logs from files or stdin
  • TypeScript support - Full TypeScript definitions included
  • Small dependency footprint - Only chalk and commander at runtime

Installation

Using npm
npm install @libster/loggy
Using yarn
yarn add @libster/loggy
Using pnpm
pnpm add @libster/loggy

Quick Start

Basic Usage
import { createLogger } from '@libster/loggy';

const logger = createLogger();

logger.info('User logged in', { userId: 123, username: 'john' });
logger.warn('Rate limit approaching', { requests: 95, limit: 100 });
logger.error('Database connection failed', { error: 'Connection timeout' });
Output Example
[2025-09-12T10:15:00.000Z] INFO  ℹ️ User logged in
  Metadata: {
    "userId": 123,
    "username": "john"
  }
[2025-09-12T10:15:01.000Z] WARN  ⚠️ Rate limit approaching
  Metadata: {
    "requests": 95,
    "limit": 100
  }
[2025-09-12T10:15:02.000Z] ERROR ❌ Database connection failed
  Metadata: {
    "error": "Connection timeout"
  }
With Configuration
import { createLogger } from '@libster/loggy';

const logger = createLogger({
  mode: 'json',           // 'pretty' or 'json'
  level: 'debug',         // 'debug', 'info', 'warn', 'error'
  redact: ['password', 'token', 'secret'], // Custom redaction keys
  timestamp: true         // Include timestamps
});

logger.info('User login', { 
  user: 'john', 
  password: 'secret123'  // Will be redacted as "****"
});
Child loggers and custom transports

Attach shared context without mutating the parent logger. A custom transport receives already-redacted structured entries.

const logger = createLogger({
  bindings: { service: 'users-api', environment: 'production' },
  transport: entry => sendToLogCollector(entry)
});

const requestLogger = logger.child({ requestId: 'req_123' });
requestLogger.info('Profile loaded', { userId: 42 });

API Reference

Logger Methods
logger.info(message, metadata?)

Log an info message with optional metadata.

logger.warn(message, metadata?)

Log a warning message with optional metadata.

logger.error(message, metadata?, error?)

Log an error message with optional metadata and Error object.

logger.debug(message, metadata?)

Log a debug message with optional metadata.

Legacy Methods

For backward compatibility, these methods are also available:

  • logger.logInfo(message, metadata?)
  • logger.logWarn(message, metadata?)
  • logger.logError(message, metadata?, error?)
  • logger.logDebug(message, metadata?)
Configuration Options
interface LoggerConfig {
  mode?: 'pretty' | 'json';        // Output format
  level?: 'debug' | 'info' | 'warn' | 'error';  // Minimum log level
  redact?: string[];               // Custom keys to redact
  timestamp?: boolean;             // Include timestamps
}

Express Middleware

Loggy includes a built-in Express middleware for request logging:

import express from 'express';
import { loggerMiddleware } from '@libster/loggy';

const app = express();

// Basic usage
app.use(loggerMiddleware());

// With configuration
app.use(loggerMiddleware({
  mode: 'json',
  skip: (req, res) => req.url === '/health', // Skip health checks
  requestId: req => req.get('X-Request-ID')
}));

app.get('/users', (req, res) => {
  res.json({ users: [] });
});

This will log requests like:

[2023-12-01T10:15:00Z] INFO GET /users 200 45ms
Middleware Configuration
interface MiddlewareConfig extends LoggerConfig {
  skip?: (req: Request, res: Response) => boolean;
  requestId?: (req: Request) => string | undefined;
}

CLI Tool

Loggy includes a CLI tool for formatting logs from files or stdin:

Basic Usage
# Format logs from stdin
cat logs.json | npx @libster/loggy --pretty

# Format logs from a file
npx @libster/loggy --file logs.json --pretty

# Output as JSON
npx @libster/loggy --file logs.json --json

# Custom redaction keys
npx @libster/loggy --file logs.json --redact password,token,secret --pretty
CLI Options
  • -p, --pretty - Output in pretty format (default)
  • -j, --json - Output in JSON format
  • -r, --redact <keys> - Comma-separated list of keys to redact
  • -f, --file <path> - Read from file instead of stdin
  • --no-timestamp - Disable timestamps
  • -l, --level <level> - Minimum log level (debug, info, warn, error)
Examples
# Pretty format with custom redaction
cat app.log | npx @libster/loggy --pretty --redact password,api_key

# JSON format for log aggregation
npx @libster/loggy --file app.log --json --level warn

# Process multiple files
for file in logs/*.log; do
  npx @libster/loggy --file "$file" --pretty
done

Automatic Redaction

Loggy automatically redacts sensitive data in your logs. By default, it redacts:

  • password
  • token
  • secret
  • apikey
  • api_key
  • auth
  • authorization
Example
const logger = createLogger();

logger.info('User login', {
  username: 'john',
  password: 'secret123',    // Redacted as "****"
  email: 'john@example.com',
  token: 'abc123'          // Redacted as "****"
});

Output:

[2023-12-01T10:15:00Z] INFO ℹ️ User login
  Metadata: {
    "username": "john",
    "password": "****",
    "email": "john@example.com",
    "token": "****"
  }
Custom Redaction
const logger = createLogger({
  redact: ['password', 'token', 'custom_secret']
});

Custom keys extend the default list. Configure redactionReplacement to change the default **** mask. Logging safely handles circular references and limits metadata traversal to 20 levels by default (maxDepth).

Error Handling

Loggy provides enhanced error formatting with stack trace highlighting:

const logger = createLogger();

try {
  throw new Error('Something went wrong');
} catch (error) {
  logger.error('Operation failed', { operation: 'user_create' }, error);
}

This will:

  • Highlight your application code in stack traces
  • Fade out Node.js internal lines
  • Include error name, message, and formatted stack trace

Output Modes

Pretty Mode (Development)
[2023-12-01T10:15:00Z] INFO ℹ️ User logged in
  Metadata: {
    "userId": 123,
    "username": "john"
  }
JSON Mode (Production)
{"timestamp":"2023-12-01T10:15:00.000Z","level":"info","message":"User logged in","metadata":{"userId":123,"username":"john"}}

Log Levels

Loggy supports four log levels with filtering:

  • debug - Detailed information for debugging
  • info - General information about application flow
  • warn - Warning messages for potentially harmful situations
  • error - Error events that might still allow the application to continue

Set the minimum log level to filter out less important messages:

const logger = createLogger({ level: 'warn' });

logger.debug('This will not be logged');
logger.info('This will not be logged');
logger.warn('This will be logged');
logger.error('This will be logged');

TypeScript Support

Loggy is written in TypeScript and includes full type definitions:

import { createLogger, Logger, LoggerConfig } from '@libster/loggy';

const config: LoggerConfig = {
  mode: 'json',
  level: 'info'
};

const logger: Logger = createLogger(config);

Examples

Express Application
import express from 'express';
import { createLogger, loggerMiddleware } from '@libster/loggy';

const app = express();
const logger = createLogger({ mode: 'json' });

app.use(loggerMiddleware({ mode: 'json' }));

app.get('/users/:id', (req, res) => {
  const userId = req.params.id;
  
  logger.info('Fetching user', { userId });
  
  // Your logic here
  res.json({ id: userId, name: 'John' });
});

app.listen(3000, () => {
  logger.info('Server started', { port: 3000 });
});
Error Handling
import { createLogger } from '@libster/loggy';

const logger = createLogger();

async function processUser(userId: string) {
  try {
    logger.info('Processing user', { userId });
    
    // Simulate some work
    if (Math.random() > 0.5) {
      throw new Error('Processing failed');
    }
    
    logger.info('User processed successfully', { userId });
  } catch (error) {
    logger.error('Failed to process user', { userId }, error as Error);
    throw error;
  }
}
Custom Redaction
import { createLogger } from '@libster/loggy';

const logger = createLogger({
  redact: ['password', 'ssn', 'credit_card', 'api_key']
});

logger.info('Payment processed', {
  userId: 123,
  amount: 99.99,
  credit_card: '4111-1111-1111-1111',  // Redacted
  api_key: 'sk-1234567890'             // Redacted
});

Development

Building
npm run build
Testing
npm test
npm run test:coverage
Linting
npm run lint
npm run lint:fix
Formatting
npm run format
npm run format:check

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request
Development Setup
git clone https://github.com/vijoy-paul/libster-loggy.git
cd loggy
npm install
npm run build
npm test

License

MIT License - see LICENSE file for details.

Changelog

1.0.0
  • Initial release
  • Core logging functionality
  • Automatic redaction
  • Express middleware
  • CLI tool
  • TypeScript support
  • Comprehensive test suite

Keywords