Closed behnam closed 5 years ago
I think it would be better to write own logger in this case. Builtin logger is more suitable for debugging to just what requests are coming in and what responses are going out.
I believe from point of view HTTP all requests/responses are fine as long as they are valid. Errors and warnings are rather suitable at handler code rather than HTTP messages logging facilities.
It is not difficult to make own logger(e.g. I use my own logger to print messages in debug builds only) and current implementation aims not to be too complex
Thanks, @DoumanAsh. IMHO, it would be helpful for rapid web-dev if the out-of-the-box logger was more informative, but totally understand if you prefer to keep it minimal and simple. Feel free to close if you think it's better to not make any change.
@fafhrd91 what do you think?
we log error and backtrace if handler returns error, i am not sure about normal 4xx/5xx. it could be configurable.
i'd like to close this issue before 1.0
i think default logger should be used as access logger, if you need app level logging it is better to use something like tokio-trace
I think this would be really useful, but the source code of the logger middleware becomes so complex that to copy and paste to customize it I don't know even where to start anyway. What if I just want to log HTTP status code >= 400, and with a proper WARN
or ERROR
severity?
OK, due that the inclusion of customizable logging level is not going to happen, I've forked the original source code of the Logger
middleware in a this new crate actix-contrib-logger to add just that, plus other improvements like by default log server errors (HTTP 5xx) with ERROR
severity, but it does allow to configure the level by status code:
use actix_contrib_logger::middleware::Logger;
use env_logger::Env;
use http::StatusCode;
use log::Level;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer};
env_logger::init_from_env(Env::default().default_filter_or("info"));
HttpServer::new(|| {
let logger = Logger::default()
.custom_level(|status| {
if status.is_server_error() {
Level::Error
} else if status == StatusCode::NOT_FOUND {
Level::Warn
} else {
Level::Info
}
});
App::new().wrap(logger)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
Logs will look like:
[2023-08-13T07:28:00Z INFO http_logger] 127.0.0.1 "GET / HTTP/1.1" 200 802 "-" "Mozilla/5.0 ..." 0.001985
[2023-08-13T07:29:10Z ERROR http_logger] 127.0.0.1 "POST /users HTTP/1.1" 500 86 "-" "curl/7.68.0" 0.002023
[2023-08-13T07:29:10Z WARN http_logger] 127.0.0.1 "PUT /users HTTP/1.1" 404 55 "-" "HTTPie/3.2.1" 0.002023
Although I'd be happy to create a PR and add any of the improvements in the actix-web project, but in the meantime my module can be used as a drop-in replacement of the original middleware.
The Logger middleware is a great tool for developing new web apps, but it's not easy to use it to set up warnings for non-successful requests, as it has the
info!()
call hardcoded.https://github.com/actix/actix-web/blob/1e1a4f846e0f3a109b168bfb660ae781697688eb/src/middleware/logger.rs#L118
The level can be calculated by a function/closure, given the request info and response status as input.
Personally, I would prefer to have 4xx/5xx responses logged as warning, instead of info.