#logging #terminal #async

traccia

A zero-dependency, flexible logging framework for Rust applications

11 releases (7 stable)

Uses new Rust 2024

new 2.2.1 Apr 12, 2025
2.1.1 Apr 10, 2025
1.4.2 Mar 9, 2025
0.2.2 Mar 3, 2025
0.1.0 Mar 1, 2025

#190 in Debugging

Download history 623/week @ 2025-03-01 118/week @ 2025-03-08 14/week @ 2025-03-15 94/week @ 2025-03-29 244/week @ 2025-04-05

356 downloads per month

MIT license

54KB
815 lines

Traccia 📝

A zero-dependency, all-in-one flexible logging framework for Rust applications.


1

2

3

4

Overview

This crate provides a configurable logging system that supports multiple output targets, customizable formatting, and different log levels. It can be used in both synchronous (blocking) and asynchronous contexts.

Features

  • Multiple Log Levels: Trace, Debug, Info, Warning, Error
  • Flexible Output Targets: Console, File, and extensible for custom targets
  • Customizable Formatting: Define your own log message formatting
  • Colored Output: Terminal-friendly colored output with automatic stripping for files
  • Async & Blocking Modes: Choose between synchronous or asynchronous logging
  • Thread-Safe: Designed for concurrent applications
  • Macro-Based API: Simple, expressive logging interface

Installation

Add this to your Cargo.toml:

[dependencies]
traccia = "2.2.1"

Quick Start

use traccia::{init, LogLevel, info, warn, error};

fn main() {
    // Initialize with Info level
    init(LogLevel::Info);

    // Log messages
    info!("Application started");
    warn!("Resource usage high: {}%", 85);
    error!("Connection failed: {}", "timeout");
}

Configuration

Basic Initialization

// Initialize with default settings (Info level, Console output)
traccia::init_default();

// Initialize with specific log level
traccia::init(LogLevel::Debug);

Custom Configuration

use traccia::{Config, LogLevel, File, Console};

// Create a custom configuration
let config = Config {
    level: LogLevel::Debug,
    targets: vec![
        Box::new(Console),
        Box::new(File::new("logs/app.log").unwrap())
    ],
    format: None, // Use default formatter
};

// Initialize with custom config
traccia::init_with_config(config);

Custom Formatter

use traccia::{Config, Formatter, Record};

struct MyFormatter;

impl Formatter for MyFormatter {
    fn format(&self, record: &Record) -> String {
        format!("{} [{}] {}: {}",
            chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
            record.level.default_coloring(),
            record.target,
            record.message
        )
    }
}

let config = Config {
    // ...
    format: Some(Box::new(MyFormatter)),
    // ...
};

Usage Examples

Basic Logging

trace!("Very detailed information");
debug!("Useful for debugging");
info!("Application progress: step {}", step_number);
warn!("Something potentially problematic happened");
error!("Operation failed: {}", error_message);
fatal!("The program crashed with error: ", error_message);

File Logging

use traccia::{Config, File, LogLevel, init_with_config};

// Create a file target
let file_target = File::new("logs/application.log").expect("Failed to open log file");

// Configure with file target
let config = Config {
    level: LogLevel::Info,
    targets: vec![Box::new(file_target)],
    format: None, // Use default formatter
};

// Initialize with this config
init_with_config(config);

Multiple Targets

use traccia::{Config, Console, File, LogLevel, init_with_config};

// Configure with both console and file targets
let config = Config {
    level: LogLevel::Debug,
    targets: vec![
        Box::new(Console),
        Box::new(File::new("logs/debug.log").unwrap()),
    ],
    format: None,
};

init_with_config(config);

Async Logging

This will be the default implementation. If you wish to change to a blocking logger, enable the blocking feature.

use traccia::{init_with_config, Config, LogLevel};

fn main() {
    // Initialize as usual
    init_with_config(Config::default_with_level(LogLevel::Info));

    // Log messages
    info!("Async logging enabled");
}

Creating Custom Targets

You can implement the Target trait to create custom log destinations:

use traccia::{Target, Error};

#[derive(Clone)]
struct NetworkTarget {
    endpoint: String,
}

impl NetworkTarget {
    fn new(endpoint: &str) -> Self {
        Self { endpoint: endpoint.to_string() }
    }
}

impl Target for NetworkTarget {
    fn write(&self, formatted: &str) -> Result<(), Error> {
        // Send log to network endpoint
        // ...
        Ok(())
    }
}

// Use it
let config = Config {
    // ...
    targets: vec![Box::new(NetworkTarget::new("https://logs.example.com"))],
    // ...
};

Performance Considerations

  • Blocking vs Async: Choose the appropriate mode based on your application needs
  • Level Filtering: Set appropriate log levels in production to minimize overhead
  • Format Complexity: Complex formatters may introduce additional performance costs

Integration with Other Libraries

This library is designed to be standalone!

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Dependencies

~0–255KB