donnie4w / tklog

lightweight and efficient rust structured log library with support for log levels, file segmentation, compressed archiving
https://crates.io/crates/tklog
Apache License 2.0
58 stars 4 forks source link

可以打印任何变量 #3

Open zqlpaopao opened 3 months ago

zqlpaopao commented 3 months ago
let r = vec![1,2,3,4];
    traces!(log, "traces>>>>{} AAAAAAAAA {} {} {} {:?}", "Some string", 1, 2, 3);

这样目前是无法打印的吗

donnie4w commented 3 months ago

traces!(log, "traces>>>>{} AAAAAAAAA {} {} {} {:?}", "Some string", 1, 2, 3); 是可以打印的。 打印结果是:[TRACE] 2024-06-05 22:59:09 testlog.rs 58:traces>>>>{} AAAAAAAAA {} {} {} {:?},Some string,1,2,3 这里 "traces>>>>{} AAAAAAAAA {} {} {} {:?}" 会被当初字符串直接打印出来。 跟标准库有一些区别。tklog提供的宏打印方法,第一个参数不是格式字符串。所有参数都是原样打印出来。

你的示例应该是漏掉了要打印的 vec!变量 。tklog提供的宏打印目前无法打印 vec! 类型,参数必须为基础数据类型或实现了 std::fmt::Display的对象。

如果打印 ("traces>>>>{} AAAAAAAAA {} {} {} {:?}", "Some string", 1, 2, 3,r) 你希望打印的结果是 traces>>>>Some string AAAAAAAAA 1 2 3 [1,2,3,4] 建议标准库的接口打印 tklog已经实现了标准库接口

tklog下个版本0.0.4 会提供一个类似标准库接口的方法,可以直接打印自定义格式化参数

donnie4w commented 3 months ago

tklog 0.0.4

#[test]
fn testformats() {
    let mut log = Logger::new();
    log.set_console(true)
        .set_level(LEVEL::Debug)
        .set_cutmode_by_time("tklogs.log", MODE::DAY, 10, true);
    let mut logger = Arc::clone(&Arc::new(Mutex::new(log)));
    let log = logger.borrow_mut();

    let v = vec![1, 2, 3];
    tklog::formats!(log, LEVEL::Debug, "Debug>>>{},{}>>>{:?}", 1, 2, v);

    let v2 = vec!['a', 'b'];
    tklog::formats!(log, LEVEL::Info, "Info>>>{},{}>>{:?}", 1, 2, v2);
    tklog::formats!(log, LEVEL::Warn, "Warn>>>{},{}", 1, 2);
    tklog::formats!(log, LEVEL::Error, "Error>>>{},{}", 1, 2);
    tklog::formats!(log, LEVEL::Fatal, "Fatal>>>{},{}", 1, 2);

    thread::sleep(Duration::from_secs(1))
}

执行结果:

[DEBUG] 2024-06-06 15:54:07 testsynclog.rs 80:Debug>>>1,2>>>[1, 2, 3]
[INFO] 2024-06-06 15:54:07 testsynclog.rs 83:Info>>>1,2>>['a', 'b']
[WARN] 2024-06-06 15:54:07 testsynclog.rs 84:Warn>>>1,2
[ERROR] 2024-06-06 15:54:07 testsynclog.rs 85:Error>>>1,2
[FATAL] 2024-06-06 15:54:07 testsynclog.rs 86:Fatal>>>1,2
zqlpaopao commented 3 months ago

好的 提个建议 如果能有个 异步 buf 写入 可以根据时间 数量 来刷到磁盘 和同步模式 (我之前用go写过 rust入手不久 ) 感觉会更好,此log 就很丰富了 有可能成为爆品

zqlpaopao commented 3 months ago

这样 这个log就要变成传入的 而且要全局的 在内部实现个format呢

donnie4w commented 3 months ago

好的 提个建议 如果能有个 异步 buf 写入 可以根据时间 数量 来刷到磁盘 和同步模式 (我之前用go写过 rust入手不久 ) 感觉会更好,此log 就很丰富了 有可能成为爆品

感谢建议!加入缓冲区写入机制的 目的应该是希望提高写入的吞吐量,这在高并发或高性能服务场景下,的确可以显著提升日志写入的效率。tklog目前默认使用延迟模式写日志, 在写入性能上有一定的优化效果,比正常多线程同步锁的模式在性能上高2-4倍。后面在性能优化上会重点考虑你的建议.

这样 这个log就要变成传入的 而且要全局的 在内部实现个format呢

新增的format主要是针对多实例的情况,所以log是要传入的。log对象并非必须要全局的,但是生命周期应该大于等于你调用的日志方法。

多实例主要应用在项目中需要设置多种日志规则,多个不同日志文件的情况。 如果你项目中不需要多实例,那么应该使用全局实例,全局实例的效率比多实例更高,而且支持标准库API

之所以fomat宏只实现了多实例,是因为标准库API本身就具备第一个参数格式化的功能:

使用 tklog+标准库log 的示例:用 uselog() 启用tklog支持标准库API

use std::{thread, time::Duration};
use tklog::{LEVEL, LOG};
fn test_synclog() {
    //初始化
    LOG.set_console(true)
        .set_level(LEVEL::Trace)
        .set_cutmode_by_size("logsize.log", 10000, 10, true)
        .uselog();  //启用官方log库
    let r = vec![1, 2, 3];
    log::trace!("trace>>>>{}{}{}{}{:?}", "aaaa", 1, 2, 3, r);
    log::debug!("debug>>>>{}{}{:?}", 1, 2, r);
    log::info!("info log");
    log::warn!("warn log");
    log::error!("error log");
    thread::sleep(Duration::from_secs(1))
}

执行结果:

[TRACE] 2024-06-06 17:53:25 testlog.rs 34:trace>>>>aaaa123[1, 2, 3]
[DEBUG] 2024-06-06 17:53:25 testlog.rs 35:debug>>>>12[1, 2, 3]
[INFO] 2024-06-06 17:53:25 testlog.rs 36:info log
[WARN] 2024-06-06 17:53:25 testlog.rs 37:warn log
[ERROR] 2024-06-06 17:53:25 testlog.rs 38:error log