是否可以在编译时更改应用程序的日志级别?

Is it possible to change the log level for an application at compile time?

我不想在运行时依赖环境变量,而是想编译一个调试或发布版本,完全删除非错误日志消息。

是否可以在 Cargo.toml 中或通过 cargo/rustc 命令行参数更改应用程序的日志级别?

我不相信 log crate 完全 内置了请求的功能。

a way to statically set the logging level。如果您使用这些 Cargo 功能中的任何一个来编译 log crate,那么日志级别将在此时达到上限:

  • release_max_level_off
  • release_max_level_error
  • release_max_level_warn
  • release_max_level_info
  • release_max_level_debug
  • release_max_level_trace

您可以在 non-release 版本中放弃 release_ 以获得相同的功能。

优化器可能会看到这个静态值并删除不可能的代码。如果发生这种情况,那么您应该可以开始了!

如果您想绝对确定,您可以通过使用 Cargo 功能创建您自己的条件编译来近似它。这是一个简单的示例,它会根据是否启用该功能来打印或不打印值:

#[cfg(not(feature = "slim"))]
macro_rules! my_info {
    ($x: expr) => { println!("{:?}", $x) }
}

#[cfg(feature = "slim")]
macro_rules! my_info {
    ($x: expr) => { }
}

fn main() {
    my_info!("Hello, world!");
}

这在Cargo.toml中有相应的节:

[features]
slim = []

当你编译/运行你的程序时,你可以选择有哪些特性:

$ cargo run
     Running `target/debug/log`
"Hello, world!"
$ cargo run --features=slim
     Running `target/debug/log`
$ 

然后只需将记录器宏包装在您自己的 conditionally-compiled 宏中即可:

#[cfg(not(feature = "slim"))]
macro_rules! my_info {
    ($($arg: tt)*) => { info!($($arg)*) }
}

#[cfg(feature = "slim")]
macro_rules! my_info {
    ($($arg: tt)*) => { }
}

运行 产量:

$ RUST_LOG=info cargo run
     Running `target/debug/log`
INFO:log: Hello, world!
$ RUST_LOG=info cargo run --features=slim
     Running `target/debug/log`
$

对于一些社论,我不同意这样做。当出现问题时,就是您 想要记录某些内容的能力的时候。在大多数情况下,我认为布尔值检查的成本不会高到足以保证这样做。我也怀疑在大多数情况下你会有兆字节的文本。

总是有例外 - 也许您需要在一个紧密的循环中记录一些东西,或者您必须编译以适应具有有限 space.

的微控制器

请注意,我没有尝试将删除日志消息与 "release" 构建的概念结合起来。我保证有时您会想要包含这些消息的发布版本,因此最好让这两个想法相互正交。