1

When I try to use tracing-appender, I notice that the time in the console does not match the time in the file. How can I get them to be the same time?

use std::io;
use std::path::Path;
use tracing::{debug, error, info, trace, warn, Level};
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::{
    fmt::{self, writer::MakeWriterExt},
    prelude::*,
};

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
    let _guard = init_tracing_subscriber(Some("./log"))?;
    trace!("Hello, world!");
    debug!("Hello, world!");
    info!("Hello, world!");
    warn!("Hello, world!");
    error!("Hello, world!");
    Ok(())
}

fn init_tracing_subscriber<P: AsRef<Path>>(
    log_dir: Option<P>,
) -> Result<Option<WorkerGuard>, anyhow::Error> {
    let mut guard = None;
    let file_log = log_dir
        .map(|p| tracing_appender::non_blocking(tracing_appender::rolling::daily(p, "server")))
        .map(|(none_blocking, g)| {
            guard = Some(g);
            fmt::Layer::new()
                .with_writer(none_blocking.with_max_level(Level::WARN))
                .with_ansi(false)
        });

    let console_log = fmt::Layer::new()
        .with_ansi(true)
        .with_writer(io::stderr.with_min_level(Level::WARN).or_else(io::stdout));

    let subscriber = tracing_subscriber::registry()
        .with(file_log)
        .with(console_log);

    subscriber.try_init()?;
    Ok(guard)
}

Also, regarding the time formatting question, do I have to format the time separately?

Console output results

2023-04-18T08:42:32.961016Z DEBUG demo: Hello, world!
2023-04-18T08:42:32.961379Z  INFO demo: Hello, world!
2023-04-18T08:42:32.961808Z  WARN demo: Hello, world!
2023-04-18T08:42:32.962337Z ERROR demo: Hello, world!

Log file

2023-04-18T08:42:32.961766Z  WARN demo: Hello, world!
2023-04-18T08:42:32.962216Z ERROR demo: Hello, world!

It bothers me a bit to notice that they are not at the same time. I didn't find the information on the internet, so I came here for help.

3moredays
  • 25
  • 3
  • 1
    I started to look how to implement that, but stopped. So some hints: the default timer in `fmt` retrieves the current time when writing it, so it is separate for each layer. You can [replace it](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/struct.Layer.html#method.with_timer) with a timer that uses a stored time, possibly from some previous layer. – Chayim Friedman Apr 18 '23 at 12:13
  • @ChayimFriedman Yes, I noticed that too, I used `Rc` to wrap a `Timer` and used `with_timer` to try to use it, but unfortunately the compiler told me that I can't use `Rc` as a `timer` and also prompted me to implement the `FormatTime` trait. but my rust programming skills are limited and I don't know how to implement it. – 3moredays Apr 18 '23 at 14:31

0 Answers0