Skip to content

Latest commit

Β 

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎨 log.rs

Beautiful, ergonomic logging and banners for Rust CLI applications

Licenses Linting Testing Packaging Cross-Build

Security Audit Scorecard Audit Quality Gate Status Security Rating Vulnerabilities

GitHub last commit Dependency Status Rust GitHub Release License


✨ Features

πŸͺ΅ Production-Ready Logging

  • Cargo-style verbosity levels (Quiet β†’ Normal β†’ Verbose β†’ Trace)
  • Dual output modes: beautiful text or structured JSON
  • Automatic task timing and span management
  • Global singleton for ergonomic API
  • Zero-cost quiet mode suppression

🎯 Elegant Banners

  • Clean ASCII art for professional first impressions
  • Smart address formatting (wildcard binds show as :PORT)
  • Optional taglines and version display
  • ANSI color support with graceful fallbacks

🎭 Multiple Styles

  • SimpleLogger: Classic ASCII symbols for maximum compatibility
  • ModernLogger: Beautiful unicode for modern terminals
  • Extensible formatter trait for custom styles

πŸ“Š Feature Matrix

A comparison of the three built‑in output styles: SimpleLogger, ModernLogger, and JSON mode.

Capability SimpleLogger ModernLogger JSON Mode
Human‑friendly text output βœ” Yes βœ” Yes (rich CLI style) βœ– No
Machine‑readable output βœ– No βœ– No βœ” Yes (structured JSON)
ANSI colors βœ” Yes (optional) βœ” Yes βœ– No
Unicode symbols βœ” Basic βœ” Polished (cliclack‑style) βœ– Not applicable
Quiet‑mode suppression βœ” Yes βœ” Yes βœ” Yes
Verbose/trace support βœ” Yes βœ” Yes βœ” Yes
Structured fields βœ– Ignored βœ– Ignored βœ” Included in JSON
Progress API compatibility βœ” Yes βœ” Yes βœ” Emits JSON events
Task tree introspection βœ” Text output βœ” Text output βœ” JSON output
Best for Simple CLIs, scripts Polished CLIs, user‑facing tools CI, log aggregation, automation

πŸš€ Quick Start

cargo add log-rs

Basic Logging

use log_rs::{
    logging::{set_logger, log, Printer, ModernLogger, Verbosity, LogFormat},
    banner::{BannerConfig, print as print_banner},
};

fn main() {
    // Initialize logger once at startup
    let logger = Printer::new(ModernLogger, LogFormat::Text, Verbosity::Normal);
    set_logger(logger);

    // Use anywhere in your app
    log::intro("Deploying application");
    log::step("Building assets");
    log::ok("Build successful");
    log::outro("Deployment complete");
    // β†’ Deploying application
    // β Ώ Building assets
    // βœ” Build successful
    // βœ” Deployment complete (took 2.3s)
}

Beautiful Banners

let banner = BannerConfig {
    name: "MyAPI",
    version: "1.0.0",
    tagline: Some("Fast and reliable REST API"),
    addr: Some("0.0.0.0:8080"),
};

print_banner(&banner);

Output:

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v1.0.0
Fast and reliable REST API
 ⇨ MyAPI listening on :8080

πŸ“– Documentation

Verbosity Levels

Control output detail with four levels:

Level Flag Usage Output
Quiet -q Cron jobs, CI Errors only
Normal (default) Standard CLI Success, warnings, info
Verbose -v Troubleshooting + Debug logs, tracing spans
Trace -vv Deep debugging + Trace logs, full diagnostics

Output Formats

Text Mode (Human-Friendly)

βœ” Server started
β Ώ Processing request
⚠ Cache miss for key: user_123
βœ— Database connection failed

JSON Mode (Machine-Friendly)

{"level":"info","message":"βœ” Server started","timestamp":"2026-01-15T10:30:00Z"}
{"level":"warn","message":"⚠ Cache miss","timestamp":"2026-01-15T10:30:01Z"}
{"level":"error","message":"βœ— Database connection failed","timestamp":"2026-01-15T10:30:02Z"}

Logger API

// Status messages
log().ok("Operation successful");
log().warn("Potential issue detected");
log().err("Operation failed");
log().info("Informational message");
log().dim("Muted remark");

// Task management
log().intro("Starting deployment");  // Begins a timed task
log().step("Building assets");       // Progress indicator
log().outro("Deployment complete");  // Ends task, shows duration

// Debug output (verbose mode only)
log().debug("Cache hit rate: 87%");
log().trace("SQL: SELECT * FROM users");

Banner Configuration

pub struct BannerConfig<'a> {
    pub name: &'a str,              // Required: app name
    pub version: &'a str,           // Required: version string
    pub tagline: Option<&'a str>,   // Optional: description
    pub addr: Option<&'a str>,      // Optional: bind address
}

Address Formatting:

  • 127.0.0.1:8080 β†’ displays as 127.0.0.1:8080
  • 0.0.0.0:8080 β†’ displays as :8080 (cleaner for wildcards)
  • [::]:8080 β†’ displays as :8080
  • Invalid/empty β†’ omitted from banner

🎨 Formatter Comparison

SimpleLogger (ASCII)

+ Configuration loaded
! Cache not configured
X Database timeout
* Processing items
β†’ Starting deployment
βœ“ Deployment complete

ModernLogger (Unicode)

βœ” Configuration loaded
⚠ Cache not configured
βœ— Database timeout
β Ώ Processing items
β†’ Starting deployment
βœ” Deployment complete
πŸ” Debug information
… Trace details

πŸ“š Examples

Run the included examples to see the loggers in action:

# Simple ASCII logger
cargo run --example simple-logger
cargo run --example simple-logger -- -v

# Modern unicode logger
cargo run --example modern-logger
cargo run --example modern-logger -- --json

# Quiet mode (errors only)
cargo run --example modern-logger -- -q

πŸ—οΈ Architecture

Two-Layer Design:

  1. FormatLogger β†’ Formats messages into styled strings

    • SimpleLogger: ASCII symbols
    • ModernLogger: Unicode symbols
    • Implement your own for custom styles
  2. ScreenLogger β†’ Prints formatted messages

    • Printer: Manages spans, timing, output routing
    • Integrates with tracing for structured logs

Benefits:

  • Clean separation of formatting and I/O
  • Easy to test formatters without side effects
  • Trivial to add new output styles
  • Swap backends without changing user code

🀝 Integration

With Tracing

The logger integrates seamlessly with the tracing ecosystem:

use tracing::info;

// In verbose mode, log() calls emit tracing events
log().intro("Processing batch");  // Creates a tracing span
log().step("Item 1");              // Nested span
log().outro("Batch complete");    // Closes span with timing

// Regular tracing works alongside
info!("Direct tracing event");

With Clap

use clap::Parser;

#[derive(Parser)]
struct Cli {
    #[arg(short, long)]
    quiet: bool,
    
    #[arg(short, long, action = clap::ArgAction::Count)]
    verbose: u8,
}

fn main() {
    let cli = Cli::parse();
    
    let verbosity = match (cli.quiet, cli.verbose) {
        (true, _) => Verbosity::Quiet,
        (_, 0) => Verbosity::Normal,
        (_, 1) => Verbosity::Verbose,
        (_, _) => Verbosity::Trace,
    };
    
    let logger = Printer::new(ModernLogger, LogFormat::Text);
    set_logger(logger);
    
    // Your app logic...
}

🎯 Design Philosophy

Great CLIs are invisible until you need them.

This toolkit prioritizes:

  • Ergonomics β†’ log().ok("done") beats dependency injection
  • Clarity β†’ Visual symbols communicate status instantly
  • Performance β†’ Lazy formatting, zero-cost abstractions
  • Flexibility β†’ Start simple, scale to production
  • Professionalism β†’ Output that looks polished everywhere

Whether you're building a quick script or a production service, these tools adapt to your needs without getting in your way.


πŸ§ͺ Testing

# Run all tests
cargo test

# Run specific module tests
cargo test logger_tests
cargo test banner_tests

# Run with output
cargo test -- --nocapture

πŸ“‹ Roadmap

A quick reference table summarizing the major enhancements planned for the logger.

Feature Description Status
Structured Fields Attach key/value metadata to any log call for richer JSON output and better machine parsing. Planned
Progress API Lightweight progress handle for long-running tasks with update, tick, and finish. Planned
Task Tree Visualizer Dump active tasks and steps with timing information in verbose/trace mode. Partial
Quiet‑But‑Timed Mode Quiet mode still prints timing summaries for tasks and steps. Planned
Plugin System for Custom Formatters Allow users to register custom formatters, themes, or output styles. Planned
Compile‑Time Log‑Level Stripping Macros that compile to nothing unless enabled, keeping release builds lean. Planned
Log Capture API for Tests Capture logs programmatically for assertions in unit tests. Planned
OpenTelemetry Integration Optional feature to export spans and events to tracing backends like Jaeger or Honeycomb. Planned
Sampling for High‑Volume Logs Prevent log floods by sampling trace/debug events. Planned
Emoji & Symbol Refinement Improved glyphs for debug/trace to enhance readability. Complete
Developer‑Mode Banner Friendly banner shown when running with RUST_LOG=debug or trace. Complete

πŸ“„ License

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


πŸ™ Acknowledgments

Inspired by:


πŸ€” FAQ

Q: Can I use both SimpleLogger and ModernLogger in the same app?
A: No, you set one logger globally at startup. Choose based on your target environment.

Q: Does quiet mode completely silence output?
A: No, errors always print. Quiet mode is for automation where you only want failures.

Q: Can I customize the banner ASCII art?
A: Currently no, but you can print your own before calling print_banner(). Open an issue if you need this feature!

Q: Is this production-ready?
A: Yes! The logger is built on the battle-tested tracing ecosystem and includes comprehensive tests.

Q: How do I capture logs in tests?
A: Use tracing-subscriber test utilities or capture stdout/stderr. See the test files for examples.


Documentation β€’ Crates.io β€’ Report Bug β€’ Request Feature

Made with ❀️ for the Rust CLI community

About

Beautiful, ergonomic logging and banners for Rust CLI applications

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages