diff --git a/backend/src/main.rs b/backend/src/main.rs index 0503ad7..b2dbbad 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -3,31 +3,12 @@ use mailpass::run_server; use anyhow::{Context, Result}; use configured::Configured; use serde::Deserialize; -use serde_json::json; -use std::{fmt::Display, panic}; -use time::{format_description::well_known::Rfc3339, OffsetDateTime}; -use tracing::error; -use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; #[tokio::main] async fn main() { - // If tracing initialization fails, nevertheless emit a structured log event. - let result = init_tracing(); - if let Err(ref error) = result { - log_error(error); - return; - }; - - // Replace the default panic hook with one that uses structured logging at ERROR level. - panic::set_hook(Box::new(|panic| error!(%panic, "process panicked"))); - - // Run and log any error. - if let Err(ref error) = run().await { - error!( - error = format!("{error:#}"), - backtrace = %error.backtrace(), - "process exited with ERROR" - ); + if let Err(e) = run().await { + eprintln!("Application error: {:?}", e); + std::process::exit(1); } } @@ -37,30 +18,10 @@ struct Config { run_server: mailpass::Config, } -fn init_tracing() -> Result<()> { - tracing_subscriber::registry() - .with(EnvFilter::from_default_env()) - .with(fmt::layer().json().flatten_event(true)) - .try_init() - .context("initialize tracing subscriber") -} - -fn log_error(error: &impl Display) { - let now = OffsetDateTime::now_utc().format(&Rfc3339).unwrap(); - let error = serde_json::to_string(&json!({ - "timestamp": now, - "level": "ERROR", - "message": "process exited with ERROR", - "error": format!("{error:#}") - })); - // Not using `eprintln!`, because `tracing_subscriber::fmt` uses stdout by default. - println!("{}", error.unwrap()); -} - async fn run() -> Result<()> { let config = Config::load().context("load configuration")?; - // info!(?config, "starting"); - - run_server(config.run_server).await + run_server(config.run_server) + .await + .context("Failed to run server") } diff --git a/backend/src/routes/mod.rs b/backend/src/routes/mod.rs index c5b6e1e..debb385 100644 --- a/backend/src/routes/mod.rs +++ b/backend/src/routes/mod.rs @@ -1,22 +1,31 @@ use axum::{ - body::Body, - http::{Request, StatusCode}, + http::StatusCode, routing::{get, post}, Json, Router, }; use serde_json::json; -use tower::ServiceBuilder; -use tower_http::trace::TraceLayer; -use tracing::{field, info_span, Span}; +use tower_http::cors::{Any, CorsLayer}; +use tower_http::trace::{self, TraceLayer}; +use tracing::Level; use crate::services::email_validator::validate_email; pub fn setup_routes() -> Router { + tracing_subscriber::fmt() + .with_target(false) + .compact() + .init(); + Router::new() .route("/", get(home)) .route("/email", post(validate_email)) .route("/health", get(health)) - .layer(ServiceBuilder::new().layer(TraceLayer::new_for_http().make_span_with(make_span))) + .route("/error", get(error)) + .layer( + TraceLayer::new_for_http() + .make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO)) + .on_response(trace::DefaultOnResponse::new().level(Level::INFO)), + ) } async fn home() -> Json { @@ -26,12 +35,10 @@ async fn home() -> Json { Json(response) } -async fn health() -> StatusCode { - StatusCode::NO_CONTENT +async fn health() -> Result<&'static str, StatusCode> { + Ok("Service is up and running") } -fn make_span(request: &Request) -> Span { - let headers = request.headers(); - let path = request.uri().path(); - info_span!("incoming request", path, ?headers, trace_id = field::Empty) +async fn error() -> Result<&'static str, StatusCode> { + Err(StatusCode::SERVICE_UNAVAILABLE) }