| Crates.io | firo_logger |
| lib.rs | firo_logger |
| version | 1.1.2 |
| created_at | 2024-10-01 09:28:36.323744+00 |
| updated_at | 2025-08-15 08:07:18.387033+00 |
| description | A high-performance, feature-rich logger for Rust applications with colored output, structured logging, and advanced configuration |
| homepage | |
| repository | https://github.com/Mightybeast12/firo_logger/ |
| max_upload_size | |
| id | 1392668 |
| size | 227,152 |
A high-performance, feature-rich logger for Rust applications with colored output, structured logging, file rotation, async logging, and advanced configuration.
Add this to your Cargo.toml:
[dependencies]
firo_logger = "0.3.0"
use firo_logger::{init_default, log_info, log_error, log_success};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize the logger with default settings
init_default()?;
// Log some messages
log_info!("Application started");
log_success!("Configuration loaded successfully");
log_error!("Failed to connect to database: {}", "Connection timeout");
Ok(())
}
use firo_logger::{LoggerConfig, LogLevel, OutputFormat, init};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = LoggerConfig::builder()
.level(LogLevel::Debug)
.format(OutputFormat::Json)
.console(true)
.colors(true)
.file("app.log")
.rotate_by_size(10 * 1024 * 1024, 5) // 10MB, keep 5 files
.async_logging(1000)
.include_caller(true)
.include_thread(true)
.metadata("app", "my-app")
.metadata("version", "1.0.0")
.build();
init(config)?;
log_info!("Logger initialized with custom configuration");
Ok(())
}
The logger can be configured using environment variables:
FIRO_LOG_LEVEL: Set log level (ERROR, WARNING, INFO, SUCCESS, DEBUG)FIRO_LOG_FILE: Set log file pathFIRO_LOG_FORMAT: Set output format (text, json, plain)NO_COLOR: Disable colored outputFORCE_COLOR: Force colored output even when not in a terminaluse firo_logger::init_from_env;
fn main() -> Result<(), Box<dyn std::error::Error>> {
init_from_env()?;
log_info!("Logger configured from environment");
Ok(())
}
use firo_logger::{LoggerConfig, LogLevel, OutputFormat, RotationFrequency};
let config = LoggerConfig::builder()
// Basic settings
.level(LogLevel::Info)
.format(OutputFormat::Text)
// Console output
.console(true)
.colors(true)
.use_stderr(true) // Use stderr for errors/warnings
// File output
.file("logs/app.log")
.rotate_by_size(50 * 1024 * 1024, 10) // 50MB, keep 10 files
.rotate_by_time(RotationFrequency::Daily, 7) // Daily rotation, keep 7 days
// Performance
.async_logging(1000) // Enable async with 1000 message buffer
// Metadata and context
.include_caller(true)
.include_thread(true)
.datetime_format("%Y-%m-%d %H:%M:%S%.3f")
.metadata("service", "api-server")
.metadata("version", env!("CARGO_PKG_VERSION"))
// Module-specific filtering
.module_filter("hyper", LogLevel::Warning)
.module_filter("my_app::debug", LogLevel::Debug)
.build();
log_error!("Database connection failed: {}", error);
log_warning!("Deprecated API used: {}", api_name);
log_info!("User {} logged in", username);
log_success!("Payment processed: ${}", amount);
log_debug!("Processing request: {:?}", request);
use firo_logger::{log_with_metadata, LogLevel};
log_with_metadata!(
LogLevel::Info,
"User login",
"user_id" => "12345",
"ip_address" => "192.168.1.100",
"user_agent" => "Mozilla/5.0...",
"session_id" => session.id()
);
use firo_logger::{log_if, LogLevel};
let debug_mode = std::env::var("DEBUG").is_ok();
log_if!(debug_mode, LogLevel::Debug, "Debug mode is enabled");
let should_trace = user.is_admin();
log_if!(should_trace, LogLevel::Info, "Admin user {} performed action", user.name);
use firo_logger::{log_rate_limited, LogLevel};
use std::time::Duration;
// In a high-frequency loop
for i in 0..10000 {
// This will only log once per second maximum
log_rate_limited!(
Duration::from_secs(1),
LogLevel::Info,
"Processing item {}", i
);
}
use firo_logger::trace_function;
fn process_payment(amount: f64, user_id: u64) -> Result<(), PaymentError> {
trace_function!("process_payment", amount, user_id);
// Function implementation...
// Entry and exit will be automatically logged
Ok(())
}
use firo_logger::{time_block, LogLevel};
let result = time_block!(LogLevel::Info, "Database query", {
// Your expensive operation here
database.complex_query().await
});
use firo_logger::log_assert;
let user_id = get_user_id();
log_assert!(user_id > 0, "User ID must be positive, got {}", user_id);
// Debug-only assertions
log_debug_assert!(expensive_invariant_check(), "Invariant violated");
2024-08-14 09:33:45.123 [ ERROR]: Database connection failed: timeout
2024-08-14 09:33:45.124 [WARNING]: Deprecated API endpoint used
2024-08-14 09:33:45.125 [ INFO]: User alice logged in
2024-08-14 09:33:45.126 [SUCCESS]: Payment of $49.99 processed
2024-08-14 09:33:45.127 [ DEBUG]: Request processed in 23ms
{"timestamp":"2024-08-14T09:33:45.123Z","level":"ERROR","message":"Database connection failed: timeout","module":"myapp::db","caller":{"file":"src/db.rs","line":42}}
{"timestamp":"2024-08-14T09:33:45.124Z","level":"INFO","message":"User alice logged in","metadata":{"user_id":"12345","ip":"192.168.1.1"}}
2024-08-14 09:33:45 [ERROR]: Database connection failed: timeout
2024-08-14 09:33:45 [INFO]: User alice logged in
let config = LoggerConfig::builder()
.file("app.log")
.rotate_by_size(10 * 1024 * 1024, 5) // 10MB files, keep 5
.build();
Generated files:
app.log (current)app.log.1628934123 (backup)app.log.1628934100 (backup)use firo_logger::RotationFrequency;
let config = LoggerConfig::builder()
.file("app.log")
.rotate_by_time(RotationFrequency::Daily, 7) // Daily rotation, keep 7 days
.build();
Generated files:
app.log (current)app.log.2024-08-13 (yesterday)app.log.2024-08-12 (day before)For high-performance applications, enable async logging:
let config = LoggerConfig::builder()
.async_logging(10000) // Buffer up to 10,000 messages
.build();
// Logging calls return immediately, processing happens in background
for i in 0..1000000 {
log_info!("Processing item {}", i)?; // Very fast, non-blocking
}
log CrateEnable the log feature and use firo_logger as a backend:
[dependencies]
firo_logger = { version = "0.3.0", features = ["log"] }
log = "0.4"
use firo_logger::log_integration::init_with_log;
fn main() -> Result<(), Box<dyn std::error::Error>> {
init_with_log()?;
// Now you can use the standard log macros
log::info!("This works with firo_logger!");
log::error!("Error handling through standard log crate");
Ok(())
}
firo_logger is designed for high performance:
Benchmarks show firo_logger can handle:
The new version is fully backwards compatible. Your existing code will continue to work:
// Old API still works
use firo_logger::legacy::{Logger, LogLevel};
Logger::log(format_args!("Still works!"));
Logger::error(format_args!("Error handling"));
But we recommend migrating to the new API:
// New API
use firo_logger::{init_default, log_info, log_error};
init_default()?;
log_info!("Much better!")?;
log_error!("Improved error handling")?;
See the examples/ directory for more examples:
# Basic usage
cargo run --example basic_usage
# Advanced features
cargo run --example advanced_features
# Performance testing
cargo run --example performance_test --release
colors (default): ANSI color supportjson (default): JSON output format supportasync (default): Async logging supportlog: Integration with the standard log cratesyslog: Syslog output support (future feature)# Minimal build without async support
[dependencies]
firo_logger = { version = "0.3.0", default-features = false, features = ["colors"] }
Before pushing changes, run the comprehensive test suite:
# Run all CI checks locally
./test-local.sh
# Individual checks
cargo fmt -- --check
cargo clippy --all-features -- -D warnings
cargo test --all-features
cargo doc --no-deps --all-features
The project includes an automated release script that handles version bumping, testing, and publishing:
# Interactive mode - asks which increment type
./release.sh
# Direct version increment
./release.sh patch # 1.0.0 โ 1.0.1 (bug fixes)
./release.sh minor # 1.0.0 โ 1.1.0 (new features)
./release.sh major # 1.0.0 โ 2.0.0 (breaking changes)
# Preview changes without executing
./release.sh --dry-run
# Show help
./release.sh --help
๐ Pre-flight checks:
๐งช Quality assurance:
๐ Version management:
Cargo.toml versionCHANGELOG.md with release date๐ Publishing:
The project uses GitHub Actions for continuous integration and deployment:
To set up automated publishing:
CARGO_REGISTRY_TOKEN in GitHub repo Settings โ Secrets โ ActionsContributions 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.
git checkout -b feature/amazing-feature)./test-local.sh)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)This project is licensed under the MIT License - see the LICENSE file for details.
log crateenv_logger, slog, and tracing