我这里有一个非常简单的代码示例,它只想获取我传入的列表的第一项。我一直在尝试通过跟踪来检测代码以帮助调试应用程序,但坦率地说,文档太复杂了,我无法完全理解。
use std::fmt::Debug;
use tracing::{span, Level, event};
fn main() {
pub fn calculate<T: Debug, const N: usize>(data_set: [T; N]) -> (i32, i32) {
// Tracing BoilerPlate
event!(Level::INFO, "something happened");
let span = span!(Level::INFO, "my_span");
let _guard = span.enter();
// Key Code
let _var = data_set.get(0);
println!("Output_1: {:?}", data_set.get(0));
event!(Level::DEBUG, "something happened inside my_span");
// Ignore
return (0, 0)
}
let data = [1509, 1857, 1736, 1815, 1576];
let _result = calculate(data);
}
Run Code Online (Sandbox Code Playgroud)
具体来说,我不明白在哪里可以查看event!日志。它们似乎没有打印到任何窗口或文件或任何东西。
有人可以指导我在哪里可以找到这些调试日志,或者为我提供如何使用跟踪箱的简化说明吗?
我正在学习 Axum,我想将日志记录添加到我组装的服务中,但不幸的是我无法让它工作。
我已添加 tower-http 来使用TraceLayer并将其添加到我的应用程序中:
# Cargo.toml
[dependencies]
axum = "0.6.1"
tower-http = { version = "0.3.5", features = ["trace"] }
Run Code Online (Sandbox Code Playgroud)
use tower_http::trace::TraceLayer;
let app = Router::new()
.route("/:name/path", axum::routing::get(handler))
.layer(TraceLayer::new_for_http())
Run Code Online (Sandbox Code Playgroud)
但是当我启动应用程序并向端点发出请求时,没有记录任何内容。是否有我可能错过的配置步骤?
我使用跟踪,我只想查看我自己的调试事件。然而,我依赖的一些板条箱也有跟踪支持,它们会乱七八糟的事件流。因此,当我将详细程度增加到 时DEBUG,我会在日志中看到很多这样的内容:
2022-08-04T20:52:24.523161Z DEBUG hyper::proto::h1::io: flushed 1008 bytes
Run Code Online (Sandbox Code Playgroud)
我尝试通过在此类调用周围添加跨度来关闭这些事件:
let response = {
let span = tracing::info_span!("my_span");
let _guard = span.enter();
client
// set up the request
.send()
.await
};
Run Code Online (Sandbox Code Playgroud)
我预计这些第 3 方DEBUG事件会消失,因为跨度的详细程度为INFO。但他们留下了。Span 的文档对Span 的详细程度的真正含义有些了解,所以我的解释可能完全错误。
如何设置依赖包的详细级别,以便只有我自己的DEBUG事件出现在跟踪日志中?
我使用环境变量设置详细级别RUST_LOG=debug,并设置跟踪订阅者,如下所示:
tracing_subscriber::fmt::init();
Run Code Online (Sandbox Code Playgroud)
相关部分Cargo.toml:
tracing = "0.1.36"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
Run Code Online (Sandbox Code Playgroud) 我将 Axum 用于相对简单的 Web API,并希望获得类似于 Go Gin、IIS 日志、Python FastAPI 等的传入请求的日志记录/跟踪输出 - 简单的路径和参数输出。
HTTP 层已添加到路由器:
let app = Router::new()
.route("/hello", get(hello_img))
.layer(TraceLayer::new_for_http());
Run Code Online (Sandbox Code Playgroud)
然而,还有很多额外的不需要的日志记录正在发生,所以我添加了一个过滤器来排除这些日志记录。添加过滤器后:
let filter = filter::Targets::new()
.with_target("tower_http::trace::on_response", Level::TRACE)
.with_target("tower_http::trace::on_request", Level::TRACE)
.with_default(Level::INFO);
Run Code Online (Sandbox Code Playgroud)
并将其添加到订阅者:
let tracing_layer = tracing_subscriber::fmt::layer();
tracing_subscriber::registry()
.with(tracing_layer)
.with(filter)
.init();
Run Code Online (Sandbox Code Playgroud)
详细信息(方法、URI、参数)都消失了。
即使没有指定格式更改,为什么会发生这种情况?如何在控制台中保留请求/响应跟踪,但过滤掉其他不需要的跟踪?
我需要动态地使用不同名称来检测跨度。如何创建具有动态命名的跟踪范围?
use tracing; // 0.1.22
fn main() {
let name: &'static str = "foo bar";
let span = tracing::span!(tracing::Level::TRACE, name);
let span_handle = span.enter();
tracing::info!("Hello, world!");
drop(span_handle);
}
Run Code Online (Sandbox Code Playgroud)
error[E0435]: attempt to use a non-constant value in a constant
--> src/main.rs:5:54
|
5 | let span = tracing::span!(tracing::Level::TRACE, name);
| ^^^^ non-constant value
Run Code Online (Sandbox Code Playgroud)
作为一名开发人员,我想动态调整日志级别。例如,我不想debug!在一切顺利时记录事件,但当发生某些情况时,我想调整日志级别,而无需重新启动应用程序来更改日志级别。我检查了文档,但找不到示例,所以我想知道是否可以这样做。
// how can I change the max_level of subscriber after it was initialised?
let subscriber = tracing_subscriber::fmt().with_max_level(Level::INFO).finish();
tracing::subscriber::set_global_default(subscriber);
debug!("some log message");
Run Code Online (Sandbox Code Playgroud) 假设我有一个返回 a 的函数Vec<Box<dyn Subscriber>>,并且我想将它们组合成一个函数以设置为默认订阅者。这个怎么做?
我正在尝试做这样的事情,但我无法使类型匹配:
pub fn init_log(subscribers: Vec<Box<dyn Subscriber>>) -> Result<(), Error> {
use tracing_subscriber::prelude::*;
let mut layers: Vec<Box<dyn Layer<dyn Subscriber>>> = Vec::new();
for subscriber in subscribers.iter().drain(..) {
let layer: Box<dyn Layer<dyn Subscriber>> =
Box::new(tracing_subscriber::layer::Identity::new().with_subscriber(subscriber));
layers.push(layer);
}
let init_layer: Box<dyn Layer<dyn Subscriber>> =
Box::new(tracing_subscriber::layer::Identity::new());
let acc_subscriber: Layered<Box<dyn Layer<dyn Subscriber>>, _> =
tracing_subscriber::fmt().finish().with(init_layer);
let composed = layers
.drain(..)
.into_iter()
.fold(acc_subscriber, |acc, layer| acc.with(layer));
tracing::subscriber::set_global_default(composed);
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
error[E0277]: the trait bound `Box<dyn tracing::Subscriber>: tracing::Subscriber` is not satisfied
--> jormungandr\src\settings\logging.rs:97:85 …Run Code Online (Sandbox Code Playgroud) 我在项目中使用跟踪库,但有一件事我无法弄清楚:如何访问我的 中的值(我在创建它时在跨度中设置的值)Layer?
我的图层看起来像这样:
impl<S> Layer<S> for CustomLayer where S: Subscriber {
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
Interest::sometimes() //hardcoding so enabled() will be called everytime a span is created
}
fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool {
if metadata.is_span() {
// How do I access value of key here?
if value == X {
true
} else if value == Y {
false
}
}
true // default
}
}
Run Code Online (Sandbox Code Playgroud) 我有以下代码,适用于我的 rust 应用程序,将日志写入 stdout 和滚动 json 文件。
let appender = tracing_appender::rolling::hourly(app_log_path.clone(), "application.log");
let (non_blocking, _guard) = tracing_appender::non_blocking(appender);
let subscriber = tracing_subscriber::registry()
.with(fmt::Layer::new().with_writer(std::io::stdout).pretty())
.with(fmt::Layer::new().with_writer(non_blocking).json());
tracing::subscriber::set_global_default(subscriber).expect("Unable to set a global collector");
Run Code Online (Sandbox Code Playgroud)
这有效,但会记录所有日志记录级别,包括详细跟踪日志记录。我想将日志限制为仅信息级别,但不知道如何做到这一点。
从跟踪文档来看,它说要做:
fmt()
.with_max_level(Level::DEBUG)
.init();
Run Code Online (Sandbox Code Playgroud)
但是,我在上面的代码中找不到任何可以添加.with_max_level()函数调用的地方。我尝试放置的每个地方都给出了不同的特征违规。例如
the following trait bounds were not satisfied:
`tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() -> std::io::Stdout {std::io::stdout}>: MakeWriter<'_>`
which is required by `tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() -> std::io::Stdout {std::io::stdout}>: MakeWriterExt`
`&tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() -> std::io::Stdout {std::io::stdout}>: MakeWriter<'_>`
which is required by `&tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() …Run Code Online (Sandbox Code Playgroud)