MagicLogger API Documentation
A comprehensive guide to using the MagicLogger API with transports, context, and rich formatting.
Table of Contents
- Installation
- Getting Started
- Logger Configuration
- Basic Logging
- Context & Metadata
- Transports
- Advanced Logging
- Styling and Formatting
- File Operations
- Browser Operations
- Progress Tracking
- Configuration Methods
- Available Colors and Styles
- API Reference
Installation
npm install magiclogger
Optional Dependencies
For specific transports, install the required dependencies:
# For S3 transport
npm install @aws-sdk/client-s3 @aws-sdk/lib-storage
# For MongoDB transport
npm install mongodb
# For WebSocket transport (Node.js)
npm install ws
# For HTTP transport (Node.js)
npm install axios form-data
Getting Started
import { Logger } from 'magiclogger';
// Create a logger with zero config (uses default console transport)
const logger = new Logger();
// Or with configuration
const logger = new Logger({
id: 'my-service',
tags: ['production', 'api'],
context: {
service: 'user-api',
version: '1.2.3'
}
});
// Basic logging
logger.info('Application started');
Tree-Shakeable Transport Imports
MagicLogger is designed for optimal bundle sizes with tree-shakeable imports:
Import Patterns
// ✅ Main logger (always needed)
import { Logger } from 'magiclogger';
// ✅ Tree-shakeable transports (import only what you need)
import {
ConsoleTransport,
FileTransport,
HTTPTransport,
S3Transport,
MongoDBTransport
} from 'magiclogger/transports';
// ✅ Convenience factories (recommended)
import {
createConsole,
createFile,
createHTTP
} from 'magiclogger/transports';
Transport Categories
Core Transports (no external dependencies):
ConsoleTransport
- Terminal output with colors (~2KB)FileTransport
- File logging with rotation (~3KB)StreamTransport
- Write to any Node.js stream (~1KB)HTTPTransport
- REST API endpoints (~4KB)
Optional Transports (require external dependencies):
S3Transport
- AWS S3 logging (+~500KB aws-sdk)MongoDBTransport
- MongoDB logging (+~2MB mongodb)WebSocketTransport
- Real-time logging (+~50KB ws)
Factory Functions
Convenience factories provide smart defaults and async initialization:
import { createConsole, createFile, createHTTP } from 'magiclogger/transports';
const logger = new Logger();
// Auto-generated names, optimized configurations
logger.addTransport(await createConsole()); // name: 'console'
logger.addTransport(await createFile('./logs/app.log')); // name: 'file-app-log'
logger.addTransport(await createHTTP('https://api.logs.com')); // name: 'http-api.logs.com'
Logger Configuration
ExtendedLoggerOptions
interface ExtendedLoggerOptions extends LoggerOptions {
// Identity & Context
id?: string; // Logger instance ID
tags?: string[]; // Global tags for all logs
context?: Record<string, any>; // Global context for all logs
// Transports
transports?: Transport[]; // Array of transports
// Behavior
verbose?: boolean; // Show debug logs
useColors?: boolean; // Enable colors (console)
theme?: string | ThemeDefinition; // Color theme
// Advanced
idGenerator?: () => string; // Custom ID generator
useLegacyOutput?: boolean; // Use legacy console/file output
// Legacy options (backward compatibility)
writeToDisk?: boolean; // Enable file logging
logDir?: string; // Log directory
logRetentionDays?: number; // Days to retain logs
storeInBrowser?: boolean; // Enable browser storage
maxStoredLogs?: number; // Max logs in browser storage
storageName?: string; // Browser storage key name
}
Quick Setup with createLogger
import { createLogger } from 'magiclogger';
const logger = createLogger('my-service', {
console: true, // or ConsoleTransportOptions
file: './logs/app.log', // or FileTransportOptions
http: 'https://logs.example.com', // or HTTPTransportOptions
s3: { bucket: 'my-logs' }, // S3TransportOptions
mongodb: { url: 'mongodb://...' }, // MongoDBTransportOptions
level: 'debug',
tags: ['api', 'v2'],
context: { region: 'us-east-1' }
});
Basic Logging
All logging methods now accept an optional metadata parameter:
// Simple messages
logger.info('User logged in');
logger.warn('High memory usage');
logger.error('Connection failed');
logger.debug('Cache hit ratio: 0.85');
logger.success('Deployment completed');
// With metadata/context
logger.info('User logged in', { userId: '123', ip: '10.0.0.1' });
logger.warn('High memory usage', { usage: '85%', threshold: '80%' });
logger.error('Connection failed', new Error('Timeout'));
logger.debug('Cache stats', { hits: 850, misses: 150, ratio: 0.85 });
logger.success('Order processed', { orderId: 'ORD-123', amount: 99.99 });
// Universal log method
logger.log('Custom message', 'info'); // level as second parameter
logger.log('Debug info', 'debug', { details: 'here' }); // with metadata
Context & Metadata
Global Context
Set default context that applies to all logs:
const logger = new Logger({
id: 'payment-service',
tags: ['payments', 'critical'],
context: {
service: 'payment-api',
version: '2.1.0',
environment: 'production',
hostname: process.env.HOSTNAME
}
});
// All logs include global context
logger.info('Service started');
Per-Log Context
Add specific context to individual logs:
// Metadata is merged with global context
logger.info('Payment processed', {
orderId: 'ORD-123',
customerId: 'CUST-456',
amount: 99.99,
currency: 'USD',
processingTime: 234
});
Error Handling
Errors are automatically extracted and structured:
// Pass error directly
logger.error('Operation failed', new Error('Invalid input'));
// Or include in metadata
logger.error('Payment failed', {
error: new Error('Card declined'),
orderId: 'ORD-123',
customerId: 'CUST-456'
});
// Multiple errors
logger.error('Multiple failures', {
errors: [error1, error2],
context: 'batch-processing'
});
Custom ID Generation
import { v4 as uuidv4 } from 'uuid';
// UUID-based IDs
const logger = new Logger({
idGenerator: () => uuidv4()
});
// Sequential IDs
const logger = new Logger({
idGenerator: (() => {
let counter = 0;
return () => `log-${++counter}-${Date.now()}`;
})()
});
Correlation IDs
// Request middleware
app.use((req, res, next) => {
const correlationId = req.headers['x-correlation-id'] || uuidv4();
req.logger = new Logger({
context: {
correlationId,
requestId: uuidv4(),
method: req.method,
path: req.path
}
});
next();
});
Transports
Transports
Adding Transports
import { Logger } from 'magiclogger';
import {
ConsoleTransport,
FileTransport,
HTTPTransport,
S3Transport
} from 'magiclogger/transports';
// At initialization
const logger = new Logger({
transports: [
new ConsoleTransport({ level: 'debug' }),
new FileTransport({ filepath: './logs' })
]
});
// Dynamically
await logger.addTransport(new HTTPTransport({
url: 'https://logs.example.com',
auth: { type: 'bearer', token: 'secret' }
}), 10); // priority: 10
// Using convenience factories (recommended)
import { createConsole, createFile, createHTTP } from 'magiclogger/transports';
const logger = new Logger({
transports: [
await createConsole({ level: 'debug' }),
await createFile('./logs/app.log')
]
});
### OTLP (OpenTelemetry) Transport
```typescript
import { Logger } from 'magiclogger';
import { OTLPTransport, createOTLPTransport } from 'magiclogger/transports/otlp';
// Direct
const loggerA = new Logger({
transports: [
new OTLPTransport({
name: 'otlp',
serviceName: 'orders',
endpoint: 'http://localhost:4318',
protocol: 'http/protobuf',
includeTraceContext: true,
resource: {
'service.version': '1.0.0',
'deployment.environment': 'dev'
}
})
]
});
// Helper
const loggerB = new Logger({
transports: [createOTLPTransport('billing', { endpoint: 'http://localhost:4318' })]
});
Transport Management
// List all transports
const transportNames = logger.listTransports();
// ['console', 'file', 'http']
// Get specific transport
const httpTransport = logger.getTransport('http');
// Remove transport
await logger.removeTransport('file');
// Get statistics
const stats = logger.getTransportStats();
// { console: { logged: 1234, errors: 0 }, ... }
Common Transport Configurations
// Console with colors
new ConsoleTransport({
name: 'console',
level: 'debug',
useColors: true,
formatter: 'pretty' // or 'json', 'simple'
});
// File with rotation
new FileTransport({
name: 'file',
filepath: './logs',
rotation: 'daily', // or 'size', 'hourly'
maxFiles: 7,
maxSize: '10MB',
compress: true
});
// HTTP with batching
new HTTPTransport({
name: 'http',
url: 'https://logs.example.com',
method: 'POST',
auth: {
type: 'bearer',
token: process.env.LOG_TOKEN
},
maxBatchSize: 100,
maxBatchTime: 5000,
retry: {
maxRetries: 3,
initialDelay: 1000
}
});
// S3 with compression
new S3Transport({
name: 's3',
bucket: 'my-logs',
region: 'us-east-1',
prefix: 'app-logs/',
compress: true,
encryption: {
type: 'AES256'
}
});
Advanced Logging
Custom Styling (Legacy)
These methods still work for backward compatibility:
// Custom colors with prefix
logger.custom('Build complete', ['green', 'bold'], 'BUILD');
logger.custom('Network error', ['red'], 'NET');
// Preset styles
logger.styled('Important notice', 'important');
logger.styled('Debug info', 'muted');
Styling and Formatting
Built-in Formatters
MagicLogger provides multiple output formatters selectable per transport:
- PlainTextFormatter (human readable; presets: simple, detailed, syslog, apache, minimal)
- JSONFormatter (structured / NDJSON; presets: compact, pretty, flat, minimal, extended)
- XMLFormatter (XML elements or full document via formatBatch)
- CSVFormatter (tabular CSV; header + rows; good for spreadsheets / BI)
- CustomFormatter base (extend to build YAML, HTML, etc.)
For deep usage examples, options, escaping rules, and conversion guidance see docs/formatters.md
.
Color Factory - Create Reusable Styles
The color()
method creates a reusable function for styling text:
// Create style functions
const highlight = logger.color('yellow', 'bold');
const error = logger.color('red', 'underline');
const code = logger.color('cyan');
const success = logger.color('green', 'bold');
// Use them in your logs
logger.info(`Run ${code('npm install')} to install dependencies`);
logger.info(`The ${highlight('important')} part is here`);
logger.error(`${error('Failed')} to connect to database`);
logger.success(`Deployment ${success('completed successfully')}`);
// Combine multiple styled parts
const userId = logger.color('cyan', 'bold');
const timestamp = logger.color('gray');
const status = logger.color('green');
logger.info(
`User ${userId('user-123')} logged in at ${timestamp('10:30:45')} - Status: ${status('active')}`
);
Color Parts - Style Specific Words
The colorParts()
method styles specific parts of a message:
// Basic usage
logger.info(
logger.colorParts('Processing file: data.json (1.2MB) - Status: OK', {
'data.json': ['yellow', 'underline'],
'1.2MB': ['cyan'],
'OK': ['green', 'bold']
})
);
// Complex example
const message = 'User john_doe performed action: DELETE on resource: /api/users/123 at 2024-01-15 10:30:45';
logger.warn(
logger.colorParts(message, {
'john_doe': ['cyan', 'bold'],
'DELETE': ['red', 'bold'],
'/api/users/123': ['yellow'],
'2024-01-15 10:30:45': ['gray']
})
);
// Error highlighting
logger.error(
logger.colorParts('Failed to connect to database postgres://localhost:5432 after 3 retries', {
'Failed': ['red', 'bold'],
'postgres://localhost:5432': ['yellow', 'underline'],
'3 retries': ['brightRed']
})
);
Combining Styling Methods
You can combine different styling approaches:
// Create reusable styles
const highlight = logger.color('yellow', 'bold');
const code = logger.color('cyan');
const error = logger.color('red', 'bold');
// Use with colorParts for complex styling
const message = `Run ${code('npm start')} to start the server on port 3000`;
logger.info(
logger.colorParts(message, {
'3000': ['brightGreen', 'bold']
})
);
// Or build complex messages
logger.info([
'Deployment',
highlight('completed'),
'in',
code('2.5s'),
'with',
logger.color('green')('0 errors')
].join(' '));
Section Headers
Create visually distinct section headers:
logger.header('DEPLOYMENT PROCESS');
logger.header('Test Results', ['white', 'bgGreen', 'bold']);
logger.header('⚠️ WARNING ⚠️', ['yellow', 'bgRed', 'bold']);
Data Tables
Format tabular data for better readability:
logger.table([
{ name: 'Service A', status: 'healthy', uptime: '99.9%', requests: 15234 },
{ name: 'Service B', status: 'degraded', uptime: '95.2%', requests: 8921 },
{ name: 'Service C', status: 'healthy', uptime: '99.8%', requests: 22847 }
]);
// With custom header colors
logger.table(
[
{ id: 1, product: 'Widget', price: 19.99, stock: 150 },
{ id: 2, product: 'Gadget', price: 39.99, stock: 75 },
{ id: 3, product: 'Doohickey', price: 9.99, stock: 0 }
],
['brightCyan', 'bold', 'underline'] // Header styling
);
Links
Make URLs and file paths clickable in supported terminals:
logger.link('https://docs.example.com', 'View documentation');
logger.link('/var/log/app.log', 'Log file location');
logger.link('file:///C:/logs/error.log', 'Windows log file');
// In messages
const docsUrl = 'https://docs.example.com/api';
logger.info(`For more information, visit: ${docsUrl}`);
logger.link(docsUrl);
Progress Tracking
MagicLogger supports in-terminal progress rendering in Node environments and provides a browser-safe no-op wrapper in the website demo. Use the progress helpers to show task advancement and finalize cleanly at 100%.
Progress Bars
// Simple progress bar
for (let i = 0; i <= 100; i += 10) {
logger.progressBar(i);
await delay(100);
}
// Custom progress bar
logger.progressBar(
75, // percentage
30, // bar length
'▓', // complete character
'░' // incomplete character
);
// Different styles
logger.progressBar(50, 40, '=', '-');
logger.progressBar(80, 25, '■', '□');
logger.progressBar(33, 20, '●', '○');
File Operations
Node.js only - manage log files:
// Get current log file path
const logPath = logger.getPath();
console.log(`Logs are being written to: ${logPath}`);
// Get/set log directory
const currentDir = logger.getLogDir();
logger.setLogDir('./logs/production', true); // true = reinitialize
// Get/set retention period
const retentionDays = logger.getLogRetentionDays();
logger.setLogRetentionDays(30, true); // true = clean old logs now
// Enable/disable file logging
logger.setFileLogging(true);
Browser Operations
Browser only - manage localStorage:
// Get all stored logs
const logs = logger.getLogs();
if (logs) {
console.log(`Found ${logs.length} stored logs`);
}
// Clear logs
logger.clearLogs();
// Download logs as file
logger.downloadLogs('debug-logs.txt');
// Enable/disable storage
logger.setStorageEnabled(true);
Configuration Methods
Runtime Configuration
// Verbose mode (show debug logs)
logger.setVerbose(true);
// Colors
logger.setColorsEnabled(false); // Disable colors
// Themes
logger.setTheme({
info: ['cyan', 'bold'],
error: ['red', 'bold', 'underline'],
success: ['green', 'bold'],
warn: ['yellow', 'bold'],
debug: ['gray', 'italic'],
header: ['white', 'bgBlue', 'bold']
});
// Get current theme
const theme = logger.theme;
Environment Variables
// Common patterns
const logger = new Logger({
verbose: process.env.LOG_LEVEL === 'debug',
id: process.env.SERVICE_NAME,
tags: [process.env.NODE_ENV],
context: {
version: process.env.APP_VERSION,
region: process.env.AWS_REGION
},
transports: [
...(process.env.LOG_TO_CONSOLE ? [
new ConsoleTransport({
level: process.env.LOG_LEVEL || 'info'
})
] : []),
...(process.env.LOG_TO_FILE ? [
new FileTransport({
filepath: process.env.LOG_DIR || './logs'
})
] : [])
]
});
Available Colors and Styles
Foreground Colors
- Basic:
black
,red
,green
,yellow
,blue
,magenta
,cyan
,white
,gray
,brightBlack
- Bright:
brightRed
,brightGreen
,brightYellow
,brightBlue
,brightMagenta
,brightCyan
,brightWhite
Background Colors
- Basic:
bgBlack
,bgRed
,bgGreen
,bgYellow
,bgBlue
,bgMagenta
,bgCyan
,bgWhite
,bgGray
- Bright:
bgBrightBlack
,bgBrightRed
,bgBrightGreen
,bgBrightYellow
,bgBrightBlue
,bgBrightMagenta
,bgBrightCyan
,bgBrightWhite
Extra Colors (aliases or 256-color picks)
- Foreground:
orange
,brightOrange
,purple
,brightPurple
,teal
,brightTeal
,pink
,brightPink
,brown
,brightBrown
,indigo
,brightIndigo
,lime
,brightLime
- Background:
bgOrange
,bgBrightOrange
,bgPurple
,bgBrightPurple
,bgTeal
,bgBrightTeal
,bgPink
,bgBrightPink
,bgBrown
,bgBrightBrown
,bgIndigo
,bgBrightIndigo
,bgLime
,bgBrightLime
Text Styles
bold
,dim
,italic
,underline
,blink
,reverse
,hidden
,strikethrough
Style Presets
info
- Cyan, bold text for standard informationsuccess
- Green, bold text for success messageswarning
- Yellow, bold text for warningserror
- Bright red, bold text for errorsdebug
- Gray, italic text for debug messagesimportant
- Magenta, bold, underlined text for critical informationhighlight
- Bright yellow, bold text to highlight informationmuted
- Dimmed text for less important informationspecial
- Bright cyan, bold text for special announcementscode
- Bright green text for code snippetsheader
- White text on blue background for section headers
API Reference
Logger Class
class Logger {
// Constructor
constructor(options?: ExtendedLoggerOptions)
// Logging methods
log(msg: string, level?: LogLevel, meta?: any): void
info(msg: string, meta?: any): void
warn(msg: string, meta?: any): void
error(msg: string, meta?: any): void
debug(msg: string, meta?: any): void
success(msg: string, meta?: any): void
// Transport management
addTransport(transport: Transport, priority?: number): Promise<void>
removeTransport(name: string): Promise<void>
getTransport(name: string): Transport | undefined
listTransports(): string[]
getTransportStats(): Record<string, any>
// Configuration
setVerbose(enabled: boolean): void
setColorsEnabled(enabled: boolean): void
setTheme(theme: Record<string, ColorName[]>): void
get theme(): Record<string, ColorName[]>
// Styling methods
custom(msg: string, colors?: ColorName[], prefix?: string): void
styled(msg: string, preset: StylePreset): void
header(title: string, colors?: ColorName[]): void
table(data: Record<string, any>[], headerColor?: ColorName[]): void
progressBar(progress: number, length?: number, completeChar?: string, incompleteChar?: string): void
link(url: string, description?: string): void
color(...colors: ColorName[]): (text: string) => string
colorParts(message: string, colorMap: Record<string, ColorName[]>): string
// File operations (Node.js)
getPath(): string | null
getLogDir(): string
setLogDir(dir: string, reinitialize?: boolean): void
getLogRetentionDays(): number
setLogRetentionDays(days: number, cleanNow?: boolean): void
setFileLogging(enabled: boolean): void
// Browser operations
getLogs(): string[] | null
clearLogs(): void
downloadLogs(filename?: string): void
setStorageEnabled(enabled: boolean): void
// Static utilities
static normalizePath(path: string): string
static normalizeLineEndings(text: string): string
static isLinkLike(text: string): boolean
static cleanupDirectory(dir: string): void
// Lifecycle
close(): Promise<void>
}
Transport Interface
interface Transport {
name: string
log(entry: LogEntry): Promise<void>
close?(): Promise<void>
}
interface LogEntry {
id: string // Unique entry ID
timestamp: string // ISO 8601 timestamp
timestampMs: number // Unix timestamp (ms)
level: LogLevel // Log level
message: string // Formatted message
plainMessage: string // Message without ANSI
loggerId?: string // Logger instance ID
tags?: string[] // Associated tags
context?: Record<string, any> // Additional context
error?: ErrorInfo // Error details
metadata?: Record<string, any> // Environment metadata
}
Types
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'success'
type ColorName = 'black' | 'red' | 'green' | /* ... */ | 'strikethrough'
type StylePreset = 'info' | 'success' | 'warning' | /* ... */ | 'header'
type IdGenerator = () => string
createLogger Helper
function createLogger(
id: string,
options?: {
console?: boolean | ConsoleTransportOptions
file?: string | FileTransportOptions
http?: string | HTTPTransportOptions
s3?: S3TransportOptions
mongodb?: MongoDBTransportOptions
level?: LogLevel
tags?: string[]
context?: Record<string, any>
verbose?: boolean
}
): Logger
Examples
Production Setup
import { Logger } from 'magiclogger';
import { ConsoleTransport, FileTransport, S3Transport } from 'magiclogger/transports';
const logger = new Logger({
id: process.env.SERVICE_NAME || 'api',
tags: [process.env.NODE_ENV || 'development'],
context: {
version: process.env.APP_VERSION,
region: process.env.AWS_REGION,
instance: process.env.INSTANCE_ID
},
idGenerator: () => `${Date.now()}-${process.pid}-${Math.random().toString(36).substr(2, 9)}`,
transports: [
// Console for development
...(process.env.NODE_ENV !== 'production' ? [
new ConsoleTransport({ level: 'debug' })
] : []),
// File for all environments
new FileTransport({
filepath: process.env.LOG_DIR || './logs',
rotation: 'daily',
maxFiles: 7
}),
// S3 for production
...(process.env.NODE_ENV === 'production' ? [
new S3Transport({
bucket: process.env.LOG_BUCKET,
compress: true
})
] : [])
]
});
// Graceful shutdown
process.on('SIGTERM', async () => {
logger.info('Shutting down');
await logger.close();
process.exit(0);
});
Request Logging Middleware
import { Logger } from 'magiclogger';
import { v4 as uuidv4 } from 'uuid';
function requestLogger(baseLogger: Logger) {
return (req, res, next) => {
const start = Date.now();
const requestId = uuidv4();
// Create request-scoped logger
req.logger = new Logger({
...baseLogger.options,
context: {
...baseLogger.options.context,
requestId,
method: req.method,
path: req.path,
ip: req.ip
}
});
// Log request
req.logger.info('Request received');
// Log response
res.on('finish', () => {
const duration = Date.now() - start;
req.logger.info('Request completed', {
statusCode: res.statusCode,
duration
});
});
next();
};
}
Multi-Service Logging
// Shared configuration
const baseConfig = {
tags: ['production'],
context: { environment: 'production' }
};
// Service-specific loggers
const apiLogger = new Logger({
...baseConfig,
id: 'api',
transports: [/* API transports */]
});
const dbLogger = new Logger({
...baseConfig,
id: 'database',
transports: [/* DB transports */]
});
const cacheLogger = new Logger({
...baseConfig,
id: 'cache',
transports: [/* Cache transports */]
});
Complex Styling Example
// Create style functions
const method = logger.color('cyan', 'bold');
const path = logger.color('yellow');
const status = logger.color('green');
const time = logger.color('gray');
const error = logger.color('red', 'bold');
// Use in logs
logger.info(
`${method('GET')} ${path('/api/users')} - ${status('200 OK')} in ${time('45ms')}`
);
logger.error(
`${method('POST')} ${path('/api/payment')} - ${error('500 Internal Error')} in ${time('523ms')}`
);
// Or use colorParts for the same effect
logger.info(
logger.colorParts('GET /api/users - 200 OK in 45ms', {
'GET': ['cyan', 'bold'],
'/api/users': ['yellow'],
'200 OK': ['green'],
'45ms': ['gray']
})
);
For more details on transports, see the Transport Documentation.