From c277fd4c8e668ceb11306320ac80cb4f81754ca2 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Wed, 4 Oct 2023 09:04:16 -0700 Subject: [PATCH] feat(backend): better logging system --- .vscode/settings.json | 9 ++++- backend/Cargo.lock | 61 ++++++++++++++++++++++++++++---- backend/Cargo.toml | 2 ++ backend/src/logger.rs | 57 +++++++++++++++++++++++++++++ backend/src/main.rs | 36 +++++++++++++------ backend/src/plugins/minecraft.rs | 4 +-- backend/src/plugins/mod.rs | 4 ++- backend/src/web/middleware.rs | 4 +-- package.json | 4 +-- 9 files changed, 157 insertions(+), 24 deletions(-) create mode 100644 backend/src/logger.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 7401dbd..e5155fd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,12 @@ "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, - "eslint.validate": ["javascript"] + "eslint.validate": [ + "javascript" + ], + "rust-analyzer.linkedProjects": [ + "./backend/Cargo.toml", + "./backend/Cargo.toml", + "./backend/Cargo.toml" + ] } diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 68ad07d..cc192f9 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -283,7 +283,7 @@ dependencies = [ "log", "parking", "polling", - "rustix", + "rustix 0.37.23", "slab", "socket2 0.4.9", "waker-fn", @@ -322,7 +322,7 @@ dependencies = [ "cfg-if 1.0.0", "event-listener", "futures-lite", - "rustix", + "rustix 0.37.23", "signal-hook", "windows-sys", ] @@ -477,6 +477,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "blake3" version = "0.3.8" @@ -628,6 +634,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "colored" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +dependencies = [ + "is-terminal", + "lazy_static", + "windows-sys", +] + [[package]] name = "concurrent-queue" version = "2.2.0" @@ -1273,6 +1290,17 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix 0.38.15", + "windows-sys", +] + [[package]] name = "itoa" version = "1.0.9" @@ -1321,6 +1349,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" + [[package]] name = "lock_api" version = "0.4.10" @@ -1613,7 +1647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ "autocfg", - "bitflags", + "bitflags 1.3.2", "cfg-if 1.0.0", "concurrent-queue", "libc", @@ -1659,7 +1693,9 @@ name = "procchi" version = "0.1.0" dependencies = [ "async-std", + "chrono", "clap", + "colored", "include_dir", "mcping", "mime_guess", @@ -1798,7 +1834,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1883,11 +1919,24 @@ version = "0.37.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", + "windows-sys", +] + +[[package]] +name = "rustix" +version = "0.38.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f9da0cbd88f9f09e7814e388301c8414c51c62aa6ce1e4b5c551d49d96e531" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys 0.4.8", "windows-sys", ] diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 7dbf38c..a4b93fd 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -7,7 +7,9 @@ edition = "2021" [dependencies] async-std = "1.12.0" +chrono = "0.4.31" clap = { version = "4.3.21", features = ["derive"] } +colored = "2.0.4" include_dir = "0.7.3" mcping = { version = "0.2.0", optional = true } mime_guess = "2.0.4" diff --git a/backend/src/logger.rs b/backend/src/logger.rs new file mode 100644 index 0000000..660d1c3 --- /dev/null +++ b/backend/src/logger.rs @@ -0,0 +1,57 @@ +use colored::Colorize; +use std::fs::{File, OpenOptions}; +use std::io::Write; +use std::sync::Mutex; + +// Open a LOG_FILE in the default log directory +static mut LOG_FILE: Option> = None; + +pub fn init(path: String) { + unsafe { + LOG_FILE = Some(Mutex::new( + OpenOptions::new() + .create(true) + .append(true) + .open(path) + .expect("Permission denied when opening log file"), + )); + } +} + +pub fn append_logfile(message: String) { + if unsafe { LOG_FILE.as_ref().is_none() } { + return; + } + + let pretty_date = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); + let mut file = unsafe { LOG_FILE.as_ref().unwrap().lock().unwrap() }; + file + .write_all(format!("{} | {}\n", pretty_date, message).as_bytes()) + .unwrap(); +} + +pub fn print_pretty(kind: String, message: String) { + let pretty_date = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); + println!("[{}] {} {}", pretty_date, kind.bold(), message); +} + +pub fn _print_error(message: String) { + print_pretty("[ERROR]".red().to_string(), message.clone()); + + // Write to log file + append_logfile(format!("[ERROR] {}", message)); +} + +pub fn _print_warning(message: String) { + print_pretty("[WARNING]".yellow().to_string(), message.clone()); + + // Write to log file + append_logfile(format!("[WARNING] {}", message)); +} + +pub fn print_info(message: String) { + print_pretty("[INFO]".blue().to_string(), message.clone()); + + // Write to log file + append_logfile(format!("[INFO] {}", message)); +} diff --git a/backend/src/main.rs b/backend/src/main.rs index 0a9a32d..881baf7 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -12,6 +12,7 @@ use tide_acme::rustls_acme::caches::DirCache; #[cfg(feature = "plugins")] use crate::plugins::parse_enable_plugins; +mod logger; mod resource_watcher; mod util; mod web; @@ -89,6 +90,10 @@ pub struct Args { /// Enable HTTPS. Not really needed for testing locally, but recommended for outside access #[arg(short = 's', long)] https: bool, + + /// Log file path + #[arg(short = 'l', long, default_value = "")] + log_file: String, } fn main() { @@ -97,6 +102,11 @@ fn main() { let mut username = String::new(); let pwd; + // Init logger + if !args.log_file.is_empty() { + logger::init(args.log_file.clone()); + } + if args.username.is_none() || args.password.is_none() { // Prompt for username print!("Username to use while authenticating: "); @@ -157,15 +167,21 @@ fn main() { #[cfg(feature = "plugins")] parse_enable_plugins(&mut app, args.plugins.clone(), args.address.clone()); - println!("Starting server on port {}...", args.port); - println!("Retaining {} elements of metric history", args.history_max); - println!("Updating every {} seconds", args.update_rate); - println!( - "Done! Access the web interface at http{}://{}:{}/", - // Lol this is so dumb - if args.https { "s" } else { "" }, - args.address, - args.port + if args.https { + logger::print_info(format!("Putting ACME cache in {}/.acme_cache", tmp_dir.display().to_string())); + } + + logger::print_info(format!("Starting server on port {}...", args.port)); + logger::print_info(format!("Retaining {} elements of metric history", args.history_max)); + logger::print_info(format!("Updating every {} seconds", args.update_rate)); + logger::print_info( + format!( + "Done! Access the web interface at http{}://{}:{}/", + // Lol this is so dumb + if args.https { "s" } else { "" }, + args.address, + args.port + ) ); task::block_on(async { @@ -198,7 +214,7 @@ fn recursive_serve(app: &mut tide::Server, path: Option<&Path>) { for file in dir.files() { let path = format!("{}", file.path().display()); - println!("Serving {}", path); + logger::print_info(format!("Serving {}", path)); app .at(&path) diff --git a/backend/src/plugins/minecraft.rs b/backend/src/plugins/minecraft.rs index 312cd0d..bc2072e 100644 --- a/backend/src/plugins/minecraft.rs +++ b/backend/src/plugins/minecraft.rs @@ -1,7 +1,7 @@ use mcping; use serde::Serialize; -use crate::State; +use crate::{State, logger}; #[derive(Serialize, Clone)] struct McData { @@ -15,7 +15,7 @@ struct McData { static mut ACCESS_ADDRESS: String = String::new(); pub fn register(app: &mut tide::Server, access_address: String) -> Vec { - println!("Enabling Minecraft plugin"); + logger::print_info("Enabling Minecraft plugin"); unsafe { ACCESS_ADDRESS = access_address; diff --git a/backend/src/plugins/mod.rs b/backend/src/plugins/mod.rs index 851be06..ad174ca 100644 --- a/backend/src/plugins/mod.rs +++ b/backend/src/plugins/mod.rs @@ -1,6 +1,8 @@ use crate::State; use serde::Serialize; +use crate::logger; + mod minecraft; #[derive(Serialize, Clone)] @@ -38,7 +40,7 @@ pub fn parse_enable_plugins( }; for endpoint in endpoints { - println!("Registered endpoint: {}", endpoint); + logger::print_info(format!("Registered endpoint: {}", endpoint)); registered_endpoints.push(Plugin { name: plugin.to_string(), endpoints: vec![endpoint], diff --git a/backend/src/web/middleware.rs b/backend/src/web/middleware.rs index 5319f79..9c1cac9 100644 --- a/backend/src/web/middleware.rs +++ b/backend/src/web/middleware.rs @@ -1,6 +1,6 @@ use tide::utils::async_trait; -use crate::User; +use crate::{User, logger}; pub struct AuthMiddleware {} @@ -14,7 +14,7 @@ where let mut res: tide::Response = tide::Response::new(401); res.insert_header("WWW-Authenticate", "Basic"); - println!("Attempted access by {}", req.remote().unwrap_or("unknown")); + logger::print_info(format!("Attempted access by {}", req.remote().unwrap_or("unknown"))); return Ok(res); } diff --git a/package.json b/package.json index 79758ac..888275e 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "name": "procchi", "version": "0.1.0", "scripts": { - "start:bun": "cd ./frontend && bun run build && cd ../backend && cargo run -- -u test -k test -s", - "start": "cd ./frontend && npm run build && cd ../backend && cargo run -- -u test -k test -s", + "start:bun": "cd ./frontend && bun run build && cd ../backend && cargo run -- -u test -k test", + "start": "cd ./frontend && npm run build && cd ../backend && cargo run -- -u test -k test", "build:bun": "cd ./frontend && bun run build && cd ../backend && cargo build --release", "build": "cd ./frontend && npm run build && cd ../backend && cargo build --release", "clippy:fix": "cargo clippy --manifest-path ./backend/Cargo.toml --all --fix",