Skip to content

Commit

Permalink
Fix log interleaving when logging from multiple threads.
Browse files Browse the repository at this point in the history
  • Loading branch information
Esper89 committed Sep 30, 2024
1 parent effbe57 commit 3618c2f
Showing 1 changed file with 30 additions and 15 deletions.
45 changes: 30 additions & 15 deletions astro_modloader/src/logging.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
use std::fs;
use std::io::prelude::*;
use std::sync::OnceLock;
use std::sync::{Mutex, OnceLock};

use colored::*;
use log::{Level, LevelFilter, Log, Metadata, Record, SetLoggerError};

#[derive(Debug)]
struct SimpleLogger {
file: fs::File,
file: Mutex<fs::File>,
}

impl SimpleLogger {
fn lock<T>(&self, f: impl FnOnce(&mut fs::File) -> T) -> T {
let mut guard = match self.file.lock() {
Ok(guard) => guard,
Err(err) => err.into_inner(),
};

f(&mut guard)
}
}

impl Log for SimpleLogger {
Expand Down Expand Up @@ -53,31 +64,35 @@ impl Log for SimpleLogger {
Level::Trace => "TRACE",
};

writeln!(
&self.file,
"[{level:<5} {file_path}:{}] {}",
record.line().unwrap_or(0),
record.args()
)
self.lock(|file| {
writeln!(
file,
"[{level:<5} {file_path}:{}] {}",
record.line().unwrap_or(0),
record.args()
)
})
.unwrap();
}
}

fn flush(&self) {
(&self.file).flush().unwrap()
self.lock(|file| file.flush()).unwrap()
}
}

fn get_logger() -> &'static SimpleLogger {
static LOGGER: OnceLock<SimpleLogger> = OnceLock::new();
LOGGER.get_or_init(|| SimpleLogger {
// open file
file: fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open("modloader_log.txt")
.unwrap(),
file: Mutex::new(
fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open("modloader_log.txt")
.unwrap(),
),
})
}

Expand Down

0 comments on commit 3618c2f

Please sign in to comment.