Blazing fast, plugin-based logging with @oxog ecosystem integration, colored output, and swappable transports
npm install @oxog/log



Blazing fast, plugin-based logging for Node.js and browsers with micro-kernel architecture.
Part of the @oxog ecosystem.
- Six Log Levels: trace, debug, info, warn, error, fatal
- Structured Logging: Attach metadata objects to log entries
- Child Loggers: Create scoped loggers with bound context
- Correlation ID: Track requests across async operations
- Source Location: Capture file and line number
- Performance Timing: Built-in time/timeEnd utilities
- Redaction: Mask sensitive fields from output
- Multiple Formats: JSON, Pretty, Auto (based on environment)
- Multiple Transports: Console, Stream, File, HTTP, localStorage
- Hybrid Sync/Async: Level-based synchronization with buffering
- Browser Support: Native DevTools integration
- Zero Config: Works out of the box with sensible defaults
- TypeScript First: Full type safety and IntelliSense support
``bash`
npm install @oxog/log
`typescript
import { createLogger } from '@oxog/log';
const log = createLogger({ name: 'my-app' });
// Simple logging
log.info('Server started');
// Structured logging with data
log.info({ port: 3000, env: 'production' }, 'Listening');
// Child loggers with context
const dbLog = log.child({ module: 'database' });
dbLog.info('Connected to database');
`
`typescript`
log.trace('Detailed debugging'); // 10
log.debug('Debug information'); // 20
log.info('Informational'); // 30
log.warn('Warning'); // 40
log.error('Error occurred'); // 50
log.fatal('Fatal error'); // 60
`typescript
const dbLog = log.child({ module: 'database' });
dbLog.info('Connected');
const queryLog = dbLog.child({ operation: 'select' });
queryLog.debug('Executing query');
`
`typescript`
const reqLog = log.withCorrelation('req-abc-123');
reqLog.info('Request received');
reqLog.info('Processing');
reqLog.info('Response sent');
`typescript
log.time('db-query');
await database.query('SELECT * FROM users');
log.timeEnd('db-query');
// Or use startTimer for more control
const end = log.startTimer('api-call');
await fetch('/api/data');
end();
`
`typescript
const log = createLogger({
redact: ['password', 'token', 'creditCard']
});
log.info({ user: 'john', password: 'secret123' });
// Output: {"user":"john","password":"[REDACTED]"}
`
`typescript
import { createLogger, consoleTransport, fileTransport } from '@oxog/log';
const log = createLogger({
transports: [
consoleTransport({ colors: true }),
fileTransport({
path: './logs/app.log',
rotate: '1d',
maxFiles: 7
})
]
});
`
`typescript
// Structured JSON (production)
const jsonLog = createLogger({ format: 'json' });
// Human-readable (development)
const prettyLog = createLogger({ format: 'pretty' });
// Auto-detect based on environment
const autoLog = createLogger({ format: 'auto' });
`
`typescript
try {
const data = await fetchData();
} catch (error) {
log.error(error, 'Failed to fetch data');
}
log.fatal(new Error('Cannot start'), 'Server error');
`
`typescript
const log = createLogger({ level: 'warn' });
log.info('This will NOT appear'); // Below minimum level
log.warn('This WILL appear');
// Dynamic level change
log.setLevel('debug');
log.info('Now this appears');
`
`typescript
const log = createLogger({ source: true });
log.info('Debug me');
// Output: {"level":30,"file":"server.ts","line":42,"msg":"Debug me"}
`
`typescript
import { createLogger, redactPlugin, sourcePlugin } from '@oxog/log';
const log = createLogger({
plugins: [
redactPlugin(['apiKey', 'secret']),
sourcePlugin()
]
});
`
`typescript
import type { Plugin } from '@oxog/types';
const myPlugin: Plugin = {
name: 'myPlugin',
version: '1.0.0',
install(kernel) {
// Custom logic
}
};
log.use(myPlugin);
`
`typescript
import { createLogger } from '@oxog/log';
const log = createLogger();
log.info('Hello from browser!');
log.warn('Careful!');
log.error('Something went wrong');
// Child loggers use console.group
const child = log.child({ component: 'Auth' });
child.info('Checking token');
`
`typescriptTransport ${transport} failed:
// Listen for transport failures
log.on('error', ({ transport, error, entry }) => {
console.error(, error.message);`
// Optionally alert ops team or use fallback
});
`typescript
const log = createLogger({
// fatal and error are sync by default (written before process exit)
sync: {
fatal: true, // default
error: true, // default
warn: false,
info: false,
debug: false,
trace: false,
}
});
// Fatal logs are written synchronously - safe before process.exit()
process.on('uncaughtException', (err) => {
log.fatal(err, 'Uncaught exception');
process.exit(1); // Log is guaranteed to be written
});
`
`typescript
import { stringifyWithRedaction } from '@oxog/log';
// More efficient than redactFields + JSON.stringify for large objects
const json = stringifyWithRedaction(
largeObject,
['password', 'token', 'headers.authorization']
);
`
`typescript
// Flush buffered logs before shutdown
await log.flush();
// Cleanup and destroy (also flushes buffer)
await log.close();
`
Creates a new logger instance.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| name | string | 'app' | Logger name |level
| | LogLevelName | 'info' | Minimum log level |format
| | 'json' \| 'pretty' \| 'auto' | 'auto' | Output format |transports
| | Transport[] | [consoleTransport()] | Output destinations |redact
| | string[] | [] | Fields to redact |source
| | boolean | false | Include source location |timestamp
| | boolean | true | Include timestamp |context
| | object | {} | Static context |plugins
| | Plugin[] | [] | Plugins to load |
#### Logging
- trace(msg) / trace(obj, msg) - Trace leveldebug(msg)
- / debug(obj, msg) - Debug levelinfo(msg)
- / info(obj, msg) - Info levelwarn(msg)
- / warn(obj, msg) - Warn levelerror(msg)
- / error(obj, msg) / error(err, msg) - Error levelfatal(msg)
- / fatal(obj, msg) / fatal(err, msg) - Fatal level
#### Context
- child(context) - Create child logger with additional contextwithCorrelation(id)
- - Create logger with correlation ID
#### Timing
- time(label) - Start a timertimeEnd(label)
- - End timer and log durationstartTimer(label)
- - Returns stop function
#### Plugin Management
- use(plugin) - Register pluginunregister(name)
- - Unregister pluginhasPlugin(name)
- - Check if plugin existslistPlugins()
- - List all plugins
#### Lifecycle
- flush() - Flush buffered logsclose()
- - Cleanup and close transports
#### Level Management
- setLevel(level) - Set minimum levelgetLevel()
- - Get current levelisLevelEnabled(level)` - Check if level is enabled
-
For detailed documentation, see the docs folder:
- Specification - Full API specification
- Implementation - Implementation details
- Tasks - Development tasks
Contributions are welcome! Please read our contributing guidelines before submitting a PR.
MIT - see LICENSE for details.
Ersin Koc - @ersinkoc