Skip to content

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.

zig
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 ​

OptionTypeDefaultDescription
levelLevel.infoMinimum log level to output.
global_color_displaybooltrueGlobally enable/disable colored output.
global_console_displaybooltrueGlobally enable/disable console output.
global_file_storagebooltrueGlobally enable/disable file output.
jsonboolfalseFormat logs as JSON objects.
pretty_jsonboolfalsePretty-print JSON output (indented).
colorbooltrueEnable ANSI color codes.
show_timebooltrueInclude timestamp in log output.
show_modulebooltrueInclude the module name.
show_functionboolfalseInclude the function name.
show_filenameboolfalseInclude the source filename.
show_linenoboolfalseInclude the source line number.
include_hostnameboolfalseInclude the system hostname.
include_pidboolfalseInclude the process ID.
capture_stack_traceboolfalseCapture stack traces for Error/Critical logs.
symbolize_stack_traceboolfalseResolve stack trace addresses to symbols.
auto_sinkbooltrueAutomatically add a console sink on init
check_for_updatesbooltrueCheck for updates on startup
enable_callbacksboolfalseEnable log callbacks (only when using callbacks)
log_format?[]const u8nullCustom log format string (e.g. "{time} {message}")
time_format[]const u8"YYYY-MM-DD HH:mm:ss.SSS"Timestamp format
timezoneenum.localTimezone for timestamps (.local or .utc)
use_arena_allocatorboolfalseEnable arena allocator for temporary allocations
arena_reset_thresholdusize64 * 1024Scratch arena reset threshold in bytes
emit_system_diagnostics_on_initboolfalseEmit system diagnostics on logger initialization
include_drive_diagnosticsbooltrueInclude drive information in diagnostics
auto_flushboolfalseAuto-flush sinks (set true only when immediate output is critical)
logs_root_path?[]const u8nullRoot directory for log files
debug_modeboolfalseEnable debug output for troubleshooting
error_handlingenum.log_and_continueError 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) ​

zig
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.

zig
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_type semantics:
    • .simple: Completed spans are kept pending until you explicitly call telemetry.exportSpans() or telemetry.flush(). Use this when you want to control export timing (e.g., at request boundaries).
    • .batch : Spans are buffered and automatically exported when batch_size or batch_timeout_ms thresholds are reached.
  • metrics_file_path overrides exporter_file_path for 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 ​

zig
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 ​

zig
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 ​

zig
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 ​

zig
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:

zig
// 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:

zig
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 config variable 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:

zig
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:

zig
// 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 ​

zig
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 to time_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
zig
config.log_format = "{time} | {level} | {message}";

To enable clickable file links in your terminal (like VS Code), enable filename and line number display:

zig
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:

FormatExample OutputDescription
YYYY-MM-DD HH:mm:ss.SSS2025-12-04 06:39:53.091Default human-readable
ISO86012025-12-04T06:39:53.091ZISO 8601 format
RFC33392025-12-04T06:39:53+00:00RFC 3339 format
YYYY-MM-DD2025-12-04Date only
HH:mm:ss06:39:53Time only
HH:mm:ss.SSS06:39:53.091Time with milliseconds
unix1764830393Unix timestamp (seconds)
unix_ms1764830393091Unix timestamp (milliseconds)
zig
// 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:

zig
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:

zig
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:

zig
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:

zig
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:

zig
// 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:

zig
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:

zig
// 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:

zig
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 ​

LevelColorANSI CodeDescription
TRACECyan36Detailed tracing
DEBUGBlue34Debug information
INFOWhite37General info
SUCCESSGreen32Success messages
WARNINGYellow33Warnings
ERRORRed31Errors
FAILMagenta35Failures
CRITICALBright Red91Critical errors

Level Colors Configuration ​

You can customize the colors for standard levels using the level_colors configuration:

zig
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:

zig
// 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:

ModifierCodeExampleResult
Bold131;1Bold Red
Underline434;4Underline Blue
Reverse732;7Reverse Green
Bright9x91Bright Red

Disabling Colors Completely ​

To completely disable colors (useful for CI/CD or log files):

zig
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:

zig
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:

zig
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:

zig
// Reset periodically in high-throughput scenarios
logger.resetArena();

Cross-Platform Colors ​

Logly automatically handles ANSI color support across platforms:

zig
// 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 ​

zig
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:

zig
var config = logly.Config.default();
config.json = true;
config.pretty_json = true;
logger.configure(config);

Output:

json
{
  "timestamp": "2024-01-15 10:30:45.000",
  "level": "INFO",
  "message": "Application started"
}

JSON with Custom Levels ​

Custom level names appear in JSON output:

zig
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.

zig
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 ​

Released under the MIT License.