Rust 日志记录库 tracing
#2023-09-26# #日志# #tracing#
一个好用的日志跟踪系统,可以帮助我们很快的定位程序中的 bug。tracing 不仅仅可以作为一个日志库去使用,还可以作为一个程序追踪库,帮助我们分析程序中存在的问题。
tracing 各个模块
-
tracing
: 作用域内的结构化日志记录和诊断系统。 -
tracing_appender
: 记录事件和跨度的编写者。也就是将日志写入文件或者控制台。 -
tracing_error
: 增强错误处理跟踪诊断信息的实用工具。 -
tracing_flame
: 用于生成折叠堆栈跟踪以生成Inferno火焰图和火焰图表的跟踪订阅者。 -
tracing_log
: 用于连接标准库日志系统和tracing系统的连接器。 -
tracing_subscriber
: 用于实现和组成tracing订阅者的工具集合。
常规使用思路
使用tracing_appender
创建控制台输出层和文件输出层。然后使用tracing_subscriber
进行事件的订阅。
在使用的时候可以使用tracing
进行日志和程序跟踪,也可使用标准log
库结合tracing_log
一同使用。
项目配置方法
在Cargo.toml文件中,添加依赖库
[dependencies]
# 日志系统
tracing = "0.1"
tracing-error = "0.2"
tracing-subscriber = { version = "0.3", features = ["std", "local-time"] }
tracing-appender = "0.2"
# color-eyre = "0.6"
日志系统初始化代码如下:
use tracing_appender::{non_blocking, rolling};
use tracing_error::ErrorLayer;
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, Layer, Registry};
pub fn logger_init() {
// 格式化输出层,并且输出到终端。
let formatting_layer = fmt::layer().pretty().with_writer(std::io::stdout);
// 文件输出层
let file_appender = rolling::daily("logs/", "log");
let (non_blocking_appender, _guard) = non_blocking(file_appender); // 输出非阻塞
let file_layer = fmt::layer()
.with_ansi(false)
.with_writer(non_blocking_appender)
.with_filter(tracing_subscriber::filter::LevelFilter::INFO) // 文件输出日志等级
.boxed();
Registry::default()
.with(ErrorLayer::default())
.with(formatting_layer)
.with(file_layer)
.init();
// color_eyre::install().unwrap();
}
在代码中使用日志
tracing的过程分为两个部分,span
和event
。
span
负责记录事件发生的地点和上下文信息,如果作用域内没有event
发生,span
不会输出任何信息。如果作用域内有event
发生,在输出event
信息的同时,也会将进入的span
信息从近到远依次输出,携带相关的上下文信息。
event
用于记录事件发生的情况,可以携带事件发生时产生的数据。
span:作用域记录
标记事件发生的上下文信息。有很多宏定义可以直接使用:
-
span!
: -
tracing_span!
:
或者时函数标记instructment
#[instructment]
fn func(){
...
}
例如
use tracing::{span, Level};
let span = span!(Level::TRACE, "my_span");
// `enter` returns a RAII guard which, when dropped, exits the span. this
// indicates that we are in the span for the current lexical scope.
// `enter`是一个 RAII(Resource Acquisition Is Initialization)守卫,
// 当这个变量被获取的时候,资源同时会被获取;变量被释放的时候,资源被释放。
let _enter = span.enter();
// perform some work in the context of `my_span`...
event:事件记录
use tracing::{event, Level}
event!(Level::INFO, passwd = "passwd");
标签:layer,span,tracing,event,日志,appender,Rust
From: https://www.cnblogs.com/qi-xmu/p/rust-log-record-library-traction-2liiil.html