Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ability to specify log level for access logger #3157

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions actix-web/CHANGES.md
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Added

- Add `Logger::level` to change the log level.

### Changed

- Updated `zstd` dependency to `0.13`.
Expand Down
1 change: 1 addition & 0 deletions actix-web/Cargo.toml
Expand Up @@ -123,6 +123,7 @@ tls-openssl = { package = "openssl", version = "0.10.55" }
tls-rustls = { package = "rustls", version = "0.21" }
tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] }
zstd = "0.13"
capture-logger = "0.1"

[[test]]
name = "test_server"
Expand Down
57 changes: 53 additions & 4 deletions actix-web/src/middleware/logger.rs
Expand Up @@ -16,7 +16,7 @@ use actix_service::{Service, Transform};
use actix_utils::future::{ready, Ready};
use bytes::Bytes;
use futures_core::ready;
use log::{debug, warn};
use log::{debug, warn, Level};
use pin_project_lite::pin_project;
use regex::{Regex, RegexSet};
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
Expand Down Expand Up @@ -47,7 +47,7 @@ use crate::{
/// ```
/// use actix_web::{middleware::Logger, App};
///
/// // access logs are printed with the INFO level so ensure it is enabled by default
/// // access logs by default are printed with the INFO level so ensure it is enabled by default
/// env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
///
/// let app = App::new()
Expand Down Expand Up @@ -89,6 +89,7 @@ struct Inner {
exclude: HashSet<String>,
exclude_regex: RegexSet,
log_target: Cow<'static, str>,
level: Level,
}

impl Logger {
Expand All @@ -99,6 +100,7 @@ impl Logger {
exclude: HashSet::new(),
exclude_regex: RegexSet::empty(),
log_target: Cow::Borrowed(module_path!()),
level: Level::Info,
}))
}

Expand Down Expand Up @@ -139,6 +141,24 @@ impl Logger {
self
}

/// Sets the logging level.
///
/// By default, the log level is `Level::Info`
///
/// # Examples
/// ```
/// # use log::Level;
/// # use actix_web::middleware::Logger;
/// Logger::default()
/// .level(Level::Debug);
/// ```
///
pub fn level(mut self, level: Level) -> Self {
let inner = Rc::get_mut(&mut self.0).unwrap();
inner.level = level;
self
}

/// Register a function that receives a ServiceRequest and returns a String for use in the
/// log line. The label passed as the first argument should match a replacement substring in
/// the logger format like `%{label}xi`.
Expand Down Expand Up @@ -242,6 +262,7 @@ impl Default for Logger {
exclude: HashSet::new(),
exclude_regex: RegexSet::empty(),
log_target: Cow::Borrowed(module_path!()),
level: Level::Info,
}))
}
}
Expand Down Expand Up @@ -308,6 +329,7 @@ where
format: None,
time: OffsetDateTime::now_utc(),
log_target: Cow::Borrowed(""),
level: self.inner.level,
_phantom: PhantomData,
}
} else {
Expand All @@ -323,6 +345,7 @@ where
format: Some(format),
time: now,
log_target: self.inner.log_target.clone(),
level: self.inner.level,
_phantom: PhantomData,
}
}
Expand All @@ -340,6 +363,7 @@ pin_project! {
time: OffsetDateTime,
format: Option<Format>,
log_target: Cow<'static, str>,
level:Level,
_phantom: PhantomData<B>,
}
}
Expand Down Expand Up @@ -386,13 +410,15 @@ where
let time = *this.time;
let format = this.format.take();
let log_target = this.log_target.clone();
let level = *this.level;

Poll::Ready(Ok(res.map_body(move |_, body| StreamLog {
body,
time,
format,
size: 0,
log_target,
level,
})))
}
}
Expand All @@ -405,6 +431,7 @@ pin_project! {
size: usize,
time: OffsetDateTime,
log_target: Cow<'static, str>,
level:Level,
}

impl<B> PinnedDrop for StreamLog<B> {
Expand All @@ -417,8 +444,7 @@ pin_project! {
Ok(())
};

log::info!(
target: this.log_target.as_ref(),
log::log!(target: this.log_target.as_ref(), this.level,
"{}", FormatDisplay(&render)
);
}
Expand Down Expand Up @@ -1004,4 +1030,27 @@ mod tests {
let req = TestRequest::default().to_srv_request();
srv.call(req).await.unwrap();
}

#[actix_rt::test]
async fn test_logger_level() {
let srv = |req: ServiceRequest| {
ok(req.into_response(HttpResponse::build(StatusCode::OK).finish()))
};
let logger = Logger::new("%{User-Agent}i test_level %s").level(log::Level::Trace);

let srv = logger.new_transform(srv.into_service()).await.unwrap();

let req = TestRequest::default()
.insert_header((
header::USER_AGENT,
header::HeaderValue::from_static("ACTIX-WEB"),
))
.to_srv_request();
capture_logger::begin_capture();
// The log is executed on drop, so the result need to be dropped
let _ = srv.call(req).await;
let log = capture_logger::pop_captured();
assert_eq!(log.unwrap().level(), log::Level::Trace);
capture_logger::end_capture();
}
}