mirror of
https://git.asonix.dog/asonix/pict-rs
synced 2024-11-20 11:21:14 +00:00
Add configuration option to control request logging
This commit is contained in:
parent
6ef9dc404f
commit
4e75764110
5 changed files with 67 additions and 18 deletions
|
@ -18,6 +18,7 @@ impl Args {
|
|||
log_format,
|
||||
log_targets,
|
||||
log_spans,
|
||||
log_requests,
|
||||
no_log_ansi,
|
||||
console_address,
|
||||
console_buffer_capacity,
|
||||
|
@ -40,6 +41,7 @@ impl Args {
|
|||
targets: log_targets.map(Serde::new),
|
||||
log_spans,
|
||||
no_ansi: no_log_ansi,
|
||||
log_requests,
|
||||
},
|
||||
console: Console {
|
||||
address: console_address,
|
||||
|
@ -584,6 +586,8 @@ struct Logging {
|
|||
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||
log_spans: bool,
|
||||
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||
log_requests: bool,
|
||||
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||
no_ansi: bool,
|
||||
}
|
||||
|
||||
|
@ -928,6 +932,9 @@ pub(super) struct Args {
|
|||
/// Whether to log openning and closing of tracing spans to stdout
|
||||
#[arg(long)]
|
||||
log_spans: bool,
|
||||
/// Whether to log request completions at an INFO level
|
||||
#[arg(long)]
|
||||
log_requests: bool,
|
||||
|
||||
#[arg(long)]
|
||||
/// Whether to disable color-codes in log output
|
||||
|
|
|
@ -55,6 +55,7 @@ struct LoggingDefaults {
|
|||
format: LogFormat,
|
||||
targets: Serde<Targets>,
|
||||
log_spans: bool,
|
||||
log_requests: bool,
|
||||
no_ansi: bool,
|
||||
}
|
||||
|
||||
|
@ -236,6 +237,7 @@ impl Default for LoggingDefaults {
|
|||
format: LogFormat::Normal,
|
||||
targets: "info".parse().expect("Valid targets string"),
|
||||
log_spans: false,
|
||||
log_requests: false,
|
||||
no_ansi: false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,6 +165,8 @@ pub(crate) struct Logging {
|
|||
pub(crate) log_spans: bool,
|
||||
|
||||
pub(crate) no_ansi: bool,
|
||||
|
||||
pub(crate) log_requests: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
|
|
|
@ -1741,7 +1741,7 @@ async fn launch<
|
|||
spawn_workers(state.clone());
|
||||
|
||||
App::new()
|
||||
.wrap(Log)
|
||||
.wrap(Log::new(state.config.tracing.logging.log_requests))
|
||||
.wrap(TracingLogger::default())
|
||||
.wrap(Deadline)
|
||||
.wrap(Metrics)
|
||||
|
|
|
@ -7,16 +7,30 @@ use actix_web::{
|
|||
ResponseError,
|
||||
};
|
||||
|
||||
pub(crate) struct Log;
|
||||
pub(crate) struct Log {
|
||||
info: bool,
|
||||
}
|
||||
pub(crate) struct LogMiddleware<S> {
|
||||
info: bool,
|
||||
inner: S,
|
||||
}
|
||||
|
||||
impl Log {
|
||||
pub(crate) fn new(info: bool) -> Self {
|
||||
Self { info }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct LogError(actix_web::Error);
|
||||
pub(crate) struct LogError {
|
||||
info: bool,
|
||||
error: actix_web::Error,
|
||||
}
|
||||
|
||||
pin_project_lite::pin_project! {
|
||||
pub(crate) struct LogFuture<F> {
|
||||
info: bool,
|
||||
|
||||
#[pin]
|
||||
inner: F,
|
||||
}
|
||||
|
@ -24,6 +38,8 @@ pin_project_lite::pin_project! {
|
|||
|
||||
pin_project_lite::pin_project! {
|
||||
pub(crate) struct LogBody<B> {
|
||||
info: bool,
|
||||
|
||||
status: Option<StatusCode>,
|
||||
|
||||
#[pin]
|
||||
|
@ -45,7 +61,10 @@ where
|
|||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ready(Ok(LogMiddleware { inner: service }))
|
||||
ready(Ok(LogMiddleware {
|
||||
info: self.info,
|
||||
inner: service,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,13 +83,20 @@ where
|
|||
&self,
|
||||
ctx: &mut core::task::Context<'_>,
|
||||
) -> std::task::Poll<Result<(), Self::Error>> {
|
||||
self.inner
|
||||
.poll_ready(ctx)
|
||||
.map(|res| res.map_err(|e| LogError(e.into()).into()))
|
||||
self.inner.poll_ready(ctx).map(|res| {
|
||||
res.map_err(|e| {
|
||||
LogError {
|
||||
info: self.info,
|
||||
error: e.into(),
|
||||
}
|
||||
.into()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||
LogFuture {
|
||||
info: self.info,
|
||||
inner: self.inner.call(req),
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +114,7 @@ where
|
|||
self: std::pin::Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Self::Output> {
|
||||
let info = self.info;
|
||||
let this = self.project();
|
||||
|
||||
std::task::Poll::Ready(match std::task::ready!(this.inner.poll(cx)) {
|
||||
|
@ -95,15 +122,23 @@ where
|
|||
let status = response.status();
|
||||
|
||||
let status = if response.response().body().size().is_eof() {
|
||||
emit(status);
|
||||
emit(status, info);
|
||||
None
|
||||
} else {
|
||||
Some(status)
|
||||
};
|
||||
|
||||
Ok(response.map_body(|_, inner| LogBody { status, inner }))
|
||||
Ok(response.map_body(|_, inner| LogBody {
|
||||
info,
|
||||
status,
|
||||
inner,
|
||||
}))
|
||||
}
|
||||
Err(e) => Err(LogError(e.into()).into()),
|
||||
Err(e) => Err(LogError {
|
||||
info,
|
||||
error: e.into(),
|
||||
}
|
||||
.into()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +163,7 @@ where
|
|||
|
||||
if opt.is_none() {
|
||||
if let Some(status) = this.status.take() {
|
||||
emit(status);
|
||||
emit(status, *this.info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,31 +173,32 @@ where
|
|||
|
||||
impl std::fmt::Display for LogError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
self.error.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for LogError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
self.0.source()
|
||||
self.error.source()
|
||||
}
|
||||
}
|
||||
|
||||
impl ResponseError for LogError {
|
||||
fn status_code(&self) -> actix_web::http::StatusCode {
|
||||
self.0.as_response_error().status_code()
|
||||
self.error.as_response_error().status_code()
|
||||
}
|
||||
|
||||
fn error_response(&self) -> actix_web::HttpResponse<actix_web::body::BoxBody> {
|
||||
let response = self.0.error_response();
|
||||
let response = self.error.error_response();
|
||||
let status = response.status();
|
||||
|
||||
if response.body().size().is_eof() {
|
||||
emit(status);
|
||||
emit(status, self.info);
|
||||
response
|
||||
} else {
|
||||
response.map_body(|_, inner| {
|
||||
LogBody {
|
||||
info: self.info,
|
||||
status: Some(status),
|
||||
inner,
|
||||
}
|
||||
|
@ -172,14 +208,16 @@ impl ResponseError for LogError {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit(status: StatusCode) {
|
||||
fn emit(status: StatusCode, info: bool) {
|
||||
if status.is_server_error() {
|
||||
tracing::error!("server error");
|
||||
} else if status.is_client_error() {
|
||||
tracing::warn!("client error");
|
||||
} else if status.is_redirection() {
|
||||
tracing::info!("redirected");
|
||||
} else {
|
||||
} else if info {
|
||||
tracing::info!("completed");
|
||||
} else {
|
||||
tracing::debug!("completed");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue