【问题标题】:How to implement a logger that appends to a file?如何实现附加到文件的记录器?
【发布时间】:2015-05-13 00:21:54
【问题描述】:

我正在尝试实现log::Log,以便对log() 的调用将消息附加到文件中。这是我目前的记录器:

pub struct MyLogger {
    loglevel: LogLevelFilter,
    logfile: Option<File>,
}

以及log::Log的实现:

impl Log for Logger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.loglevel
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            let msg = format!("{}\t| {}\t| {}", record.level(), record.target(), record.args());
            self.logfile.write_all(msg.as_bytes()).unwrap();
        }
    }
}

这是可以理解的,因为log() 没有采用可变引用,所以失败了。我不能采用可变引用,因为那样我就无法正确实现该类型,那么实现这一点的惯用方法是什么?

【问题讨论】:

    标签: logging rust


    【解决方案1】:

    当您需要呈现非可变界面但在幕后进行突变时,您可以使用内部可变性。这样做的常见方法是使用来自std::cell 的东西。文档提到了这个特定的用例:

    因为您必须使用变异来实现最初定义为采用 &self 的 trait 方法。

    具体来说,在这种情况下,我会尝试使用RefCell

    不幸的是,Log 要求实现者也是Sync + Send,但单元格不是。这意味着我们需要升级到可以处理多个线程的东西。那东西是Mutex:

    extern crate log;
    
    use std::fs::File;
    use std::io::Write;
    use std::sync::Mutex;
    use log::{LogLevelFilter,LogMetadata,LogRecord,Log};
    
    pub struct FileLogger {
        loglevel: LogLevelFilter,
        logfile: Option<Mutex<File>>,
    }
    
    impl Log for FileLogger {
        fn enabled(&self, metadata: &LogMetadata) -> bool {
            metadata.level() <= self.loglevel
        }
    
        fn log(&self, record: &LogRecord) {
            if self.enabled(record.metadata()) {
                let msg = format!("{}\t| {}\t| {}", record.level(), record.target(), record.args());
                self.logfile.as_ref().map(|f| {
                    f.lock().unwrap().write_all(msg.as_bytes()).unwrap()
                });
            }
        }
    }
    
    #[test]
    fn it_works() {
    }
    

    【讨论】:

    • 注意:在调用log的线程中具有同步I/O通常是不希望的,因此通常使用内部队列或缓冲区并有一个专门的“消费者”线程负责写入文件。在 Rust 世界中,也许是一个频道?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2022-07-12
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    相关资源
    最近更新 更多