π A beautiful, terminal-focused structured logger for Rust
CCB brings elegance and visual appeal to the Rust ecosystem. It is designed for command-line interface (CLI) applications that want to achieve beautiful, readable, and structured log output.
- Semantic Log Levels: Trace, Debug, Info, Warn, Error with four-character alignment
- Automatic Colors: Beautiful colored output with smart terminal detection
- Precise Timestamps: High-precision timestamps in
2006-01-02 03:04:05.789format - Chainable Context: Add structured key-value pairs with
with(key, value) - Simple Macros: Easy-to-use macros with variadic arguments support
- Global Logger: Set and use a global logger instance across your application
- Terminal Friendly: No icons, maximum compatibility across terminals
- Zero Config: Works beautifully out of the box with sensible defaults
Add CCB Logger to your Cargo.toml:
[dependencies]
ccb = "0.1.0"use ccb::{info, warn, error, debug, trace};
fn main() {
// Simple logging
info!("Application started");
warn!("This is a warning");
error!("Something went wrong");
// With structured fields
info!("User login", "user_id", "12345", "ip", "192.168.1.100");
error!("Database error", "table", "users", "error", "connection timeout");
}use ccb::Logger;
fn main() {
// Enable JSON output for structured logging
let logger = Logger::new()
.with_json_output(true)
.with_timestamp_format("%Y-%m-%dT%H:%M:%S%.3fZ");
logger.info("User authenticated", "user_id", "12345", "ip", "192.168.1.100");
// Output: {"timestamp":"2024-01-15T14:30:25.123Z","level":"INFO","message":"User authenticated","user_id":"12345","ip":"192.168.1.100"}
}use ccb::{Logger, Level, set_global_logger};
fn main() {
// Create a custom logger
let logger = Logger::new()
.with_level(Level::Debug)
.with_colors(true)
.with_timestamp(true)
.with_json_output(false)
.with_timestamp_format("%Y-%m-%d %H:%M:%S%.3f")
.with_field_order(vec![
"timestamp".to_string(),
"level".to_string(),
"message".to_string()
])
.with("service", "my-app")
.with("version", "1.0.0");
// Set as global logger
set_global_logger(logger);
// Now all macro calls will use the configured logger
debug!("Debug message with context");
info!("Request processed", "method", "GET", "path", "/api/users");
}use ccb::Logger;
fn main() {
// Enable JSON output for machine-readable logs
let logger = Logger::new()
.with_json_output(true)
.with_timestamp_format("%Y-%m-%dT%H:%M:%S%.3fZ")
.with_field_order(vec!["timestamp", "level", "message", "service"]);
// Log messages will be output as JSON
info!("User login", "user_id", "12345", "ip", "192.168.1.100");
// Output example:
// {"timestamp":"2024-01-15T14:30:25.123Z","level":"INFO","message":"User login","user_id":"12345","ip":"192.168.1.100","service":"my-app"}
}use ccb::{Logger, Level, Config};
fn main() {
// Custom configuration
let config = Config {
level: Level::Trace,
use_colors: false, // Disable colors for CI/CD
show_timestamp: true,
};
let logger = Logger::with_config(config)
.with("component", "auth")
.with("environment", "production");
// Direct logger usage
logger.trace("Entering function", &[("fn", "authenticate")]);
logger.info("Authentication successful", &[("user", "alice")]);
logger.error("Rate limit exceeded", &[("ip", "192.168.1.1"), ("attempts", "10")]);
}2024-01-15 14:30:25.1234 INFO Application started
2024-01-15 14:30:25.1235 WARN Configuration file not found path=config.toml
2024-01-15 14:30:25.1236 INFO User login user_id=12345 ip=192.168.1.100
2024-01-15 14:30:25.1237 ERRO Database connection failed error=timeout retry_count=3
2024-01-15 14:30:25.1238 DEBG Cache hit key=user:12345 ttl=300
CCB supports five log levels with four-character alignment:
| Level | Code | Color | Description |
|---|---|---|---|
| Trace | TRCE |
Cyan | π Detailed tracing information |
| Debug | DEBG |
Blue | π Debug information for developers |
| Info | INFO |
Green | βΉοΈ General information messages |
| Warn | WARN |
Yellow | |
| Error | ERRO |
Red | β Error conditions |
with_level(level)- Set minimum log levelwith_colors(bool)- Enable/disable colored outputwith_timestamp(bool)- Show/hide timestampswith(key, value)- Add context key-value pair
CCB automatically detects if output is going to a terminal and enables colors accordingly. You can override this behavior:
let logger = Logger::new().with_colors(false); // Force disable colorsRun the test suite:
cargo testRun tests with output:
cargo test -- --nocaptureCheck out the examples/ directory for more usage patterns:
cargo run --example basic_usageContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- π΄ Fork the repository
- π Create your feature branch (
git checkout -b feature/amazing-feature) - β
Commit your changes (
git commit -m 'Add some amazing feature') - π€ Push to the branch (
git push origin feature/amazing-feature) - π Open a Pull Request
- Add
asynclogging methods andasync-stdintegration - Avoid HashMap cloning, use
Arc<Context>orCow<str>for string allocation optimization - Use
RwLockinstead ofMutexto avoid deadlock risks - Split the 1000+ lines
lib.rsinto multiple modules (levels, formatters, outputs, etc.) - Add JSON Schema support and custom field serialization
- Add file output, rotation, and compression features
- Support complex filtering based on field values and regex patterns
- Add boundary tests, stress tests, and concurrency tests
- Support configuration file and environment variable driven configuration
- Support custom formatters and interceptors
- Output to console, file, and network simultaneously
- Sampling and aggregation for high-frequency logs
- Lightweight mode optimized for production environments
- Automatically add call stack, thread ID, and other fields
- Automatic detection of development/testing/production environments
This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by charmbracelet/log β€οΈ
- CCB has no real meaning, the name was given by a friend
- Built with β€οΈ for the Rust community
- Thanks to all contributors! π
- charmbracelet/log - The original Go implementation
- env_logger - Simple logger controlled via environment
- tracing - Application-level tracing framework