@vantor/logger
v1.0.1
Published
High-performance structured logger with levels, transports and buffering
Maintainers
Readme
@libs-ts/logger
📝 Lightweight structured logger with levels and transports
Production-ready logging for Node.js and TypeScript applications with structured output, multiple log levels, and customizable transports.
✨ Features
- ✅ Log levels - debug, info, warn, error
- 📊 Structured logging - JSON output with context
- 🎯 TypeScript - Full type safety
- 🔌 Transports - Pluggable output destinations
- 🏷️ Context - Attach metadata to all logs
- ⚡ Lightweight - <3KB minified
- 📦 Zero dependencies
📦 Installation
npm install @libs-ts/logger
pnpm add @libs-ts/logger
yarn add @libs-ts/logger🚀 Quick Start
import { createLogger } from '@libs-ts/logger';
const logger = createLogger({ level: 'info' });
logger.info('Server started', { port: 3000 });
logger.warn('High memory usage', { usage: '85%' });
logger.error('Database connection failed', { error: err });📚 API Reference
createLogger(options?)
Create a new logger instance.
Options:
{
level?: 'debug' | 'info' | 'warn' | 'error'; // Minimum log level
context?: Record<string, any>; // Default context
}Logger Methods
logger.debug(message: string, context?: Record<string, any>): void
logger.info(message: string, context?: Record<string, any>): void
logger.warn(message: string, context?: Record<string, any>): void
logger.error(message: string, context?: Record<string, any>): voidlogger.addTransport(transport)
Add a custom transport function.
logger.addTransport((entry) => {
// entry: { level, message, timestamp, context }
console.log(JSON.stringify(entry));
});🎯 Usage Examples
Basic Logging
import { createLogger } from '@libs-ts/logger';
const logger = createLogger();
logger.info('Application started');
logger.debug('Debug information', { userId: 123 });
logger.warn('Deprecated API used');
logger.error('Failed to process', { error: 'Connection timeout' });With Context
const logger = createLogger({
level: 'info',
context: {
service: 'api-server',
version: '1.0.0',
environment: process.env.NODE_ENV
}
});
// All logs will include the context
logger.info('Request received', { method: 'GET', path: '/api/users' });
// Output includes: service, version, environment, method, pathCustom Transports
import { createLogger, Logger } from '@libs-ts/logger';
import { writeFileSync, appendFileSync } from 'fs';
const logger = createLogger({ level: 'debug' });
// File transport
logger.addTransport((entry) => {
const line = JSON.stringify(entry) + '\n';
appendFileSync('app.log', line);
});
// HTTP transport (send to logging service)
logger.addTransport(async (entry) => {
if (entry.level === 'error') {
await fetch('https://logs.example.com/ingest', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(entry)
});
}
});
// Slack transport for errors
logger.addTransport(async (entry) => {
if (entry.level === 'error') {
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'POST',
body: JSON.stringify({
text: `🚨 Error: ${entry.message}`,
attachments: [{
color: 'danger',
fields: Object.entries(entry.context || {}).map(([key, value]) => ({
title: key,
value: String(value),
short: true
}))
}]
})
});
}
});💡 Advanced Examples
Express.js Integration
import express from 'express';
import { createLogger } from '@libs-ts/logger';
const app = express();
const logger = createLogger({
context: { service: 'express-api' }
});
// Request logging middleware
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
logger.info('Request completed', {
method: req.method,
path: req.path,
status: res.statusCode,
duration: `${duration}ms`
});
});
next();
});
// Error logging middleware
app.use((err, req, res, next) => {
logger.error('Request failed', {
error: err.message,
stack: err.stack,
method: req.method,
path: req.path
});
res.status(500).json({ error: 'Internal Server Error' });
});
app.listen(3000, () => {
logger.info('Server started', { port: 3000 });
});Database Query Logging
import { createLogger } from '@libs-ts/logger';
const logger = createLogger({
level: 'debug',
context: { component: 'database' }
});
async function queryWithLogging(sql: string, params: any[]) {
const start = Date.now();
try {
logger.debug('Executing query', { sql, params });
const result = await db.query(sql, params);
const duration = Date.now() - start;
logger.debug('Query completed', {
sql,
duration: `${duration}ms`,
rows: result.rowCount
});
return result;
} catch (error) {
logger.error('Query failed', {
sql,
params,
error: error.message
});
throw error;
}
}Microservices Logging
import { createLogger } from '@libs-ts/logger';
class UserService {
private logger = createLogger({
context: {
service: 'user-service',
version: '2.1.0'
}
});
async createUser(data: any) {
this.logger.info('Creating user', { email: data.email });
try {
const user = await db.users.create(data);
this.logger.info('User created', { userId: user.id, email: user.email });
return user;
} catch (error) {
this.logger.error('Failed to create user', {
email: data.email,
error: error.message
});
throw error;
}
}
async deleteUser(userId: string) {
this.logger.warn('Deleting user', { userId });
await db.users.delete(userId);
this.logger.info('User deleted', { userId });
}
}Correlation ID Tracking
import { AsyncLocalStorage } from 'async_hooks';
import { createLogger } from '@libs-ts/logger';
const asyncStorage = new AsyncLocalStorage();
function getCorrelationId(): string {
return asyncStorage.getStore() as string || 'unknown';
}
const logger = createLogger();
// Override transport to add correlation ID
const originalTransport = logger['consoleTransport'];
logger.addTransport((entry) => {
const correlationId = getCorrelationId();
originalTransport({
...entry,
context: { ...entry.context, correlationId }
});
});
// Middleware
app.use((req, res, next) => {
const correlationId = req.headers['x-correlation-id'] || crypto.randomUUID();
asyncStorage.run(correlationId, () => next());
});
// Usage - correlation ID automatically included
app.get('/api/users', (req, res) => {
logger.info('Fetching users');
// Log includes correlationId automatically
});🎨 Production Setup
import { createLogger } from '@libs-ts/logger';
import { writeFileSync } from 'fs';
import { join } from 'path';
const isProd = process.env.NODE_ENV === 'production';
const logger = createLogger({
level: isProd ? 'info' : 'debug',
context: {
env: process.env.NODE_ENV,
hostname: process.env.HOSTNAME,
pid: process.pid
}
});
// Production: JSON to file
if (isProd) {
logger.addTransport((entry) => {
const logFile = join(__dirname, 'logs', `app-${new Date().toISOString().split('T')[0]}.log`);
writeFileSync(logFile, JSON.stringify(entry) + '\n', { flag: 'a' });
});
}
export { logger };🤝 Contributing
Contributions welcome! Please open an issue or PR.
📄 License
MIT
Made with ❤️ for production-ready logging
