1use chrono_lite::{Tm, time, localtime};
2use crate::core::{HttpLogger, HttpError};
3use crate::reqres::{HttpRequest, HttpResponse};
4use crate::util::escape;
5
6pub struct DefaultLogger;
8impl DefaultLogger {
9 fn format(&self, req: &HttpRequest, res: &HttpResponse) -> String {
10 let addr = req.addr;
11 let method = escape::control_sequences(req.method.as_str());
12 let route = escape::control_sequences(&req.route);
13
14 let code = res.code;
15 let desc = code.as_str();
16
17 let Tm { tm_mday, tm_mon, tm_year, tm_hour, tm_min, tm_sec, .. } = localtime(time()).expect("date out of range");
18 let year = tm_year + 1900;
19 let month = tm_mon + 1;
20 let date = format_args!("{tm_hour:02}:{tm_min:02}:{tm_sec:02} {tm_mday:02}-{month:02}-{year}");
21
22 let agent = req.get_header("User-Agent").and_then(|a| a.split(' ').next()).unwrap_or("-");
24 let agent = escape::control_sequences(agent);
25 format!("[{date}] {addr} {agent} {method} {route} -> {code} {desc}")
26 }
27}
28
29impl HttpLogger for DefaultLogger {
30 fn log(&self, req: &HttpRequest, res: &HttpResponse) {
31 println!("{}", self.format(req, res));
32 }
33
34 fn err(&self, req: &HttpRequest, res: &HttpResponse, error: &dyn HttpError) {
35 println!("{} ({}: {})", self.format(req, res), error.name(), error);
36 }
37}