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<()> {
dotenv().ok();
init_logger();
info!("Hello, world!");
let port = env::var("PHTHONUS_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::{
body::Bytes,
@ -40,30 +40,44 @@ pub async fn add_version(
/// This middleware will calculate each request latency
/// and add request's information to each info_span.
pub fn logging_route(router: Router) -> Router {
router.layer(
TraceLayer::new_for_http()
.make_span_with(|req: &Request<_>| {
let unknown = &HeaderValue::from_static("Unknown");
let empty = &HeaderValue::from_static("");
let headers = req.headers();
let ua = headers
.get("User-Agent")
.unwrap_or(unknown)
.to_str()
.unwrap_or("Unknown");
let host = headers.get("Host").unwrap_or(empty).to_str().unwrap_or("");
info_span!("HTTP", method = ?req.method(), host, uri = ?req.uri(), ua)
})
.on_request(|_req: &Request<_>, _span: &Span| {})
.on_response(|res: &Response, latency: Duration, _span: &Span| {
info!("{} {}μs", res.status(), latency.as_micros());
})
.on_body_chunk(|_chunk: &Bytes, _latency: Duration, _span: &Span| {})
.on_eos(|_trailers: Option<&HeaderMap>, _stream_duration: Duration, _span: &Span| {})
.on_failure(
|error: ServerErrorsFailureClass, _latency: Duration, _span: &Span| {
error!("{}", error);
},
),
)
let make_span = |req: &Request<_>| {
let unknown = &HeaderValue::from_static("Unknown");
let empty = &HeaderValue::from_static("");
let headers = req.headers();
let ua = headers
.get("User-Agent")
.unwrap_or(unknown)
.to_str()
.unwrap_or("Unknown");
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()
.make_span_with(make_span)
.on_request(|_req: &Request<_>, _span: &Span| {})
.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_failure(
|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)
}
}