Loggers
Understanding the Logger class and how to use it effectively.
What is a Logger?
A Logger is the main interface for logging in jslog. It accepts a Handler that determines how and where log records are processed.
import { Logger, TextHandler } from '@omdxp/jslog';
const logger = new Logger(new TextHandler());
Creating Loggers
Using the New Function
import { New, JSONHandler } from '@omdxp/jslog';
const logger = New(new JSONHandler());
Using the Constructor
import { Logger, ColorHandler } from '@omdxp/jslog';
const logger = new Logger(new ColorHandler());
Using the Default Logger
import { Default } from '@omdxp/jslog';
const logger = Default(); // Returns singleton default logger
Logging Methods
Basic Logging
logger.debug(msg, ...attrs); // DEBUG level
logger.info(msg, ...attrs); // INFO level
logger.warn(msg, ...attrs); // WARN level
logger.error(msg, ...attrs); // ERROR level
With Attributes
import { String, Int, Bool } from '@omdxp/jslog';
logger.info('User action',
String('action', 'login'),
String('user', 'alice'),
Int('attempts', 3),
Bool('success', true)
);
Generic Log Method
import { Level } from '@omdxp/jslog';
logger.log(Level.WARN, 'Custom level log', String('key', 'value'));
Context Methods
Adding Persistent Attributes
Create a new logger with additional attributes:
import { String } from '@omdxp/jslog';
const baseLogger = New(new TextHandler());
// Create logger with request context
const requestLogger = baseLogger.with(
String('request_id', 'req-123'),
String('user_id', 'user-456')
);
requestLogger.info('Processing request');
// Output includes: request_id="req-123" user_id="user-456"
Adding Groups
Organize related attributes:
const dbLogger = baseLogger.withGroup('database');
dbLogger.info('Connected', String('host', 'localhost'));
// Output: database.host="localhost"
// Nested groups
const poolLogger = dbLogger.withGroup('pool');
poolLogger.info('Created', Int('size', 10));
// Output: database.pool.size=10
Checking if a Level is Enabled
Avoid expensive operations when logging is disabled:
import { Level } from '@omdxp/jslog';
if (logger.enabled(Level.DEBUG)) {
const expensiveData = computeExpensiveDebugInfo();
logger.debug('Debug info', Any('data', expensiveData));
}
Context Methods (Future Context Support)
These methods are placeholders for future context support:
logger.debugContext(msg, ...attrs);
logger.infoContext(msg, ...attrs);
logger.warnContext(msg, ...attrs);
logger.errorContext(msg, ...attrs);
Currently, they behave the same as their non-context counterparts.
Logger Composition
Create specialized loggers for different parts of your application:
// Base logger
const appLogger = New(new JSONHandler({ level: Level.INFO }));
// Service-specific loggers
const authLogger = appLogger.withGroup('auth');
const dbLogger = appLogger.withGroup('database');
const apiLogger = appLogger.withGroup('api');
// Use them independently
authLogger.info('User authenticated', String('user', 'alice'));
dbLogger.warn('Slow query', Int('duration_ms', 1500));
apiLogger.error('Request failed', Int('status', 500));
Best Practices
1. Use Structured Attributes
// ❌ Bad: String interpolation
logger.info(`User ${userId} logged in from ${ip}`);
// ✅ Good: Structured attributes
logger.info('User logged in', String('user_id', userId), String('ip', ip));
2. Create Logger Hierarchies
const rootLogger = New(new JSONHandler());
const serviceLogger = rootLogger.withGroup('myservice');
const requestLogger = serviceLogger.with(String('version', '1.0.0'));
3. Check Level Before Expensive Operations
if (logger.enabled(Level.DEBUG)) {
logger.debug('State', Any('state', complexObject));
}
4. Use Appropriate Log Levels
- DEBUG: Detailed information for debugging
- INFO: General informational messages
- WARN: Warning messages for potentially harmful situations
- ERROR: Error messages for failures
Next Steps
- Handlers - Learn about different handler types
- Attributes - Master attribute types and usage
- Levels - Understand log levels in depth