-
Notifications
You must be signed in to change notification settings - Fork 2
Slogger Configuration
Complete configuration guide for Slogger.
- Configuration Overview
- SloggerOptions
- Handler Configuration
- Log Levels
- Sampling Configuration
- Environment-Based Configuration
- Advanced Patterns
Slogger configuration consists of three main components:
- Application settings - App name, global log level
- Handlers - Output destinations with their own settings
- Sampling - Optional global or per-handler log sampling
The main configuration object for creating a Slogger instance.
import type {
HandlerConfig,
LogContext,
SamplingOptions,
SyslogSeverities,
} from '@tundralibs/slogger';
interface SloggerOptions {
appName: string; // Application identifier, max 30 chars
level: SyslogSeverities; // Global minimum log level
handlers?: HandlerConfig[]; // Handler configurations (omit for a silent no-op logger)
sampling?: SamplingOptions; // Optional global sampling
interpolateMessage?: boolean; // Resolve ${path} in the MESSAGE against context (default: false — see below)
contextProvider?: () => LogContext; // Per-record context merged UNDER call/scope context
}handlers is optional — a Slogger built without it silently discards
everything, which is occasionally useful as a test/placeholder logger
(equivalent to a single BlackholeHandler, minus even the sampling
check). interpolateMessage and contextProvider are covered in the
README's
Message interpolation and
Automatic context
sections — not repeated here, since interpolateMessage's security
rationale is the kind of thing that drifts if maintained in two
places.
String identifier for your application. Appears in all log entries.
const logger = new Slogger({
appName: 'MyApp',
// ...
});Best practices:
- Use consistent naming across your application
- Keep it short and descriptive
- Use environment-aware names:
MyApp-Dev,MyApp-Prod
Global minimum severity level. Controls which logs are processed.
import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
const logger = new Slogger({
appName: 'MyApp',
level: SyslogSeverities.INFO, // Only INFO and above
// ...
});See Log Levels for details.
Array of handler configurations. Each handler represents an output destination.
import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
const logger = new Slogger({
appName: 'MyApp',
level: SyslogSeverities.INFO,
handlers: [
{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.DEBUG,
formatter: 'standard',
},
{
name: 'file',
type: 'FileHandler',
level: SyslogSeverities.INFO,
directory: './logs',
filenameTemplate: 'app.log',
formatter: 'json',
},
],
});See Handler Configuration for details.
Optional global sampling configuration applied to all handlers.
import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
const logger = new Slogger({
appName: 'MyApp',
level: SyslogSeverities.DEBUG,
handlers: [/* ... */],
sampling: {
sampleRate: 0.1, // Sample 10% of logs
bypassSamplingForLevel: SyslogSeverities.ERROR, // Always log errors
},
});See Sampling Configuration for details.
Each handler requires a configuration object with common and handler-specific options.
import type {
SamplingOptions,
SloggerFormatter,
SyslogSeverities,
} from '@tundralibs/slogger';
interface HandlerConfig {
name: string; // Unique handler identifier, max 30 chars
type: string; // Handler type (a name registered on LogManager)
level: SyslogSeverities; // Minimum level for this handler — required, no default
formatter?: string | SloggerFormatter; // Output formatter (default: standardFormat)
sampling?: SamplingOptions; // Per-handler sampling
[key: string]: unknown; // Handler-specific options
}-
'ConsoleHandler'- Console output -
'FileHandler'- File output -
'HTTPHandler'- HTTP endpoint -
'SyslogHandler'- RFC 5424 syslog over TCP/UDP/UNIX socket -
'TCPHandler'- Raw line-delimited or octet-counted TCP -
'StreamHandler'- Any web-standardWritableStream -
'MemoryHandler'- In-process ring buffer of structured records -
'BlackholeHandler'- No output - Custom types registered via
LogManager.addHandler()
Full option lists and runnable examples for every type live in
Handlers — the four newer handlers
below (SyslogHandler, TCPHandler, StreamHandler, MemoryHandler)
are only summarised here.
// SyslogHandler — see Slogger-Handlers.md#syslog-handler
{
name: 'syslog',
type: 'SyslogHandler',
level: SyslogSeverities.INFO,
transport: { type: 'tcp', host: 'logs.example.com', port: 514 }, // or 'udp' | 'unix'
facility: SyslogFacilities.LOCAL3, // default: USER
}
// TCPHandler — see Slogger-Handlers.md#tcp-handler
{
name: 'tcp',
type: 'TCPHandler',
level: SyslogSeverities.INFO,
host: 'logstash.internal',
port: 5044,
framing: 'lf', // default: 'lf'; or 'octet-count'
formatter: 'json',
}
// StreamHandler — see Slogger-Handlers.md#stream-handler
{
name: 'stream',
type: 'StreamHandler',
level: SyslogSeverities.INFO,
stream: someWritableStream, // WritableStream<Uint8Array> by default
useTextMode: false, // true for WritableStream<string>
}
// MemoryHandler — see Slogger-Handlers.md#memory-handler
{
name: 'recent',
type: 'MemoryHandler',
level: SyslogSeverities.DEBUG,
capacity: 500, // default: 100 records
}{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.DEBUG,
useColor: true, // Enable colored output (default: false)
formatter: 'standard',
}{
name: 'file',
type: 'FileHandler',
level: SyslogSeverities.INFO,
directory: './logs/${date}', // Directory (supports variables)
filenameTemplate: 'app-${hour}.log', // File name (supports variables)
maxFileSizeBytes: 50 * 1024 * 1024, // Max size in bytes (default: 50 MiB)
bufferSizeBytes: 4096, // Buffer size in bytes (default: 4096)
formatter: 'json',
}Supported variables:
-
${name}- Handler name -
${date}- YYYY-MM-DD -
${year}- YYYY -
${month}- MM -
${day}- DD -
${hour}- HH
{
name: 'http',
type: 'HTTPHandler',
level: SyslogSeverities.WARNING,
url: 'https://logs.example.com/ingest', // Endpoint URL
method: 'POST', // 'POST' | 'PUT' — required, no default
batchSize: 50, // Batch size (default: 1)
maxBufferSize: 10_000, // Queue cap, records; drop-oldest (default: 10_000)
headers: { // Custom headers
'Authorization': 'Bearer TOKEN',
'Content-Type': 'application/json'
},
formatter: 'json',
}
methodhas no default — omitting it (or passing anything besides'POST'/'PUT') throwsSloggerConfigErrorat construction.batchSizedefaults to1(send immediately), not a pre-batched value — set it explicitly for actual batching.maxBufferSizebounds the pending-batch-plus-retry queue so a persistently down endpoint drops the oldest records instead of growing memory unboundedly; see Handlers → HTTP Handler for the full option list.
{
name: 'null',
type: 'BlackholeHandler',
level: SyslogSeverities.DEBUG,
}Slogger uses syslog severity levels (RFC 5424).
| Level | Numeric | Name | Description | Use Case |
|---|---|---|---|---|
| EMERGENCY | 0 | emergency | System unusable | Catastrophic failures |
| ALERT | 1 | alert | Action required immediately | Critical alerts |
| CRITICAL | 2 | critical | Critical conditions | System component failures |
| ERROR | 3 | error | Error conditions | Application errors |
| WARNING | 4 | warning | Warning conditions | Deprecated API usage |
| NOTICE | 5 | notice | Normal but significant | Significant events |
| INFO | 6 | info | Informational messages | General information |
| DEBUG | 7 | debug | Debug-level messages | Development debugging |
import type { Slogger } from '@tundralibs/slogger';
declare const logger: Slogger;
declare const value: unknown;
logger.emergency('System is unusable'); // Level 0
logger.alert('Immediate action required'); // Level 1
logger.critical('Critical component failed'); // Level 2
logger.error('Operation failed'); // Level 3
logger.warning('Deprecated API used'); // Level 4
logger.notice('Significant event occurred'); // Level 5
logger.info('User logged in'); // Level 6
logger.debug('Variable value: ' + value); // Level 7Logs are filtered by comparing numeric levels:
import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
// Global level: INFO (6)
const logger = new Slogger({
appName: 'MyApp',
level: SyslogSeverities.INFO, // 6
handlers: [/* ... */],
});
logger.debug('Debug message'); // Filtered out (7 > 6)
logger.info('Info message'); // Logged (6 <= 6)
logger.error('Error message'); // Logged (3 <= 6)Each handler can have its own minimum level:
import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
const logger = new Slogger({
appName: 'MyApp',
level: SyslogSeverities.DEBUG, // Global: DEBUG (7)
handlers: [
{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.DEBUG, // Console: DEBUG (7)
},
{
name: 'file',
type: 'FileHandler',
level: SyslogSeverities.INFO, // File: INFO (6)
},
{
name: 'http',
type: 'HTTPHandler',
level: SyslogSeverities.ERROR, // HTTP: ERROR (3)
},
],
});
// DEBUG logs go to console only
// INFO logs go to console and file
// ERROR logs go to console, file, and HTTPReduce log volume by sampling a percentage of logs.
Applied to all handlers:
import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
const logger = new Slogger({
appName: 'HighVolume',
level: SyslogSeverities.DEBUG,
handlers: [/* ... */],
sampling: {
sampleRate: 0.01, // Sample 1%
bypassSamplingForLevel: SyslogSeverities.ERROR, // Always log errors
},
});Different sampling rates for each handler:
import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
const logger = new Slogger({
appName: 'MyApp',
level: SyslogSeverities.DEBUG,
handlers: [
{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.INFO,
// No sampling for console
},
{
name: 'debug-file',
type: 'FileHandler',
level: SyslogSeverities.DEBUG,
sampling: {
sampleRate: 0.05, // Sample 5% of DEBUG logs
bypassSamplingForLevel: SyslogSeverities.WARNING, // Always log warnings+
},
},
],
});import type { SyslogSeverities } from '@tundralibs/slogger';
interface SamplingOptions {
sampleRate?: number; // 0.0-1.0 (0.1 = 10%, 1.0 = 100%)
bypassSamplingForLevel?: SyslogSeverities; // Logs at/above always logged
}Adapt configuration to different environments.
import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
const isDev = Deno.env.get('ENV') === 'development';
const logger = new Slogger({
appName: isDev ? 'MyApp-Dev' : 'MyApp-Prod',
level: isDev ? SyslogSeverities.DEBUG : SyslogSeverities.INFO,
handlers: isDev
? [
{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.DEBUG,
useColor: true,
formatter: 'detailed',
},
]
: [
{
name: 'file',
type: 'FileHandler',
level: SyslogSeverities.INFO,
directory: '/var/log/myapp',
filenameTemplate: 'app.log',
maxFileSizeBytes: 100 * 1024 * 1024,
formatter: 'json',
},
{
name: 'errors',
type: 'HTTPHandler',
level: SyslogSeverities.ERROR,
url: Deno.env.get('LOG_ENDPOINT')!,
headers: {
'Authorization': `Bearer ${Deno.env.get('LOG_API_KEY')}`,
},
formatter: 'json',
},
],
});import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
const logLevelMap: Record<string, SyslogSeverities> = {
'emergency': SyslogSeverities.EMERGENCY,
'alert': SyslogSeverities.ALERT,
'critical': SyslogSeverities.CRITICAL,
'error': SyslogSeverities.ERROR,
'warning': SyslogSeverities.WARNING,
'notice': SyslogSeverities.NOTICE,
'info': SyslogSeverities.INFO,
'debug': SyslogSeverities.DEBUG,
};
const envLevel = Deno.env.get('LOG_LEVEL') || 'info';
const level = logLevelMap[envLevel] || SyslogSeverities.INFO;
const logger = new Slogger({
appName: Deno.env.get('APP_NAME') || 'MyApp',
level,
handlers: [{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.INFO,
formatter: 'standard',
}],
});import {
type HandlerConfig,
Slogger,
type SyslogSeverities,
} from '@tundralibs/slogger';
import { parse } from 'https://deno.land/std/jsonc/mod.ts';
declare const logLevelMap: Record<string, SyslogSeverities>; // see above
interface LogConfig {
appName: string;
level: string;
handlers: Array<{
name: string;
type: string;
[key: string]: unknown;
}>;
}
const configText = await Deno.readTextFile('./config/logging.jsonc');
const config = parse(configText) as unknown as LogConfig;
const logger = new Slogger({
appName: config.appName,
level: logLevelMap[config.level],
handlers: config.handlers as HandlerConfig[],
});import {
Slogger,
type SloggerOptions,
SyslogSeverities,
} from '@tundralibs/slogger';
type Environment = 'development' | 'staging' | 'production';
const configs: Record<Environment, SloggerOptions> = {
development: {
appName: 'MyApp-Dev',
level: SyslogSeverities.DEBUG,
handlers: [{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.INFO,
formatter: 'detailed',
useColor: true,
}],
},
staging: {
appName: 'MyApp-Staging',
level: SyslogSeverities.INFO,
handlers: [
{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.INFO,
formatter: 'standard',
},
{
name: 'file',
type: 'FileHandler',
level: SyslogSeverities.INFO,
directory: './logs',
filenameTemplate: 'app.log',
formatter: 'json',
},
],
},
production: {
appName: 'MyApp',
level: SyslogSeverities.INFO,
handlers: [
{
name: 'file',
type: 'FileHandler',
level: SyslogSeverities.INFO,
directory: '/var/log/myapp',
filenameTemplate: 'app.log',
maxFileSizeBytes: 100 * 1024 * 1024,
formatter: 'json',
},
{
name: 'errors',
type: 'HTTPHandler',
level: SyslogSeverities.ERROR,
url: Deno.env.get('LOG_ENDPOINT')!,
formatter: 'json',
},
],
},
};
const env = (Deno.env.get('ENV') as Environment) || 'development';
const logger = new Slogger(configs[env]);import {
type HandlerConfig,
Slogger,
SyslogSeverities,
} from '@tundralibs/slogger';
const handlers: HandlerConfig[] = [
{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.INFO,
formatter: 'standard',
},
];
// Add file handler if log path is configured
const logPath = Deno.env.get('LOG_PATH');
if (logPath) {
handlers.push({
name: 'file',
type: 'FileHandler',
level: SyslogSeverities.INFO,
directory: logPath,
filenameTemplate: 'app.log',
formatter: 'json',
});
}
// Add HTTP handler if endpoint is configured
const logEndpoint = Deno.env.get('LOG_ENDPOINT');
if (logEndpoint) {
handlers.push({
name: 'http',
type: 'HTTPHandler',
level: SyslogSeverities.ERROR,
url: logEndpoint,
formatter: 'json',
});
}
const logger = new Slogger({
appName: 'MyApp',
level: SyslogSeverities.INFO,
handlers,
});import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
const logger = new Slogger({
appName: 'MyApp',
level: SyslogSeverities.INFO,
handlers: [{
name: 'console',
type: 'ConsoleHandler',
level: SyslogSeverities.INFO,
formatter: 'standard',
}],
});
// Add handler at runtime
import { FileHandler, jsonFormatter } from '@tundralibs/slogger';
const fileHandler = new FileHandler('runtime-file', {
level: SyslogSeverities.DEBUG,
directory: './logs',
filenameTemplate: 'debug.log',
formatter: jsonFormatter,
});
logger.registerHandler(fileHandler);- Handlers - Handler details
- Formatters - Formatter details
- Examples - Usage examples
- Performance - Performance tuning