Logger Providers
Logger providers are responsible for processing and outputting log messages to various destinations. Vercube includes two built-in providers and allows you to create custom providers.
Built-in Providers
ConsoleProvider
The ConsoleProvider
outputs log messages to the console with color-coded levels.
typescript
export function useContainer(container: Container): Container {
// Bind the logger to the container
container.bind(Logger, BaseLogger);
// Configure the logger
container.get(Logger).configure({
logLevel: 'info',
providers: [
{
name: 'console',
provider: ConsoleProvider,
logLevel: 'debug'
}
]
});
}
Features:
- Color-coded log levels
- Configurable timestamp format
- Pretty-printed objects
- Stack trace formatting for errors
JSONProvider
The JSONProvider
formats log messages as JSON, making them suitable for log aggregation systems.
typescript
export function useContainer(container: Container): Container {
// Bind the logger to the container
container.bind(Logger, BaseLogger);
// Configure the logger
container.get(Logger).configure({
logLevel: 'info',
providers: [
{
name: 'console',
provider: JSONProvider,
logLevel: 'debug'
}
]
});
}
Features:
- Structured JSON output
- Configurable pretty printing
- Timestamp inclusion
- Error serialization
Creating Custom Providers
To create a custom provider, extend the LoggerProvider
abstract class:
typescript
import { LoggerProvider, LoggerTypes } from '@vercube/logger';
class CustomProvider extends LoggerProvider {
private options: LoggerTypes.ProviderOptions = {};
initialize(options: LoggerTypes.ProviderOptions): void {
this.options = options;
// Initialize your provider
}
processMessage(message: LoggerTypes.LogMessage): void {
// Process and output the log message
console.log(`[${message.level}] ${message.message}`);
if (message.args.length > 0) {
console.log('Additional args:', message.args);
}
}
}
Provider Interface
typescript
abstract class LoggerProvider {
abstract initialize(options: LoggerTypes.ProviderOptions): void;
abstract processMessage(message: LoggerTypes.LogMessage): void;
}
Log Message Structure
typescript
interface LogMessage {
level: 'debug' | 'info' | 'warn' | 'error';
message: string;
args: any[];
timestamp: Date;
}
Example: File Provider
Here's an example of a custom provider that writes logs to a file:
typescript
import { LoggerProvider, LoggerTypes } from '@vercube/logger';
import * as fs from 'fs';
import * as path from 'path';
class FileProvider extends LoggerProvider {
private fileStream: fs.WriteStream;
private options: LoggerTypes.ProviderOptions = {
filename: 'app.log',
directory: './logs'
};
initialize(options: LoggerTypes.ProviderOptions): void {
this.options = { ...this.options, ...options };
// Ensure log directory exists
if (!fs.existsSync(this.options.directory)) {
fs.mkdirSync(this.options.directory, { recursive: true });
}
// Create write stream
const filePath = path.join(this.options.directory, this.options.filename);
this.fileStream = fs.createWriteStream(filePath, { flags: 'a' });
}
processMessage(message: LoggerTypes.LogMessage): void {
const logEntry = {
timestamp: message.timestamp.toISOString(),
level: message.level,
message: message.message,
args: message.args
};
this.fileStream.write(JSON.stringify(logEntry) + '\n');
}
}
Using Custom Providers with DI
typescript
export function useContainer(container: Container): Container {
// Bind the logger to the container
container.bind(Logger, BaseLogger);
// Configure the logger
container.get(Logger).configure({
logLevel: 'info',
providers: [
{
name: 'file',
provider: FileProvider,
options: {
filename: 'app.log',
directory: './logs'
}
}
]
});
}
Best Practices
Error Handling
- Handle initialization errors gracefully
- Implement proper cleanup in case of errors
- Log provider errors without causing infinite loops
Performance
- Use asynchronous operations for I/O
- Implement buffering for high-volume logging
- Consider using streams for file output
Configuration
- Provide sensible defaults
- Validate configuration options
- Document all available options
Testing
- Write unit tests for your provider
- Test different log levels
- Test error scenarios
- Test configuration options
Dependency Injection
- Bind providers to the DI container
- Use the container to resolve providers
- Inject providers into services that need them
See Also
- Logger - The main Logger class
- Types - Type definitions
- Advanced Topics - Advanced usage patterns