Crates.io | flashlog |
lib.rs | flashlog |
version | 0.2.4 |
source | src |
created_at | 2024-08-29 11:31:21.63118 |
updated_at | 2024-11-25 03:03:11.430785 |
description | A fast logging library for Rust |
homepage | |
repository | https://github.com/JunbeomL22/flashlog |
max_upload_size | |
id | 1355987 |
size | 74,090 |
A blazingly fast Rust logging library with lazy evaluation.
flash_xxx!
macros is inherently lazy.JSON
format for easy parsing and analysis.Add FlashLog to your Cargo.toml
:
[dependencies]
flashlog = "0.2"
Basic usage example:
use flashlog::{Logger, LogLevel, flash_info};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let logger = Logger::initialize()
.with_file("logs", "message")?
.with_max_log_level(LogLevel::Info)
.launch();
flash_info!("Hello, FlashLog!");
Ok(())
}
FlashLog can easily log custom structs:
use serde::{Deserialize, Serialize};
use flashlog::{Logger, LogLevel, flash_info};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct LogStruct {
data: [u64; 10],
}
impl Default for LogStruct {
fn default() -> Self {
LogStruct { data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let logger = Logger::initialize()
.with_file("logs", "message")?
.with_max_log_level(LogLevel::Info)
.launch();
let log_struct = LogStruct::default();
flash_info!("Log message"; log_struct = log_struct);
Ok(())
}
Topic and message are optional and separated by a semicolon. In addition, messages can be added with key-value pairs
use flashlog::{flash_info, flush, Logger, LogLevel, TimeZone};
pub enum Hello {
World,
FlashLog,
}
impl std::fmt::Display for Hello {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Hello::World => write!(f, "World"),
Hello::FlashLog => write!(f, "FlashLog"),
}
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let _logger = Logger::initialize()
.with_file("logs", "message")? // Log to a file called "message" in the "logs" directory
.with_roll_period(RollingPeriod::Daily)? // Log file is rolled in daily basis
.with_max_roll_files(10)? // Ten old file will remain. if compress is true, there will remain 10 gz file (older log) as well
.with_compress(false)? // compress old log file
.with_console_report(true) // Enable logging to the console
.with_msg_flush_interval(2_000_000_000) // Flush every 2 seconds
.with_msg_buffer_size(10) // Flush when there are 10 more log messages
.with_max_log_level(LogLevel::Debug) // Set the maximum log level to Debug
.with_timezone(TimeZone::Local) // Use local timezone for timestamps
.launch();
flash_info!(Hello::FlashLog);
// {"date":"20240915","level":"Info","message":"","offset":9,"src":"src\\logger_v2.rs:346","time":"20:34:30.684:921:877","topic":"World"}
flash_info!(Hello::World);
// {"date":"20240915","level":"Info","message":"","offset":9,"src":"src\\logger_v2.rs:347","time":"20:34:30.684:922:238","topic":"FlashLog"}
flash_info!("Hello");
// {"date":"20240915","level":"Info","message":"","offset":9,"src":"src\\logger_v2.rs:348","time":"20:34:30.684:922:488","topic":"Hello"}
flash_info!("Hello"; "FlashLog");
// {"date":"20240915","level":"Info","message":"FlashLog","offset":9,"src":"src\\logger_v2.rs:349","time":"20:34:30.684:922:739","topic":"Hello"}
flash_info!("Hello"; "FlashLog"; version = "0.1.0");
// {"data":{"version":"0.1.0"},"date":"20240915","level":"Info","message":"FlashLog","offset":9,"src":"src\\logger_v2.rs:350","time":"20:34:30.684:924:813","topic":"Hello"}
flash_info!("Hello"; "FlashLog"; version = "0.1.0", author = "John Doe");
// {"data":{"author":"John Doe","version":"0.1.0"},"date":"20240915","level":"Info","message":"FlashLog","offset":9,"src":"src\\logger_v2.rs:351","time":"20:34:30.684:925:143","topic":"Hello"}
flash_info!(version = "0.1.0");
// {"data":{"version":"0.1.0"},"date":"20240915","level":"Info","message":"","offset":9,"src":"src\\logger_v2.rs:352","time":"20:34:30.684:925:394","topic":""}
flash_info!(version = "0.1.0", author = "John Doe");
// {"data":{"author":"John Doe","version":"0.1.0"},"date":"20240915","level":"Info","message":"","offset":9,"src":"src\\logger_v2.rs:353","time":"20:34:30.684:925:654","topic":""}
flash_info!("topic1"; "message {} {}", 1, 2);
// {"data":"","date":"20240915","level":"Info","message":"message 1 2","offset":9,"src":"src\\logger_v2.rs:354","time":"20:34:30.684:925:955","topic":"topic1"}
flash_info!("topic2"; "message {} {}", 1, 2; struct_info = 1, struct_info2 = 2);
// {"data":{"struct_info":1,"struct_info2":2},"date":"20240915","level":"Info","message":"message 1 2","offset":9,"src":"src\\logger_v2.rs:355","time":"20:34:30.684:926:847","topic":"topic2"}
flush!(); // this flushes regardless of the buffer size and flush interval
Ok(())
}
Print 500,000 logs. Perform the test 5 times. Before each test, sleep for 2 seconds, then print a warm-up message, and then continuously print 500,000 messages. Test has been done on two types: i32 and
struct LogStruct {
data: [u64; 10],
}
{"data":{"log_struct":{"data":[1,2,3,4,5,6,7,8,9,10]}},"date":"20240915","level":"Info","message":"","offset":9,"src":"src/main.rs:52","time":"20:52:02.998:044:806","topic":"Bench"}
2024-08-29 09:39:13.503+09 0ms INFO main [src/main.rs:57] Log message: LogStruct { data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }
2024-08-29 10:31:16.7598955 [INFO] Log message: LogStruct { data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }
Aug 29 01:53:20.725 INFO Log message: LogStruct { data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }
[2024-08-29T05:59:56.608510100Z INFO example_fern] Log message: LogStruct { data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }
2024-08-30T01:17:18.997070Z INFO example_tracing: Log message: LogStruct { data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }
Logger | i32 | 80 byte struct |
---|---|---|
flashlog | 48 ns | 60 ns |
ftlog | 260 ns | 480 ns |
fast_log | 410 ns | 358 ns |
slog | 250 ns | 452 ns |
fern | 3,813 ns | 3,962 ns |
tracing | 4,003 ns | 4,258 ns |
Logger | i32 | 80 byte struct |
---|---|---|
flashlog | 80 ns | 90 ns |
ftlog | 323 ns | 581 ns |
fast_log | 500 ns | 500 ns |
slog | 324 ns | 604 ns |
fern | 4,732 ns | 5,714 ns |
tracing | 5,177 ns | 6,190 ns |
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.