1

I use the standard log module of rust. I'm trying to have a very simple logger that records all that is sent to it via debug!, trace!, etc. Then from time to time, I want to read these records and do something else with them. I had something like this in mind (I have removed useless code):

struct SimpleLogger {
    records : Vec<String>
}

impl SimpleLogger {
    fn dump(&mut self) {
        for x in self.records.into_iter() {
            println!("{}", x);
        }
        self.records.clear();
    }
}

impl log::Log for SimpleLogger {
    fn log(&self, record: &Record) {
        if self.enabled(record.metadata()) {
            self.records.push(format!("{} - {}", record.level(), record.args()));
        }
    }
}

This is challenging for these reasons:

  • Once the logger has been set as the global logger (using log::set_logger), I loose the ownership. So I can't call dump anymore (because I don't have a reference to it anymore, it has been captured by set_logger).
  • In the Log trait, the log method accepts a non mutable reference to self. Therefore, I can't update the vector of records there.

I've checked other loggers and they seem to use Write objects, but still it seems everything is thought to deliver the records and then throw them away. Moreover, it seems the loggers need to be thread safe so I'd have to use mutex...

How can I do ?

Herohtar
  • 5,347
  • 4
  • 31
  • 41
wiz21
  • 141
  • 7
  • 2
    Concerning the second reason you mention, [this question](https://stackoverflow.com/q/63487359/11527076) (and its answer) is about interior mutability and uses as example the `Messenger` service of the Rust Book with a similar concern. – prog-fh Mar 20 '22 at 09:51
  • 2
    Make `records` to be `Arc>` and keep a reference to it to do the dump. – Cecilio Pardo Mar 20 '22 at 20:11
  • 1
    As for your first question, `set_logger()` takes a reference (doesn't move), so why can't you use it anymore? – Chayim Friedman Mar 20 '22 at 20:43

1 Answers1

0

The best and most simplified crate I found was this and it works very nicely here is the code

Don't forget to add this to cargo.toml first

log2 = "0.1.7"

use log2::*;

fn main() {
    let _log2 = log2::start();

    trace!("send order request to server");
    debug!("receive order response");
    info!("order was executed");
    warn!("network speed is slow");
    error!("network connection was broken");
}

source : https://crates.io/crates/log2

grepit
  • 21,260
  • 6
  • 105
  • 81