Rust:tracing日志库笔记

本文介绍了Rust语言中的Tracing库,一个用于分布式追踪的日志系统,讨论了其版本、features、配置方法(如MaxLevelFilter、EnvFilter等)、subscriber的使用以及如何结合Console和文件日志输出。还提到了如何通过环境变量进行日志级别控制和test_writer在测试中的应用。
摘要由CSDN通过智能技术生成
[dependencies]  
tracing = { version = "0.1", features = ["max_level_trace", "release_max_level_info"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

可看做log的进化版,用于分布式追踪。

features = ["max_level_trace", "release_max_level_info"]可以指定tracing生成的日志的level范围,在编译期完成过滤。似乎不推荐使用

使用 tracing 记录日志 - Rust语言圣经(Rust Course)

Rust 语言的全链路追踪库 tracing - 知乎

tracing只是生成日志,但打印、记录还是要交给Collector,如tracing_subscriber。

span 等级问题

TODO

tracing_subscriber

fn main() {  
    // 设置一个Subscriber  
    tracing_subscriber::fmt().init();  

	//没有span也行,但不太符合规范
    let span = info_span!("root");  
    let _enter = span.enter();  
    
    info!("This is a test log message");  
}
tracing_subscriber::fmt()  
    .with_max_level(tracing::Level::TRACE)  
    .init();

fmt()返回一个SubscriberBuilder,可以使用with来添加配置。如果使用finish()则会生成Subscribe,然后要手动用registry挂载到全局;如果使用init()则自动挂载到全局,结束配置。

tracing_subscriber在引入features = ["env-filter"]后可以通过环境变量来设置日志范围,使用.with(tracing_subscriber::EnvFilter::from_default_env());后就会读取RUST_LOG环境变量作为其最大(即最低)日志级别。可以用build.rs来指定:

fn main() {
    println!("cargo:rustc-env=RUST_LOG=info");
}

使用layer实现同时打印到控制台和文件:

fn config_tracing(){  
    let console_subscriber = tracing_subscriber::fmt::layer()  
        .with_writer(std::io::stdout);  
    let log_file = std::fs::File::create("log.txt").unwrap();  
    let file_subscriber = tracing_subscriber::fmt::layer()  
        .with_writer(log_file)  
        .with_ansi(false);  
  
    let subscriber = tracing_subscriber::registry()  
        .with(console_subscriber)  
        .with(file_subscriber);  
  
    tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");  
}

filter

使用EnvFilter以进行日志过滤。

"debug,my_crate_name=trace,hyper=debug"意思是全局默认过滤到debug以上,my_crate_name过滤到trace,hyper过滤到debug。

使用try_from_env可以实现“如果环境变量有则用环境变量的,否则用unwrap_or_else中的”。比如下面的代码可以设置环境变量APP_LOG"trace,hyper=debug"以覆盖默认变量。

let env_filter = EnvFilter::try_from_env("APP_LOG")  
    .unwrap_or_else(|_| EnvFilter::new("debug,ipfs_node_wrapper=trace,hyper=debug"));  
  
let console_subscriber = tracing_subscriber::fmt::layer()  
    .with_writer(std::io::stdout)  
    .with_filter(env_filter);

测试时输出

测试lib crate时可能需要输出日志来debug,因此lib的toml中要在[dev-dependencies]下引入tracing_subscriber然后在测试的开头写上:

tracing_subscriber::fmt()
	.with_max_level(tracing::Level::DEBUG)
	.with_test_writer()
	.init();

with_test_writer开启了测试中的capture日志的功能。with_test_writer

tracing_appender

这是专门用于写日志到文件的库。

fn config_tracing(){  
    let console_subscriber = tracing_subscriber::fmt::layer()  
        .with_writer(std::io::stdout);  
  
    let file_appender = RollingFileAppender::new(  
        Rotation::HOURLY,  
        "log",  
        "ipfs_node_wrapper.log");  
    let file_subscriber = tracing_subscriber::fmt::layer()  
        .with_writer(file_appender)  
        .with_ansi(false);  

    let subscriber = tracing_subscriber::registry()  
        .with(console_subscriber)  
        .with(file_subscriber);  
  
    tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");  
}

或者更简单的官方例子:

use tracing_subscriber::fmt::writer::MakeWriterExt;

// Log all events to a rolling log file.
let logfile = tracing_appender::rolling::hourly("/logs", "myapp-logs");
// Log `INFO` and above to stdout.
let stdout = std::io::stdout.with_max_level(tracing::Level::INFO);

tracing_subscriber::fmt()
    // Combine the stdout and log file `MakeWriter`s into one
    // `MakeWriter` that writes to both
    .with_writer(stdout.and(logfile))
    .init();
  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值