rust tracing 的实用实践

1. 引子

最近想要迁移一部分java应用至rust,在实际体验了tklog,log4rs,和tracing三款流行的日志框架后,最后选用了tracing,log4rs的文件备份文件名没有时间,不便于管理,tklog的功能稍显简陋,在使用uselog()后会将某些底层包日志输出至终端,即使过滤掉某第三方个包(假设叫A)之后,这个包依赖的第三方包(A依赖的第三方包B)的日志依旧会被显示,但是tklog本身又无法显示包名,只能显示文件名,根本不知道这个日志是从哪个包漏出来的XD,最后在经历多次尝试后最终选定了使用最广泛的tracing!

2. 加入tracing包

log = "0.4" #使用log门面
tracing = "0.1" #本体
tracing-appender = { package = "tracing-appender-plus", version = "0.2", features = ["local-time",] } #滚动日志,package里的是文件滚动的增强,原版的只使用utc+0配置,非utc+0时区的日志时间文件名不正确。说一个好好笑的事情,这个问题存在3年了,有人提了issue给维护者了,维护者考虑再三说想用chrono的时间替代原来的,但是因为chrono好久没更新了,有个cve漏洞没修,所以就一直放着,一直不改,怎么说呢,没勺子不能用筷子吃饭吗?加一个手动设置时间偏移量的函数不行吗?ememem...
tracing-subscriber = { version = "0.3", features = ["time", "env-filter"] } #日志订阅,tracing默认不打印日志,需要订阅才会打印
time = { version = "0.3", features = ["macros"] } #时间包,用来格式化日志和终端的时间显示

3. 上代码

use time::macros::{format_description, offset};
use tracing_appender::{non_blocking::WorkerGuard, rolling::{RollingFileAppender, Rotation}};
use tracing_subscriber::{fmt::{time::OffsetTime, writer::MakeWriterExt}, EnvFilter};
pub fn tracing_init() -> (WorkerGuard, WorkerGuard) {
    //格式化时间
    let time_fmt =
        format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]");//精确到毫秒
    let timer = OffsetTime::new(offset!(+8), time_fmt);
    //创建滚动日志
    let file_appender = RollingFileAppender::builder()
        .rotation(Rotation::DAILY)//按天滚动
        .filename_prefix("service")//日志前缀
        .filename_suffix("log")//日志文件后缀名
        .max_log_files(30)//保留的日志最大数量
        .build("logs")//日志文件所在的文件夹,默认./的相对路径
        .expect("failed to initialize rolling file appender");
    //使用非阻塞输出
    let (stdout, guard1) = tracing_appender::non_blocking(std::io::stdout());//异步输出到stdout
    let (file, guard2) = tracing_appender::non_blocking(file_appender);//异步输出到文件

    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from(
            "warn,actix_web1=debug,nacos_rust_client=info",
        ))//这里可以自定义某些第三方库的日志是否打印,第一个是全局日志等级,后面的是自定义包
        .with_line_number(true)//显示行数
        .with_thread_ids(true)//显示线程id
        .with_ansi(false)//是否添加颜色信息,对于不支持颜色文本查看器日志文件会有乱码
        .with_timer(timer)//设置时间格式化样式
        .with_writer(file.and(stdout))//设置输出
        .init();//初始化
    (guard1, guard2)//一定要在主函数持有这两个异步缓冲区,否则无法输出
}

4. 参考文献

  1. https://probiecoder.cn/rust/tracing.html
  2. https://blog.csdn.net/qq_54714089/article/details/136717431
posted @ 2024-12-22 01:00  Jiajie6591  阅读(9)  评论(0编辑  收藏  举报