28b22f6b22
* upgrade axum to 0.8.9 (and side deps) Bumps axum 0.7.5 → 0.8.9, axum-extra 0.9.4 → 0.12.6, axum-client-ip 0.6.1 → 1.3.1, axum-test 16.2.0 → 20.0.0, utoipa-swagger-ui 8.1 → 9.0.2. * warn upon using fallback ip Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * chore: replace use of deprecated try_next() * update console-subscriber to ensure single version of axum in the lock file * removed unused axum-test dev-dep --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
94 lines
2.7 KiB
Rust
94 lines
2.7 KiB
Rust
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use crate::middleware::client_ip::ClientIpAddr;
|
|
use axum::extract::Request;
|
|
use axum::http::HeaderValue;
|
|
use axum::http::header::{HOST, USER_AGENT};
|
|
use axum::middleware::Next;
|
|
use axum::response::IntoResponse;
|
|
use colored::Colorize;
|
|
use std::time::Instant;
|
|
use tracing::{debug, info};
|
|
|
|
enum LogLevel {
|
|
Debug,
|
|
Info,
|
|
}
|
|
|
|
pub async fn log_request_info(
|
|
client_ip: ClientIpAddr,
|
|
request: Request,
|
|
next: Next,
|
|
) -> impl IntoResponse {
|
|
log_request(client_ip, request, next, LogLevel::Info).await
|
|
}
|
|
|
|
pub async fn log_request_debug(
|
|
client_ip: ClientIpAddr,
|
|
request: Request,
|
|
next: Next,
|
|
) -> impl IntoResponse {
|
|
log_request(client_ip, request, next, LogLevel::Debug).await
|
|
}
|
|
|
|
/// Simple logger for requests
|
|
async fn log_request(
|
|
ClientIpAddr(addr): ClientIpAddr,
|
|
request: Request,
|
|
next: Next,
|
|
level: LogLevel,
|
|
) -> impl IntoResponse {
|
|
// TODO dz use `OriginalUri` extractor to get full URI even for nested
|
|
// routers if routes aren't logged correctly in handlers
|
|
fn header_map(header: Option<&HeaderValue>, msg: String) -> String {
|
|
header
|
|
.map(|x| x.to_str().unwrap_or(&msg).to_string())
|
|
.unwrap_or(msg)
|
|
}
|
|
|
|
let method = request.method().to_string().green();
|
|
let uri = request.uri().to_string().blue();
|
|
let agent = header_map(
|
|
request.headers().get(USER_AGENT),
|
|
"Unknown User Agent".to_string(),
|
|
);
|
|
|
|
let host = header_map(request.headers().get(HOST), "Unknown Host".to_string());
|
|
|
|
let start = Instant::now();
|
|
// run request through all middleware, incl. extractors
|
|
let res = next.run(request).await;
|
|
let time_taken = start.elapsed();
|
|
let status = res.status();
|
|
let print_status = if status.is_client_error() || status.is_server_error() {
|
|
status.to_string().red()
|
|
} else if status.is_success() {
|
|
status.to_string().green()
|
|
} else {
|
|
status.to_string().yellow()
|
|
};
|
|
|
|
let taken = "time taken".bold();
|
|
|
|
let time_taken = match time_taken.as_millis() {
|
|
ms if ms > 500 => format!("{taken}: {}", format!("{ms}ms").red()),
|
|
ms if ms > 200 => format!("{taken}: {}", format!("{ms}ms").yellow()),
|
|
ms if ms > 50 => format!("{taken}: {}", format!("{ms}ms").bright_yellow()),
|
|
ms => format!("{taken}: {ms}ms"),
|
|
};
|
|
|
|
let agent_str = "agent".bold();
|
|
|
|
match level {
|
|
LogLevel::Debug => debug!(
|
|
"[{addr} -> {host}] {method} '{uri}': {print_status} {time_taken} {agent_str}: {agent}"
|
|
),
|
|
LogLevel::Info => info!(
|
|
"[{addr} -> {host}] {method} '{uri}': {print_status} {time_taken} {agent_str}: {agent}"
|
|
),
|
|
}
|
|
|
|
res
|
|
}
|