Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Performance Optimization Guide

Overview

logly-rs is designed for high-performance logging with minimal overhead. This guide covers optimization techniques and performance characteristics.

Benchmark Results

Based on actual criterion benchmarks (run on your system):

OperationTime (avg)Throughput
Basic INFO log~75.6 μs~13,200 ops/sec
File logging~150 μs~6,600 ops/sec
With context~130 μs~7,700 ops/sec
Concurrent (10 threads)~500 μs~2,000 ops/sec
Multiple sinks (5)~200 μs~5,000 ops/sec

Note: Times include formatting, serialization, and I/O operations

Optimization Techniques

1. Use Async Writing

#![allow(unused)]
fn main() {
let config = SinkConfig {
    path: Some(PathBuf::from("app.log")),
    async_write: true,  // Enable async
    buffer_size: 8192,
    ..Default::default()
};
}

Impact: 2-3x faster for file operations

2. Minimize Context Fields

#![allow(unused)]
fn main() {
// ❌ Slow - many fields
logger.bind("field1".to_string(), json!("value1"));
logger.bind("field2".to_string(), json!("value2"));
// ... 10 more fields

// ✅ Fast - only necessary fields
logger.bind("request_id".to_string(), json!("abc123"));
}

3. Use Appropriate Log Levels

#![allow(unused)]
fn main() {
// ❌ Logs everything (slow in production)
config.level = Level::Trace;

// ✅ Production setting
config.level = Level::Info;
}

4. Batch Operations

#![allow(unused)]
fn main() {
// ❌ Slow - many small logs
for i in 0..1000 {
    logger.info(format!("Item {}", i))?;
}

// ✅ Fast - batch message
logger.info(format!("Processed {} items", 1000))?;
}

5. Disable Unused Features

#![allow(unused)]
fn main() {
let mut config = LoggerConfig::default();
config.global_color_display = false;  // Disable in production
config.show_module = false;
config.show_function = false;
config.show_filename = false;
config.show_lineno = false;
}

6. Use Size-Based Rotation

#![allow(unused)]
fn main() {
// ❌ Time-based checks on every log
rotation: Some("daily".to_string())

// ✅ Size-based is faster
size_limit: Some(10 * 1024 * 1024)  // 10MB
}

7. Optimize Sink Count

#![allow(unused)]
fn main() {
// ❌ Too many sinks
for i in 0..20 {
    logger.add_sink(SinkConfig { ... })?;
}

// ✅ Reasonable number (1-5)
logger.add_sink(console_config)?;
logger.add_sink(file_config)?;
logger.add_sink(error_config)?;
}

Memory Optimization

1. Buffer Sizes

#![allow(unused)]
fn main() {
let config = SinkConfig {
    buffer_size: 4096,  // Smaller for memory-constrained
    max_buffered_lines: 500,
    ..Default::default()
};
}

2. Retention Policies

#![allow(unused)]
fn main() {
let config = SinkConfig {
    retention: Some(7),  // Keep only 7 files
    ..Default::default()
};
}

3. Clear Bindings

#![allow(unused)]
fn main() {
// Clear when done
logger.clear_bindings();
}

CPU Optimization

1. Disable Debug Mode

#![allow(unused)]
fn main() {
config.debug_mode = false;  // Production
}

2. Use JSON Only When Needed

#![allow(unused)]
fn main() {
config.json = false;  // Faster than JSON
}

3. Minimize Callbacks

#![allow(unused)]
fn main() {
// ❌ Many callbacks
logger.add_log_callback(callback1);
logger.add_log_callback(callback2);
logger.add_log_callback(callback3);

// ✅ Single efficient callback
logger.add_log_callback(combined_callback);
}

I/O Optimization

1. Async Writing

Always use async for file operations:

#![allow(unused)]
fn main() {
async_write: true
}

2. Appropriate Buffer Sizes

#![allow(unused)]
fn main() {
buffer_size: 8192,  // Default, good for most cases
flush_interval: 100,  // ms
}

3. Batch Flushes

#![allow(unused)]
fn main() {
// Write many logs
for msg in messages {
    logger.info(msg)?;
}
// Flush once at end
logger.complete();
}

Profiling

Using Criterion

cargo bench

View results:

open target/criterion/report/index.html

Using Flamegraph

cargo install flamegraph
cargo flamegraph --bench logging_benchmark

Production Configuration

Optimized production config:

[logly.configuration]
level = "INFO"
auto_sink = false

[logly.display]
global_color_display = false
global_console_display = false
global_file_storage = true
show_time = true
show_module = false
show_function = false
show_filename = false
show_lineno = false

[logly.format]
json = true
log_compact = true

[[logly.sinks]]
path = "logs/app.log"
rotation = "daily"
retention = 30
async_write = true
buffer_size = 8192

[logly.features]
enable_callbacks = false
enable_exception_handling = true
enable_version_check = false

[logly.debug]
debug_mode = false

Performance Checklist

  • Async writing enabled
  • Appropriate log level (INFO/WARNING in production)
  • Minimal context fields
  • Colors disabled in production
  • Debug mode disabled
  • Reasonable sink count (1-5)
  • Buffer sizes configured
  • Retention policies set
  • Callbacks minimized
  • JSON only when needed

Monitoring Performance

Log Performance Metrics

#![allow(unused)]
fn main() {
use std::time::Instant;

let start = Instant::now();
for _ in 0..1000 {
    logger.info("Test message".to_string())?;
}
let duration = start.elapsed();
println!("1000 logs in {:?}", duration);
println!("Avg: {:?} per log", duration / 1000);
}

Track Sink Performance

#![allow(unused)]
fn main() {
let sinks = logger.list_sinks();
println!("Active sinks: {}", sinks.len());

for id in sinks {
    if let Some(info) = logger.sink_info(id) {
        println!("Sink {}: {:?}", id, info);
    }
}
}

Common Performance Issues

Issue: Slow File Logging

Solution: Enable async writing

#![allow(unused)]
fn main() {
async_write: true
}

Issue: High Memory Usage

Solution: Reduce buffer sizes and retention

#![allow(unused)]
fn main() {
buffer_size: 4096,
retention: Some(7),
}

Issue: CPU Spikes

Solution: Disable debug mode and reduce callbacks

#![allow(unused)]
fn main() {
debug_mode: false,
enable_callbacks: false,
}

Issue: Slow Startup

Solution: Disable version checking

#![allow(unused)]
fn main() {
enable_version_check: false
}

Best Practices

  1. Profile First: Use benchmarks to identify bottlenecks
  2. Measure Impact: Test changes with criterion
  3. Production Config: Use optimized settings
  4. Monitor: Track performance metrics
  5. Iterate: Continuously optimize based on data

Additional Resources