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