feat(axum): update log format

This commit is contained in:
xfy
2024-09-19 22:56:29 +08:00
parent e79c23ea08
commit 8cbace8605
2 changed files with 41 additions and 28 deletions

View File

@ -20,7 +20,6 @@ type Result<T> = std::result::Result<T, Box<dyn Error>>;
async fn main() -> Result<()> { async fn main() -> Result<()> {
dotenv().ok(); dotenv().ok();
init_logger(); init_logger();
info!("Hello, world!");
let port = env::var("PHTHONUS_PORT") let port = env::var("PHTHONUS_PORT")
.map(|port| port.parse::<u16>().unwrap_or(DEFAULT_PORT)) .map(|port| port.parse::<u16>().unwrap_or(DEFAULT_PORT))

View File

@ -1,4 +1,4 @@
use std::time::Duration; use std::{fmt::Display, time::Duration};
use axum::{ use axum::{
body::Bytes, body::Bytes,
@ -40,30 +40,44 @@ pub async fn add_version(
/// This middleware will calculate each request latency /// This middleware will calculate each request latency
/// and add request's information to each info_span. /// and add request's information to each info_span.
pub fn logging_route(router: Router) -> Router { pub fn logging_route(router: Router) -> Router {
router.layer( let make_span = |req: &Request<_>| {
TraceLayer::new_for_http() let unknown = &HeaderValue::from_static("Unknown");
.make_span_with(|req: &Request<_>| { let empty = &HeaderValue::from_static("");
let unknown = &HeaderValue::from_static("Unknown"); let headers = req.headers();
let empty = &HeaderValue::from_static(""); let ua = headers
let headers = req.headers(); .get("User-Agent")
let ua = headers .unwrap_or(unknown)
.get("User-Agent") .to_str()
.unwrap_or(unknown) .unwrap_or("Unknown");
.to_str() let host = headers.get("Host").unwrap_or(empty).to_str().unwrap_or("");
.unwrap_or("Unknown"); info_span!("HTTP", method = ?req.method(), host, uri = ?req.uri(), ua)
let host = headers.get("Host").unwrap_or(empty).to_str().unwrap_or(""); };
info_span!("HTTP", method = ?req.method(), host, uri = ?req.uri(), ua)
}) let trace_layer = TraceLayer::new_for_http()
.on_request(|_req: &Request<_>, _span: &Span| {}) .make_span_with(make_span)
.on_response(|res: &Response, latency: Duration, _span: &Span| { .on_request(|_req: &Request<_>, _span: &Span| {})
info!("{} {}μs", res.status(), latency.as_micros()); .on_response(|res: &Response, latency: Duration, _span: &Span| {
}) info!("{}", format_latency(latency, res.status()));
.on_body_chunk(|_chunk: &Bytes, _latency: Duration, _span: &Span| {}) })
.on_eos(|_trailers: Option<&HeaderMap>, _stream_duration: Duration, _span: &Span| {}) .on_body_chunk(|_chunk: &Bytes, _latency: Duration, _span: &Span| {})
.on_failure( .on_eos(|_trailers: Option<&HeaderMap>, _stream_duration: Duration, _span: &Span| {})
|error: ServerErrorsFailureClass, _latency: Duration, _span: &Span| { .on_failure(
error!("{}", error); |error: ServerErrorsFailureClass, latency: Duration, _span: &Span| {
}, error!("{}", format_latency(latency, error));
), },
) );
router.layer(trace_layer)
}
/// Format request latency and status message
/// return a string
fn format_latency(latency: Duration, status: impl Display) -> String {
let micros = latency.as_micros();
let millis = latency.as_millis();
if micros >= 1000 {
format!("{} {}ms", status, millis)
} else {
format!("{} {}μs", status, micros)
}
} }