Skip to content

icegull/rs_loglib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rs_loglib

A high-performance, thread-safe logging library for Rust with rolling file support.

Features

  • Rolling File Support: Automatically rotate logs based on file size
  • Multiple Logger Instances: Run multiple independent loggers with different configurations
  • Thread Safety: Safe for concurrent use across multiple threads using parking_lot mutex
  • Instant Flush Option: Optional immediate buffer flushing for critical logging scenarios
  • Structured Output: Timestamp, thread ID, and log level in each log entry

Installation

Add to your Cargo.toml:

[dependencies]
rs_loglib = { git = "https://github.com/icegull/rs_loglib" }

Quick Start

use rs_loglib::{LogConfig, init_logger, info};

fn main() {
    // Initialize a logger instance
    let logger = init_logger(
        LogConfig::new()
            .with_instance_name("myapp")
            .with_file_name("app.log")
    ).unwrap();

    // Log messages
    info!(logger, "Hello from rs_loglib!");
}

Configuration Options

The following table lists all available configuration options and their default values:

Option Type Default Value Description
log_path PathBuf "logs" Base directory for log files
max_files u32 5 Maximum number of backup files to keep
max_size u64 20 * 1024 * 1024 (20MB) Maximum size per log file in bytes
is_async bool false Reserved for async logging (not yet implemented)
instant_flush bool false Enable instant buffer flushing
file_name String "app" Base name for log files
instance_name String "default" Unique identifier for logger instance

Configuration Example

use rs_loglib::LogConfig;

let config = LogConfig::new()
    .with_path("/var/log/myapp")         // Custom log directory
    .with_file_name("server.log")        // Custom file name
    .with_max_size(10 * 1024 * 1024)     // 10MB per file
    .with_max_files(3)                   // Keep 3 backup files
    .with_instant_flush(true)            // Enable instant flush
    .with_instance_name("server");       // Instance identifier

File Naming Convention

  • Main log file: {file_name}.log
  • Rotated files: {file_name}.1.log, {file_name}.2.log, etc.
  • Example: server.logserver.1.logserver.2.log

Log Levels

Four log levels are available in order of severity:

Level Macro Usage
ERROR error!() Error conditions
WARN warn!() Warning messages for potential issues
INFO info!() General operational messages
DEBUG debug!() Detailed information for debugging

Additionally, there is a fatal!() macro that logs an ERROR level message with "FATAL:" prefix and terminates the program.

use rs_loglib::{debug, info, warn, error, fatal};

debug!(logger, "Debug information: {:?}", data);
info!(logger, "Server started on port {}", port);
warn!(logger, "Connection timeout after {} seconds", timeout);
error!(logger, "Failed to connect: {}", err);
fatal!(logger, "Unrecoverable error");  // Terminates the program

Log Format

Each log entry follows this format:

TIMESTAMP [THREAD_ID][LEVEL] MESSAGE

Example output:

2024-01-20 15:30:45.123 [01234][INFO ] Server started on port 8080
2024-01-20 15:30:45.125 [01234][ERROR] Failed to connect to database
  • TIMESTAMP: Local time in YYYY-MM-DD HH:MM:SS.mmm format
  • THREAD_ID: 5-digit hash of the thread ID
  • LEVEL: Log level (left-aligned, 5 characters)

Multiple Loggers

Each logger instance is independent and can have its own configuration:

use rs_loglib::{LogConfig, init_logger, info, error, warn};

// Application logger
let app_logger = init_logger(LogConfig::new()
    .with_instance_name("app")
    .with_path("logs")
    .with_file_name("app.log")
).unwrap();

// Access logger with different settings
let access_logger = init_logger(LogConfig::new()
    .with_instance_name("access")
    .with_path("logs")
    .with_file_name("access.log")
    .with_max_files(10)
).unwrap();

// Use different loggers
info!(app_logger, "Application started");
info!(access_logger, "GET /api/users 200");

Thread Safety

All logging operations are thread-safe. The library uses parking_lot::Mutex for efficient synchronization:

use rs_loglib::{LogConfig, init_logger, info};
use std::thread;

let logger = init_logger(LogConfig::new()
    .with_instance_name("threaded")
    .with_file_name("threaded.log")
).unwrap();

let logger_clone = logger.clone();

let handle = thread::spawn(move || {
    for i in 0..1000 {
        info!(logger_clone, "Message {} from spawned thread", i);
    }
});

for i in 0..1000 {
    info!(logger, "Message {} from main thread", i);
}

handle.join().unwrap();

Error Handling

The init_logger function returns a Result type for proper error handling:

use rs_loglib::{LogConfig, init_logger, info};

match init_logger(LogConfig::new().with_instance_name("app")) {
    Ok(logger) => {
        info!(logger, "Logger initialized successfully");
    }
    Err(e) => {
        eprintln!("Failed to initialize logger: {}", e);
    }
}

Log Rotation

Log rotation helps manage disk space:

  • When a log file exceeds max_size, it is automatically rotated
  • Existing backup files are shifted (app.1.logapp.2.log, etc.)
  • Files exceeding max_files count are automatically removed
  • A new empty log file is created for continued logging

Dependencies

  • parking_lot: High-performance synchronization primitives
  • time: Date and time formatting
  • lazy_static: Lazy static initialization

License

MIT License. See LICENSE for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages