From c7e3b12856558a04e44455d81373cc7d7bc08180 Mon Sep 17 00:00:00 2001 From: Lumither Tao Date: Tue, 19 Nov 2024 00:33:09 -0800 Subject: [PATCH] feat(macros) add `panic_with_log` --- backend/api_server/Cargo.toml | 1 + backend/api_server/src/init.rs | 37 ++------------------------ backend/api_server/src/main.rs | 7 ++--- backend/api_server/src/server.rs | 31 +++++++++++++--------- backend/macros/Cargo.toml | 2 ++ backend/macros/src/lib.rs | 15 +---------- backend/macros/src/log.rs | 45 ++++++++++++++++++++++++++++++++ 7 files changed, 74 insertions(+), 64 deletions(-) create mode 100644 backend/macros/src/log.rs diff --git a/backend/api_server/Cargo.toml b/backend/api_server/Cargo.toml index 09883f5..e140b1e 100644 --- a/backend/api_server/Cargo.toml +++ b/backend/api_server/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] +macros = { path = "../macros" } constants = { path = "../constants" } chrono = { version = "0.4.38", features = ["serde", "alloc"] } tracing = "0.1.40" diff --git a/backend/api_server/src/init.rs b/backend/api_server/src/init.rs index 73e53fd..c240d89 100644 --- a/backend/api_server/src/init.rs +++ b/backend/api_server/src/init.rs @@ -1,17 +1,10 @@ use crate::logger; -use std::{ - backtrace::{Backtrace, BacktraceStatus}, - env, panic, - panic::PanicHookInfo, -}; -use tracing::{error, event, span, Level}; +use std::{env, panic}; use tracing_appender::non_blocking::WorkerGuard; pub fn logger_init() -> (WorkerGuard, WorkerGuard) { - let ret = logger::init(); - panic::set_hook(Box::new(panic_hook)); - ret + logger::init() } pub fn load_env() { @@ -28,29 +21,3 @@ pub fn load_env() { println!("[info] no .env file referred, starting up") } } - -fn panic_hook(panic_info: &PanicHookInfo) { - let payload = panic_info.payload(); - // panic_info. - - let payload = if let Some(s) = payload.downcast_ref::<&str>() { - Some(&**s) - } else { - payload.downcast_ref::().map(|s| s.as_str()) - }; - - // let location = panic_info.location().map(|l| l.to_string()); - // let backtrace = Backtrace::capture(); - // let note = (backtrace.status() == BacktraceStatus::Disabled) - // .then_some("run with RUST_BACKTRACE=1 environment variable to display a backtrace"); - // (Some(backtrace), note) - // }; - // - // panic_info. - - if let Some(location) = panic_info.location() { - eprintln!("err filename: {}", location.file()) - } - - event!(target: "test", Level::ERROR, "panic hook: {:?}", panic_info); -} diff --git a/backend/api_server/src/main.rs b/backend/api_server/src/main.rs index 411e673..c1431c4 100644 --- a/backend/api_server/src/main.rs +++ b/backend/api_server/src/main.rs @@ -1,3 +1,6 @@ +use macros::panic_with_log; +use tracing::Level; + mod blog; mod init; mod logger; @@ -9,12 +12,10 @@ async fn main() { init::load_env(); let _guards = init::logger_init(); - // panic!("test"); - match server::start().await { Ok(_) => {} Err(e) => { - panic!("server start failed: {}", e); + panic_with_log!(Level::ERROR, "failed to start server: {}", e); } }; } diff --git a/backend/api_server/src/server.rs b/backend/api_server/src/server.rs index 6dfb8e8..047eae1 100644 --- a/backend/api_server/src/server.rs +++ b/backend/api_server/src/server.rs @@ -5,14 +5,13 @@ use std::process::exit; use std::str::FromStr; use crate::blog; -use crate::scheduler::tasks::basic::BasicTask; -use crate::scheduler::Scheduler; use axum::Router; +use macros::panic_with_log; use sqlx::{ postgres::{PgConnectOptions, PgPoolOptions}, ConnectOptions, }; -use tracing::{error, info, warn}; +use tracing::{error, info, warn, Level}; pub async fn start() -> Result<(), Box> { let port: u32 = match env::var("BACKEND_PORT") { @@ -39,8 +38,8 @@ pub async fn start() -> Result<(), Box> { }; // cron task - let scheduler = Scheduler::new(); - let test_str = "hello world".to_string(); + // let scheduler = Scheduler::new(); + // let test_str = "hello world".to_string(); // scheduler.insert( // BasicTask::new( // move || blog::cron::check_update::task(test_str.clone()), @@ -51,15 +50,23 @@ pub async fn start() -> Result<(), Box> { // http server let app = Router::new() - .nest("blog", blog::get_router()) + .nest("/blog", blog::get_router()) .with_state(db_pool); - let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port)) - .await - .unwrap_or_else(|e| { - error!("failed to build TCP listener: {}", e.to_string()); - exit(1); - }); + let listener = match tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port)).await { + Ok(listener) => { + info!("server started on 0.0.0.0:{}", port); + listener + } + Err(e) => { + panic_with_log!( + Level::ERROR, + "failed to start server on 0.0.0.0:{}: {}", + port, + e.to_string() + ); + } + }; axum::serve(listener, app).await.unwrap_or_else(|e| { error!("failed to start axum: {}", e.to_string()); diff --git a/backend/macros/Cargo.toml b/backend/macros/Cargo.toml index a11722a..6291521 100644 --- a/backend/macros/Cargo.toml +++ b/backend/macros/Cargo.toml @@ -4,3 +4,5 @@ version = "0.1.0" edition = "2021" [dependencies] +tracing = "0.1.40" +tracing-subscriber = "0.3.18" diff --git a/backend/macros/src/lib.rs b/backend/macros/src/lib.rs index b93cf3f..aad31d7 100644 --- a/backend/macros/src/lib.rs +++ b/backend/macros/src/lib.rs @@ -1,14 +1 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +mod log; diff --git a/backend/macros/src/log.rs b/backend/macros/src/log.rs new file mode 100644 index 0000000..f7dd357 --- /dev/null +++ b/backend/macros/src/log.rs @@ -0,0 +1,45 @@ +/// log the message at specific log level and exit(1) +/// +/// # Example +/// ```rust +/// +/// use macros::panic_with_log; +/// use tracing::Level; +/// +/// panic_with_log!(Level::ERROR, "Test panicked: {}", 42); +/// ``` +#[macro_export] +macro_rules! panic_with_log { + ($level:expr, $msg:literal $(, $($arg:tt)*)?) => {{ + use std::process; + use tracing::event; + event!($level, $msg $(, $($arg)*)?); + process::exit(1); + }}; +} + +#[cfg(test)] +mod tests { + #[test] + fn test_panic_with_log() { + use std::io; + use tracing::Level; + use tracing_subscriber::prelude::*; + use tracing_subscriber::{fmt, Registry}; + + let format = tracing_subscriber::fmt::format() + .with_level(true) + .with_target(true) + .with_source_location(true); + + let subscriber = Registry::default().with( + fmt::Layer::default() + .with_writer(io::stderr) + .event_format(format), + ); + + tracing::subscriber::set_global_default(subscriber).unwrap(); + + panic_with_log!(Level::ERROR, "Test panicked: {}", 42); + } +}