ane*_*son 5 trace rust rust-cargo rust-tokio
我正在为公司内部使用编写一个 Rust 板条箱,它包装了优秀的 Tokiotracing
板条箱,并带有一些附加功能。我不仅重新导出了 中的宏tracing
,而且还添加了一些我自己的在内部调用tracing
宏的宏。我的目标是让我们所有的其他内部 crate 仅依赖于我的包装 crate,而不必tracing
在每个 crate 中明确引入依赖项。
这非常有效,直到我今天遇到一个问题,我花了几个小时来隔离。我做了一个最小的例子来展示这里的行为。
在这个例子中,我有一个带有两个 crate 的工作区:my-logger-crate
它包装tracing
和公开一个 macro print_trace!
,一个二进制 cratemy-binary-crate
依赖于my-logger-crate
,并在main
函数内调用宏。
该Cargo.toml
用于my-logger-crate
非常简单; 我添加到自动生成的骨架中的唯一内容是tracing
依赖项:
[package]
name = "my-logger-crate"
version = "0.1.0"
authors = ["Adam Nelson <anelson@users.noreply.github.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tracing = "0.1.12"
Run Code Online (Sandbox Code Playgroud)
这是my-logger-crate
宏:
[package]
name = "my-logger-crate"
version = "0.1.0"
authors = ["Adam Nelson <anelson@users.noreply.github.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tracing = "0.1.12"
Run Code Online (Sandbox Code Playgroud)
这由 使用my-binary-crate
,它Cargo.toml
也很简单:
[package]
name = "my-binary-crate"
version = "0.1.0"
authors = ["Adam Nelson <anelson@users.noreply.github.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
my-logger-crate = { path = "../my-logger-crate" }
# If the following line is uncommented, then the call to `print_trace!` in `main()` fails to compile.
# tower = "0.3"
Run Code Online (Sandbox Code Playgroud)
这是 中的main()
函数my-binary-crate
:
/// Re-export everything in the `tracing` crate
pub use ::tracing::*;
/// A version of the `trace!` macro that sets a special target
#[macro_export]
macro_rules! print_trace {
($($arg:tt)*) => (
// Invoke the `trace!` macro which is defined in the `tracing` crate but which has been
// re-exported from this crate, so that downstream callers don't have to take an explicit
// dependency on `tracing`
$crate::trace!(target: "console", $($arg)*)
)
}
Run Code Online (Sandbox Code Playgroud)
如果my-binary-crate
没有任何冲突的依赖项,这将编译并运行良好。
但是看看如果我们tower
在my-binary-crate/Cargo.toml
文件中有依赖会发生什么:
[package]
name = "my-binary-crate"
version = "0.1.0"
authors = ["Adam Nelson <anelson@users.noreply.github.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
my-logger-crate = { path = "../my-logger-crate" }
# If the following line is uncommented, then the call to `print_trace!` in `main()` fails to compile.
tower = "0.3"
Run Code Online (Sandbox Code Playgroud)
这是发生的事情:
[package]
name = "my-binary-crate"
version = "0.1.0"
authors = ["Adam Nelson <anelson@users.noreply.github.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
my-logger-crate = { path = "../my-logger-crate" }
# If the following line is uncommented, then the call to `print_trace!` in `main()` fails to compile.
# tower = "0.3"
Run Code Online (Sandbox Code Playgroud)
该print_trace!
宏扩展出来的tracing::trace!
宏,然后扩展到tracing::event!
,然后扩展到代码来记录事件,其中包括对呼叫tracing::...
。在我添加该tower
依赖项之前,所有这些都可以正常工作,因此显然编译器能够tracing::...
正确解析,即使my-binary-crate
对tracing
自身没有直接依赖关系。
我怀疑这与依赖冲突有关。 tower
拉入一个很长的依赖树,包括tower-buffer
,它本身依赖于tracing = "0.1.2"
。
我对 Cargo 如何解决这个看似冲突的理解是它会使用tracing
version 0.1.12
,因为我的日志记录箱明确依赖于 version =0.1.12
,并tower-buffer
指定了0.1.2
,它等效于^0.1.2
. 但我不明白为什么添加这个额外的依赖树会破坏我的宏的使用。
目前,我已经通过tracing
在所有使用我的日志记录箱的下游箱中添加显式依赖来解决它,但这远非理想。
我在启用宏跟踪的情况下运行:
fn main() {
println!("Hello, world!");
// Log a trace event with the logging system
my_logger_crate::print_trace!("this is a trace message from print_trace!");
}
Run Code Online (Sandbox Code Playgroud)
不足为奇的是,该错误是试图调用tracing::__mk_format_string!
,这失败,因为没有这样的箱子tracing
被引用my-binary-crate
。奇怪的是,为了解决这个错误,tracing
必须评估其他几个宏。也许这是一个错误tracing
,它应该是$crate::__mk_format_string!
。但是,在我添加tower
对my-binary-crate
.
归档时间: |
|
查看次数: |
624 次 |
最近记录: |