2025-07-08 22:50:42 +08:00
|
|
|
use std::fs::{self, OpenOptions};
|
|
|
|
use std::io::Write;
|
|
|
|
use std::path::Path;
|
|
|
|
|
2025-07-08 23:04:07 +08:00
|
|
|
use chrono::Local;
|
2025-07-08 22:50:42 +08:00
|
|
|
use colored::Colorize;
|
|
|
|
use log::{Level, LevelFilter, Log, Metadata, Record, SetLoggerError};
|
|
|
|
|
|
|
|
pub(crate) struct ServerLogger;
|
|
|
|
static LOGGER: ServerLogger = ServerLogger;
|
|
|
|
|
|
|
|
impl ServerLogger {
|
|
|
|
pub(crate) fn init() -> Result<(), SetLoggerError> {
|
|
|
|
log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Info))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn log_to_console(record: &Record) {
|
|
|
|
let formatted_message = format!(
|
|
|
|
"[{}] [{}] [{}:{}]\n{}",
|
2025-07-08 23:04:07 +08:00
|
|
|
Local::now().to_rfc3339(),
|
2025-07-08 22:50:42 +08:00
|
|
|
match record.level() {
|
|
|
|
Level::Error => "ERROR".red(),
|
|
|
|
Level::Warn => "WARN".yellow(),
|
|
|
|
Level::Info => "INFO".green(),
|
|
|
|
Level::Debug => "DEBUG".blue(),
|
|
|
|
Level::Trace => "TRACE".blue(),
|
|
|
|
},
|
|
|
|
record.file().expect("Failed to get file name!"),
|
|
|
|
record.line().expect("Failed to get line number!"),
|
|
|
|
record.args()
|
|
|
|
);
|
|
|
|
|
|
|
|
println!("{formatted_message}")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn log_to_file(record: &Record) {
|
|
|
|
let formatted_message = format!(
|
|
|
|
"[{}] [{}] [{}:{}]\n{}",
|
2025-07-08 23:04:07 +08:00
|
|
|
Local::now().to_rfc3339(),
|
2025-07-08 22:50:42 +08:00
|
|
|
record.level(),
|
|
|
|
record.file().expect("Failed to get file name!"),
|
|
|
|
record.line().expect("Failed to get line number!"),
|
|
|
|
record.args()
|
|
|
|
);
|
|
|
|
|
|
|
|
let logging_dir = Path::new("./logs");
|
|
|
|
|
|
|
|
if !logging_dir.exists() {
|
|
|
|
fs::create_dir_all(logging_dir).expect("Failed to create directory!");
|
|
|
|
}
|
|
|
|
let mut logging_file = OpenOptions::new()
|
|
|
|
.append(true)
|
|
|
|
.create(true)
|
|
|
|
.open(logging_dir.join("server_log.txt"))
|
|
|
|
.expect("Failed to create logging file!");
|
|
|
|
|
|
|
|
writeln!(logging_file, "{formatted_message}").expect("Failed to write into logging file!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Log for ServerLogger {
|
|
|
|
fn enabled(&self, metadata: &Metadata) -> bool {
|
|
|
|
metadata.level() <= Level::Info
|
|
|
|
}
|
|
|
|
|
|
|
|
fn log(&self, record: &Record) {
|
|
|
|
if self.enabled(record.metadata()) {
|
|
|
|
ServerLogger::log_to_console(record);
|
|
|
|
ServerLogger::log_to_file(record);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn flush(&self) {}
|
|
|
|
}
|