rust 是否有办法以编程方式更改日志箱的默认日志记录级别?

kiayqfof  于 2023-02-16  发布在  其他
关注(0)|答案(5)|浏览(202)

我正在用Rust开发一个项目,它是由系统管理员通过CLI使用的。在这个程序中,我希望有这样的行:

warn!("File {} not found, proceeding to next file", file_path);

我不认为这是软件上下文中的错误,但我仍然希望我的用户知道。
然而,Rust的日志记录系统在默认情况下只打印ERROR日志级别的消息,我发现改变这个默认值的唯一方法是设置RUST_LOG环境变量--我不希望我的用户必须这样做。我想我可以创建一个 Package 器脚本,它只设置变量和exec,但我宁愿不这样做。
有没有一种方法可以从程序内部以编程方式更改默认级别?

ktca8awb

ktca8awb1#

这里有一个技巧可以让它

if env::var("RUST_LOG").is_err() {
    env::set_var("RUST_LOG", "info")
}
env_logger::init();
6yt4nkrj

6yt4nkrj2#

不,这是不可能的,浏览一下liblog库的代码就可以看到,所有日志级别的配置都存储在全局变量中,这些变量只使用Once原语修改一次,并且没有办法修改这个配置。
rust eclipse 记录非常简单;如果你想要更复杂的东西,你将不得不自己做。liblog提供了一个扩展点,一个名为Logger的特性,它可能可以用于您的目的。

bq3bfh9z

bq3bfh9z3#

下面是我认为您正在寻找的示例:

#[macro_use]
extern crate log;
use log::{LogRecord, LogLevel, LogMetadata, LogLevelFilter, SetLoggerError};

struct SimpleLogger;

impl log::Log for SimpleLogger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= LogLevel::Warn
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            // I can probably change colors here
            println!("{} - {}", record.level(), record.args());
        }
    }
}

pub fn init() -> Result<(), SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(LogLevelFilter::Warn);
        Box::new(SimpleLogger)
    })
}

fn main() {

    init(); // probably should do something better here

    info!("I am info");
    warn!("I am warn");
    error!("I am error");
}
gcmastyq

gcmastyq4#

多亏了Vladimir's answer,我深入研究了liblog源代码,并最终找到了一种hacky(而且可能很活泼)的方法:

fn main() {
    use std::os;
    os::setenv("RUST_LOG", "warn");
}

如果在任何日志记录之前完成此操作,则日志记录系统将被设置为好像是从外部设置的一样。

nhaq1z21

nhaq1z215#

如果你使用env_logger,你可以在main中做一些类似的事情:

env_logger::builder()
        .filter_level(log::LevelFilter::Debug)
        .format_target(false)
        .format_timestamp(None)
        .init();

相关问题