1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use std::path::PathBuf;

use bevy::prelude::*;
use de_core::fs::logs_dir;
use tracing::Level;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::{fmt, EnvFilter};

pub(crate) struct LogPlugin;

/// the handle for the guard (dropping it will disable the log writer)
#[derive(Resource)]
pub(crate) struct CurrentLogHandle {
    #[allow(dead_code)]
    guard: WorkerGuard,
}

impl Plugin for LogPlugin {
    fn build(&self, app: &mut App) {
        let dir: PathBuf = logs_dir()
            .map(|d| d.into())
            .unwrap_or(PathBuf::from("logs"));

        // for file name
        let dt = chrono::Local::now();
        let path: PathBuf = dt.format("%Y-%m-%d_%H-%M-%S.jsonl").to_string().into();

        let file_appender = tracing_appender::rolling::never(dir.as_path(), path.as_path());

        let (non_blocking_log_writer, _guard) = tracing_appender::non_blocking(file_appender);

        let collector = tracing_subscriber::registry()
            .with(
                EnvFilter::builder()
                    // defaults to INFO if RUST_LOG not set
                    .with_default_directive(Level::INFO.into())
                    .from_env_lossy(),
            )
            .with(fmt::layer().with_writer(std::io::stdout))
            .with(fmt::layer().json().with_writer(non_blocking_log_writer));
        tracing::subscriber::set_global_default(collector)
            .expect("Unable to set a global collector");

        app.insert_resource(CurrentLogHandle { guard: _guard });

        info!("Logging to file {path:?} in directory: {dir:?}");
    }
}