Configuration β
Logly.zig offers a comprehensive and flexible configuration system, allowing you to tailor every aspect of the logging behavior to your application's needs.
Basic Configuration β
The Config struct is the primary interface for global settings. You can start with a default configuration and modify it as needed.
var config = logly.Config.default();
// Global controls
config.global_color_display = true;
config.global_console_display = true;
config.global_file_storage = true;
// Log level
config.level = .debug;
// Display options
config.show_time = true;
config.show_module = true;
config.show_function = false;
config.show_filename = true; // Useful for debugging
config.show_lineno = true; // Pinpoint the exact line
config.include_hostname = true; // Add hostname to logs
config.include_pid = true; // Add process ID
// Output format
config.json = false;
config.pretty_json = false;
config.color = true;
// Features
config.enable_callbacks = false; // Enable only when using callbacks
config.enable_exception_handling = true;
logger.configure(config);Configuration Options β
| Option | Type | Default | Description |
|---|---|---|---|
level | Level | .info | Minimum log level to output. |
global_color_display | bool | true | Globally enable/disable colored output. |
global_console_display | bool | true | Globally enable/disable console output. |
global_file_storage | bool | true | Globally enable/disable file output. |
json | bool | false | Format logs as JSON objects. |
pretty_json | bool | false | Pretty-print JSON output (indented). |
color | bool | true | Enable ANSI color codes. |
show_time | bool | true | Include timestamp in log output. |
show_module | bool | true | Include the module name. |
show_function | bool | false | Include the function name. |
show_filename | bool | false | Include the source filename. |
show_lineno | bool | false | Include the source line number. |
include_hostname | bool | false | Include the system hostname. |
include_pid | bool | false | Include the process ID. |
capture_stack_trace | bool | false | Capture stack traces for Error/Critical logs. |
symbolize_stack_trace | bool | false | Resolve stack trace addresses to symbols. |
auto_sink | bool | true | Automatically add a console sink on init |
check_for_updates | bool | true | Check for updates on startup |
enable_callbacks | bool | false | Enable log callbacks (only when using callbacks) |
log_format | ?[]const u8 | null | Custom log format string (e.g. "{time} {message}") |
time_format | []const u8 | "YYYY-MM-DD HH:mm:ss.SSS" | Timestamp format |
timezone | enum | .local | Timezone for timestamps (.local or .utc) |
use_arena_allocator | bool | false | Enable arena allocator for temporary allocations |
arena_reset_threshold | usize | 64 * 1024 | Scratch arena reset threshold in bytes |
emit_system_diagnostics_on_init | bool | false | Emit system diagnostics on logger initialization |
include_drive_diagnostics | bool | true | Include drive information in diagnostics |
auto_flush | bool | false | Auto-flush sinks (set true only when immediate output is critical) |
logs_root_path | ?[]const u8 | null | Root directory for log files |
debug_mode | bool | false | Enable debug output for troubleshooting |
error_handling | enum | .log_and_continue | Error handling strategy (.silent, .log_and_continue, .fail_fast, .callback) |
Module Configuration β
The Config struct provides settings for various logging modules. Each module can be enabled and configured through its respective config section:
Distributed Configuration (Microservices) β
var config = logly.Config.default();
config.distributed = .{
.enabled = true,
.service_name = "payment-service", // Your service name
.region = "us-east-1", // Deployment region
.environment = "production", // Service environment (dev/prod/staging)
.trace_header = "X-Trace-ID", // Header key for Trace ID
.span_header = "X-Span-ID", // Header key for Span ID
};Telemetry β
OpenTelemetry-specific configuration is available via the telemetry field on Config. Use built-in presets (TelemetryConfig.jaeger(), TelemetryConfig.zipkin(), TelemetryConfig.file(path), TelemetryConfig.highThroughput(), TelemetryConfig.development(), etc.) or customize the fields directly.
var config = logly.Config.default();
// Use a preset for Jaeger and tweak batching
config.telemetry = logly.TelemetryConfig.jaeger();
config.telemetry.span_processor_type = .batch; // Auto-export when thresholds hit
config.telemetry.batch_size = 1024;
config.telemetry.batch_timeout_ms = 2000;
// Or use file-based development preset
config.telemetry = logly.TelemetryConfig.development();Notes:
span_processor_typesemantics:.simple: Completed spans are kept pending until you explicitly calltelemetry.exportSpans()ortelemetry.flush(). Use this when you want to control export timing (e.g., at request boundaries)..batch: Spans are buffered and automatically exported whenbatch_sizeorbatch_timeout_msthresholds are reached.
metrics_file_pathoverridesexporter_file_pathfor JSON/Prometheus metric exports.- Default telemetry values (batch size, timeouts, headers) are centralized in
Constants.TelemetryDefaults. - v0.1.8: Fixed an OTLP exporter compile-time issue (removed an unnecessary discard in
writeOtlpSpan) so telemetry builds cleanly across targets.
Thread Pool Configuration β
var config = logly.Config.default();
config.thread_pool = .{
.enabled = true, // Enable thread pool
.thread_count = 4, // Number of worker threads (0 = auto)
.queue_size = 10000, // Max queued tasks
.stack_size = 1024 * 1024, // Stack size per thread
.work_stealing = true, // Enable work stealing
};Scheduler Configuration β
var config = logly.Config.default();
config.scheduler = .{
.enabled = true, // Enable scheduler
.cleanup_max_age_days = 7, // Delete logs older than 7 days
.max_files = 10, // Keep max 10 rotated files
.compress_before_cleanup = true, // Compress before deleting
.file_pattern = "*.log", // Pattern for log files
};Compression Configuration β
var config = logly.Config.default();
config.compression = .{
.enabled = true, // Enable compression
.algorithm = .deflate, // Compression algorithm
.level = .default, // Compression level
.on_rotation = true, // Compress on rotation
.keep_original = false, // Delete original after compression
.extension = ".gz", // Compressed file extension
};Async Configuration β
var config = logly.Config.default();
config.async_config = .{
.enabled = true, // Enable async logging
.buffer_size = 8192, // Ring buffer size
.batch_size = 100, // Messages per batch
.flush_interval_ms = 100, // Auto-flush interval
.min_flush_interval_ms = 10, // Min interval between flushes
.max_latency_ms = 5000, // Max latency before forced flush
.overflow_policy = .drop_oldest, // On buffer overflow
.background_worker = true, // Auto-start worker thread
};Helper Methods β
Use helper methods for cleaner configuration:
// Enable async logging
var config = logly.Config.default().withAsync(.{
.enabled = true,
.buffer_size = 8192,
});
// Enable compression
var config2 = logly.Config.default().withCompression(logly.CompressionConfig.production());
// Enable thread pool with specific thread count
var config3 = logly.Config.default().withThreadPool(.{
.enabled = true,
.thread_count = 4,
});
// Enable scheduler
var config4 = logly.Config.default().withScheduler(.{
.enabled = true,
.cleanup_max_age_days = 7,
});
// Enable arena allocation
var config5 = logly.Config.default().withArenaAllocation();
// Chain multiple features
var config6 = logly.Config.default()
.withAsync(.{ .enabled = true, .buffer_size = 8192 })
.withCompression(logly.CompressionConfig.production())
.withThreadPool(.{ .enabled = true, .thread_count = 0 }) // Auto-detect CPU cores
.withArenaAllocation();Allocator Configuration (Explicit vs Builder) β
Both forms are valid and supported:
var config = logly.Config.default();
config.use_arena_allocator = true;
// Equivalent builder aliases
config = config.withArenaAllocation();
config = config.withArenaAllocator();
config = config.withArena();Difference:
- Field assignment mutates your existing
configvariable in place. - Builder/alias methods return a modified copy (reassign to keep changes).
You can also run your application/request scratch allocations in your own arena that is backed by GPA, independently of Logly's internal arena:
const std = @import("std");
var gpa = std.heap.DebugAllocator(.{}){};
defer _ = gpa.deinit();
var app_arena = std.heap.ArenaAllocator.init(gpa.allocator());
defer app_arena.deinit();
const request_alloc = app_arena.allocator();
const tmp = try request_alloc.alloc(u8, 256);
_ = tmp;
// Release request-scoped allocations in one step
_ = app_arena.reset(.retain_capacity);Configuration Presets β
Logly provides pre-configured presets for common scenarios:
// Production: JSON output, sampling, compression, scheduler enabled
const prod_config = logly.ConfigPresets.production();
// Development: DEBUG level, colors, source location shown
const dev_config = logly.ConfigPresets.development();
// High Throughput: Async, thread pool, rate limiting enabled
const perf_config = logly.ConfigPresets.highThroughput();
// Secure: Redaction enabled, no hostname/PID in output
const secure_config = logly.ConfigPresets.secure();
// Log-only mode (no console output)
const log_only = logly.Config.logOnly();
// Display-only mode (console only, no files)
const display_only = logly.Config.displayOnly();
// Custom display/storage settings
const custom = logly.Config.withDisplayStorage(true, true, true);Using Presets β
var logger = try logly.Logger.initWithConfig(allocator, logly.ConfigPresets.production());Advanced Configuration β
Custom Log Format β
You can customize the log output format using the log_format option. The following placeholders are supported:
{time}: Timestamp (formatted according totime_format){level}: Log level{message}: Log message{module}: Module name{function}: Function name{file}: Filename (clickable in supported terminals){line}: Line number{trace_id}: Distributed trace ID{span_id}: Span ID
config.log_format = "{time} | {level} | {message}";Clickable Links β
To enable clickable file links in your terminal (like VS Code), enable filename and line number display:
config.show_filename = true;
config.show_lineno = true;This will output the location in path/to/file:line format.
Time Configuration β
Logly supports multiple timestamp formats:
| Format | Example Output | Description |
|---|---|---|
YYYY-MM-DD HH:mm:ss.SSS | 2025-12-04 06:39:53.091 | Default human-readable |
ISO8601 | 2025-12-04T06:39:53.091Z | ISO 8601 format |
RFC3339 | 2025-12-04T06:39:53+00:00 | RFC 3339 format |
YYYY-MM-DD | 2025-12-04 | Date only |
HH:mm:ss | 06:39:53 | Time only |
HH:mm:ss.SSS | 06:39:53.091 | Time with milliseconds |
unix | 1764830393 | Unix timestamp (seconds) |
unix_ms | 1764830393091 | Unix timestamp (milliseconds) |
// Use ISO8601 format
config.time_format = logly.Config.TimeFormat.iso8601;
// Use Unix timestamp
config.time_format = logly.Config.TimeFormat.unix;
// Use canonical default pattern
config.time_format = logly.Config.TimeFormat.default_pattern;
// Configure timezone
config.timezone = .utc; // Use UTC
config.timezone = .local; // Use local time (default)Enterprise Configuration β
Filtering β
Configure rule-based log filtering:
const Filter = logly.Filter;
var filter = Filter.init(allocator);
defer filter.deinit();
// Only allow warning and above
try filter.addMinLevel(.warning);
// Filter by module prefix
try filter.addModulePrefix("database");
// Filter by message content
try filter.addMessageFilter("heartbeat", .deny);
logger.setFilter(&filter);Sampling β
Configure log sampling for high-volume scenarios:
const Sampler = logly.Sampler;
const SamplerPresets = logly.SamplerPresets;
// Use preset: 10% sampling
var sampler = SamplerPresets.sample10Percent(allocator);
defer sampler.deinit();
logger.setSampler(&sampler);
// Or custom: rate limit to 100 per second
var rate_sampler = Sampler.init(allocator, .{ .rate_limit = .{
.max_records = 100,
.window_ms = 1000,
}});Redaction β
Configure sensitive data masking:
const Redactor = logly.Redactor;
var redactor = Redactor.init(allocator);
defer redactor.deinit();
// Mask passwords by keyword
try redactor.addPattern("password", .keyword, "password", "[REDACTED]");
// Mask credit card patterns
try redactor.addPattern("card", .contains, "card=", "[CARD-REDACTED]");
logger.setRedactor(&redactor);Metrics β
Enable logging metrics collection:
logger.enableMetrics();
// ... later ...
if (logger.getMetrics()) |metrics| {
std.debug.print("Total: {}, Errors: {}\n", .{
metrics.total_records,
metrics.error_count,
});
}Distributed Tracing β
Configure distributed tracing context:
// Set trace context from incoming request
try logger.setTraceContext("trace-abc-123", "span-parent-456");
// Or set correlation ID
try logger.setCorrelationId("request-789");
// Create spans for operations
const span = try logger.startSpan("database_query");
defer span.end(null) catch {};
try logger.info("Executing query");Color Configuration β
Global Color Control β
Control colors globally across all sinks:
var config = logly.Config.default();
// Disable all colors globally
config.global_color_display = false;
// Or enable colors per output type
config.color = true; // Enable ANSI color codes
logger.configure(config);Per-Sink Color Control β
Each sink can have independent color settings:
// Console with colors enabled
_ = try logger.addSink(.{
.color = true, // Explicit colors on
});
// File sink with colors disabled (recommended for files)
_ = try logger.addSink(.{
.path = "logs/app.log",
.color = false, // No ANSI codes in files
});
// JSON file (colors don't apply to JSON structure)
_ = try logger.addSink(.{
.path = "logs/app.json",
.json = true,
.color = false,
});Windows Color Support β
Enable ANSI colors on Windows at application startup:
pub fn main() !void {
// Enable Virtual Terminal Processing on Windows
// This is a no-op on Linux/macOS
_ = logly.Terminal.enableAnsiColors();
// ... rest of initialization
}Built-in Level Colors β
| Level | Color | ANSI Code | Description |
|---|---|---|---|
| TRACE | Cyan | 36 | Detailed tracing |
| DEBUG | Blue | 34 | Debug information |
| INFO | White | 37 | General info |
| SUCCESS | Green | 32 | Success messages |
| WARNING | Yellow | 33 | Warnings |
| ERROR | Red | 31 | Errors |
| FAIL | Magenta | 35 | Failures |
| CRITICAL | Bright Red | 91 | Critical errors |
Level Colors Configuration β
You can customize the colors for standard levels using the level_colors configuration:
var config = logly.Config.default();
// Use a built-in theme
config.level_colors.theme_preset = .neon; // .bright, .dim, .neon, .pastel, .dark, etc.
// Override specific level colors (ANSI codes)
config.level_colors.info_color = "36"; // Cyan
config.level_colors.warning_color = "33;1"; // Bold Yellow
config.level_colors.error_color = "31;4"; // Underline Red
logger.configure(config);Available theme presets:
.default: Standard ANSI colors.bright: Bold/bright variants.dim: Dim variants.minimal: Gray-scale theme.neon: Vivid 256-color palette.pastel: Soft pastel colors.dark: Optimized for dark terminals.light: Optimized for light terminals.none: No colors
Custom Level Colors β
Define custom levels with your own colors:
// Basic custom colors
try logger.addCustomLevel("audit", 35, "35"); // Magenta
try logger.addCustomLevel("security", 55, "91"); // Bright Red
// With modifiers (bold, underline, reverse)
try logger.addCustomLevel("notice", 22, "36;1"); // Bold Cyan
try logger.addCustomLevel("alert", 48, "31;4"); // Underline Red
try logger.addCustomLevel("highlight", 38, "33;7"); // Reverse Yellow
// Use custom levels
try logger.custom("audit", "User login detected");
try logger.customf("security", "Access from IP: {s}", .{"10.0.0.1"});Color Modifiers β
Combine base colors with modifiers:
| Modifier | Code | Example | Result |
|---|---|---|---|
| Bold | 1 | 31;1 | Bold Red |
| Underline | 4 | 34;4 | Underline Blue |
| Reverse | 7 | 32;7 | Reverse Green |
| Bright | 9x | 91 | Bright Red |
Disabling Colors Completely β
To completely disable colors (useful for CI/CD or log files):
var config = logly.Config.default();
config.global_color_display = false; // Master switch
config.color = false; // Disable ANSI codes
logger.configure(config);Performance Configuration β
Arena Allocator β
For high-throughput logging scenarios, enable the arena allocator to reduce allocation overhead:
var config = logly.Config.default();
// Enable arena allocator for temporary allocations
config.use_arena_allocator = true;
// Optionally set the reset threshold (default: 64KB)
config.arena_reset_threshold = 128 * 1024; // 128KB
const logger = try logly.Logger.initWithConfig(allocator, config);
defer logger.deinit();Or use the convenience method:
const config = logly.Config.default().withArenaAllocation();
const logger = try logly.Logger.initWithConfig(allocator, config);Both config.use_arena_allocator = true and config = config.withArenaAllocator() enable the same logger behavior. The difference is mutation style:
- Field assignment updates an existing config value.
- Builder aliases return a modified copy.
Benefits:
- Reduces allocation overhead for formatting operations
- Better cache locality for temporary buffers
- Faster logging in high-frequency scenarios
Manual Arena Reset:
For long-running applications, you can manually reset the arena to prevent memory growth:
// Reset periodically in high-throughput scenarios
logger.resetArena();Cross-Platform Colors β
Logly automatically handles ANSI color support across platforms:
// Enable colors (call at startup)
_ = logly.Terminal.enableAnsiColors();
// Check if colors are supported
if (logly.Terminal.supportsAnsiColors()) {
// Terminal supports colors
}
// Explicitly enable/disable colors (useful for bare metal)
logly.Terminal.setColorEnabled(true); // or false
// Check effective color status
if (logly.Terminal.isColorEnabled()) {
// Colors are available
}Platform Support:
- Windows: Automatically enables Virtual Terminal Processing
- Linux/macOS: ANSI colors natively supported
- Bare Metal/Freestanding: Controllable via
setColorEnabled()
JSON Configuration β
Basic JSON Logging β
var config = logly.Config.default();
config.json = true;
logger.configure(config);
try logger.info("Application started");
// Output: {"timestamp":"...","level":"INFO","message":"Application started"}Pretty JSON β
Enable indented, human-readable JSON:
var config = logly.Config.default();
config.json = true;
config.pretty_json = true;
logger.configure(config);Output:
{
"timestamp": "2024-01-15 10:30:45.000",
"level": "INFO",
"message": "Application started"
}JSON with Custom Levels β
Custom level names appear in JSON output:
try logger.addCustomLevel("audit", 35, "35");
try logger.custom("audit", "Security event");
// Output: {"timestamp":"...","level":"AUDIT","message":"Security event"}Rules System Configuration β
The Rules System provides guided diagnostics and can be customized with specific symbols.
var config = logly.Config.default();
config.rules.enabled = true;
// Define custom symbols (supports Emoji if terminal allows)
config.rules.symbols.error_analysis = "Γ°ΕΈβΊβ Cause:";Advanced Features β
For more advanced customizations like custom themes, scoped context, and advanced redaction, check out the Advanced Features Example and the Context Guide.
See Also β
- Sinks - Configure output destinations (Console, File, Network)
- Network Logging - Detailed guide on TCP/UDP logging
- Compression - Configure log compression
