Easy to use, Efficient, Structured, Console logging, File logging, File rotation, File compression, Synchronous logging, Asynchronous loggingtrace, debug, info, warn, error, and fatal log levels.RUST_LOG.[dependencies]
tklog = "0.3.0" # "0.x.x" current version
The simplest way to use tklog involves direct macro calls:
use tklog::{trace, debug, error, fatal, info, warn};
fn testlog() {
trace!("trace>>>>", "aaaaaaaaa", 1, 2, 3, 4);
debug!("debug>>>>", "bbbbbbbbb", 1, 2, 3, 5);
info!("info>>>>", "ccccccccc", 1, 2, 3, 5);
warn!("warn>>>>", "dddddddddd", 1, 2, 3, 6);
error!("error>>>>", "eeeeeeee", 1, 2, 3, 7);
fatal!("fatal>>>>", "ffffffff", 1, 2, 3, 8);
}
[TRACE] 2024-05-26 11:47:22 testlog.rs 27:trace>>>>,aaaaaaaaa,1,2,3,4
[DEBUG] 2024-05-26 11:47:22 testlog.rs 28:debug>>>>,bbbbbbbbb,1,2,3,5
[INFO] 2024-05-26 11:47:22 testlog.rs 29:info>>>>,ccccccccc,1,2,3,5
[WARN] 2024-05-26 11:47:22 testlog.rs 30:warn>>>>,dddddddddd,1,2,3,6
[ERROR] 2024-05-26 11:47:22 testlog.rs 31:error>>>>,eeeeeeee,1,2,3,7
[FATAL] 2024-05-26 11:47:22 testlog.rs 32:fatal>>>>,ffffffff,1,2,3,8
use tklog::{
sync::Logger,LEVEL, LOG,
Format, MODE,
};
fn log_init() {
LOG.set_console(true) // Enables console logging
.set_level(LEVEL::Info) // Sets the log level; default is Debug
.set_format(Format::LevelFlag | Format::Time | Format::ShortFileName) // Defines structured log output with chosen details
.set_cutmode_by_size("tklogsize.txt", 1<<20, 10, true) // Cuts logs by file size (1 MB), keeps 10 backups, compresses backups
.set_formatter("{level}{time} {file}:{message}\n"); // Customizes log output format; default is "{level}{time} {file}:{message}"
}
This illustrates global, singleton-style logging setup. Additionally, tklog facilitates custom multi-instance logging configurations, useful in systems requiring distinct logging structures across different components.
tklog also accommodates multiple instances for scenarios that require distinct logging configurations. Each instance can possess its unique settings for console output, log level, file rotation, and a custom formatter.
use tklog::{
debugs, errors, fatals, infos,
sync::Logger,LEVEL, LOG,
traces, warns, Format, MODE,
};
fn testmutlilog() {
let mut log = Logger::new();
log.set_console(true)
.set_level(LEVEL::Debug) //Set the log level to Debug
.set_cutmode_by_time("tklogs.log", MODE::DAY, 10, true) //Split log files daily, keep up to 10 backups, and compress them
.set_formatter("{message} | {time} {file}{level}\n"); //Customize the log structure's output format and additional content
let mut logger = Arc::clone(&Arc::new(Mutex::new(log)));
let log = logger.borrow_mut();
traces!(log, "traces>>>>", "AAAAAAAAA", 1, 2, 3, 4);
debugs!(log, "debugs>>>>", "BBBBBBBBB", 1, 2, 3, 5);
infos!(log, "infos>>>>", "CCCCCCCCC", 1, 2, 3, 5);
warns!(log, "warns>>>>", "DDDDDDDDDD", 1, 2, 3, 6);
errors!(log, "errors>>>>", "EEEEEEEE", 1, 2, 3, 7);
fatals!(log, "fatals>>>>", "FFFFFFFF", 1, 2, 3, 8);
thread::sleep(Duration::from_secs(1))
}
debugs>>>>,BBBBBBBBB,1,2,3,5 | 2024-05-26 14:13:25 testlog.rs 70[DEBUG]
infos>>>>,CCCCCCCCC,1,2,3,5 | 2024-05-26 14:13:25 testlog.rs 71[INFO]
warns>>>>,DDDDDDDDDD,1,2,3,6 | 2024-05-26 14:13:25 testlog.rs 72[WARN]
errors>>>>,EEEEEEEE,1,2,3,7 | 2024-05-26 14:13:25 testlog.rs 73[ERROR]
fatals>>>>,FFFFFFFF,1,2,3,8 | 2024-05-26 14:13:25 testlog.rs 74[FATAL]
Example:
LOG.set_level(LEVEL::Info) //Sets the log level to Info
.set_console(bool). LOG.set_console(false) //Disables console logging (default is true)
Format::Nano : No formatting
Format::Date : Outputs date (e.g., 2024-05-26)
Format::Time : Outputs time to seconds (e.g., 14:13:25)
Format::Microseconds :Outputs time with microseconds (e.g., 18:09:17.462245)
Format::LongFileName :Full file path with line number (e.g., tests/testlog.rs 25)
Format::ShortFileName : Abbreviated file path with line number (e.g., testlog.rs 25)
Format::LevelFlag : Log level marker (e.g., [Debug]).
For custom formats:
LOG.set_format(Format::LevelFlag | Format::Time | Format::ShortFileName)
Default is "{level}{time} {file}:{message}\n".
{level}: Log level indicator, e.g., [Debug].
{time}: Logged timestamp.
{file}: Filename and line number.
{message}: Log content.
LOG.set_formatter("{message} | {time} {file}{level}\n")
Reminder: Text outside the {level}, {time}, {file}, and {message} tags is output verbatim, including delimiters, spaces, and newlines.
Modes: MODE::HOUR, MODE::DAY, MODE::MONTH.
Use .set_cutmode_by_time() with:
- File path
- Time mode
- Maximum backup count
- Compression option
let mut log = Logger::new();
log.set_cutmode_by_time("/usr/local/tklogs.log", MODE::DAY, 0, false);
This configures the log to be stored at /usr/local/tklogs.log, rotated daily, with no limit on backups, and without compressing daily logs.
Backup Naming Conventions:
tklogs_20240521.logtklogs_20240522.logtklogs_2024052110.logtklogs_2024052211.logtklogs_202403.logtklogs_202404.logUtilize .set_cutmode_by_size() with the following parameters:
let mut log = Logger::new();
log.set_cutmode_by_size("tklogs.log", 100<<20, 10, true);
Here, tklogs.log denotes the path, with files rolling at 100 MB each, retaining 10 backups, and compressing them.
Backup File Naming Convention:
tklogs_1.log.gz
tklogs_2.log.gz
tklogs_3.log.gz
.set_cutmode_by_mixed() Function, Parameters Include:Example
let mut log = Logger::new();
log.set_cutmode_by_mixed("/usr/local/tklogs.log", 1 << 30, MODE::DAY, 10, true);
The backup file path is /usr/local/tklogs.log. The log file will roll over when it reaches 1GB (1<<30) in size. The rolling time mode is set to daily backups. The parameter 10 indicates that a maximum of 10 recent backup files will be retained. The parameter true indicates that backup log files will be compressed.
tklogs_20240521_1.logtklogs_20240521_2.logtklogs_20240521_3.logtklogs_20240521_4.logtklogs_20240522_1.logtklogs_20240522_2.logtklogs_20240522_3.logtklogs_20240522_4.log
Mixed Backup by Hour and Size, for example:
tklogs_2024052110_1.logtklogs_2024052110_2.logtklogs_2024052110_3.logtklogs_2024052211_1.logtklogs_2024052211_2.logtklogs_2024052211_3.log
Mixed Backup by Month and Size, for example:
tklogs_202403_1.logtklogs_202403_2.logtklogs_202403_3.logtklogs_202404_1.logtklogs_202404_2.logtklogs_202404_3.logLog Printing Methods:
trace!, debug!, info!, warn!, error!, fatal!
Multiple Instances:
traces!, debugs!, infos!, warns!, errors!, fatals!Asynchronous Logging
async_trace!, async_debug!, async_info!, async_warn!, async_error!, async_fatal!
Multiple Instances Async:
async_traces!, async_debugs!, async_infos!, async_warns!, async_errors!, async_fatals!Example: Global Asynchronous Usage
use tklog::{
async_debug, async_error, async_fatal, async_info, async_trace, async_warn, LEVEL, Format, ASYNC_LOG
};
async fn async_log_init() {
// Configure global singleton
ASYNC_LOG
.set_console(false) // Disable console output
.set_level(LEVEL::Trace) // Set log level to Trace
.set_format(Format::LevelFlag | Format::Time | Format::ShortFileName) // Define structured logging output
.set_cutmode_by_size("tklog_async.txt", 10000, 10, false) // Rotate log files by size, every 10,000 bytes, with 10 backups
.await;
}
#[tokio::test]
async fn testlog() {
async_log_init().await;
async_trace!("trace>>>>", "aaaaaaa", 1, 2, 3);
async_debug!("debug>>>>", "aaaaaaa", 1, 2, 3);
async_info!("info>>>>", "bbbbbbbbb", 1, 2, 3);
async_warn!("warn>>>>", "cccccccccc", 1, 2, 3);
async_error!("error>>>>", "ddddddddddddd", 1, 2, 3);
async_fatal!("fatal>>>>", "eeeeeeeeeeeeee", 1, 2, 3);
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
}
[TRACE] 20:03:32 testasynclog.rs 20:trace>>>>,aaaaaaa,1,2,3
[DEBUG] 20:03:32 testasynclog.rs 21:debug>>>>,aaaaaaa,1,2,3
[INFO] 20:03:32 testasynclog.rs 22:info>>>>,bbbbbbbbb,1,2,3
[WARN] 20:03:32 testasynclog.rs 23:warn>>>>,cccccccccc,1,2,3
[ERROR] 20:03:32 testasynclog.rs 24:error>>>>,ddddddddddddd,1,2,3
[FATAL] 20:03:32 testasynclog.rs 25:fatal>>>>,eeeeeeeeeeeeee,1,2,3
use std::sync::Arc;
use tklog::{
async_debugs, async_errors, async_fatals, async_infos, async_traces, async_warns, LEVEL, Format, ASYNC_LOG, MODE
};
#[tokio::test]
async fn testmultilogs() {
let mut log = tklog::Async::Logger::new();
log.set_console(false)
.set_level(LEVEL::Debug)
.set_cutmode_by_time("tklogasync.log", MODE::DAY, 10, true)
.await
.set_formatter("{message} | {time} {file}{level}\n");
let mut logger = Arc::clone(&Arc::new(Mutex::new(log)));
let log = logger.borrow_mut();
async_traces!(log, "async_traces>>>>", "AAAAAAAAAA", 1, 2, 3);
async_debugs!(log, "async_debugs>>>>", "BBBBBBBBBB", 1, 2, 3);
async_infos!(log, "async_infos>>>>", "CCCCCCCCCC", 1, 2, 3);
async_warns!(log, "async_warns>>>>", "DDDDDDDDDD", 1, 2, 3);
async_errors!(log, "async_errors>>>>", "EEEEEEEEEEE", 1, 2, 3);
async_fatals!(log, "async_fatals>>>>", "FFFFFFFFFFFF", 1, 2, 3);
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
}
async_debugs>>>>,BBBBBBBBBB,1,2,3 | 2024-05-26 20:10:24 testasynclog.rs 45[DEBUG]
async_infos>>>>,CCCCCCCCCC,1,2,3 | 2024-05-26 20:10:24 testasynclog.rs 46[INFO]
async_warns>>>>,DDDDDDDDDD,1,2,3 | 2024-05-26 20:10:24 testasynclog.rs 47[WARN]
async_errors>>>>,EEEEEEEEEEE,1,2,3 | 2024-05-26 20:10:24 testasynclog.rs 48[ERROR]
async_fatals>>>>,FFFFFFFFFFFF,1,2,3 | 2024-05-26 20:10:24 testasynclog.rs 49[FATAL]
uselog() function```rust use std::{thread, time::Duration}; use tklog::{Format, LEVEL, LOG}; fn test_synclog() { //init LOG LOG.set_conso
$ claude mcp add tklog \
-- python -m otcore.mcp_server <graph>