One line per request, written when the response goes out: method, path, status, how long it took and how many bytes came in and went out. Bodies are never logged (they are a child's words), only their sizes.
8use log::{error, info, warn}; 9 10pub struct Access { 11 method: String, 12 path: String, 13 started: Instant, 14 bytes_in: usize, 15} 16 17impl Access { 18 pub fn new(request: &tiny_http::Request) -> Self { 19 Self { method: request.method().to_string(), path: request.url().to_owned(), started: Instant::now(), bytes_in: 0 } 20 }
Notes how large the request body turned out to be.
Sends the response and logs the request: errors at error, refusals at warn, the rest at info.
28 pub fn respond<R: Read>(&self, request: tiny_http::Request, response: tiny_http::Response<R>) { 29 let status = response.status_code().0; 30 let bytes_out = response.data_length(); 31 let ms = self.started.elapsed().as_millis(); 32 let out = bytes_out.map_or_else(|| "?".to_owned(), |n| n.to_string()); 33 let (m, p, b) = (&self.method, &self.path, self.bytes_in); 34 if status >= 500 { 35 error!(target: "access", "{m} {p} -> {status} in {ms} ms, {b} bytes in, {out} out"); 36 } else if status >= 400 { 37 warn!(target: "access", "{m} {p} -> {status} in {ms} ms, {b} bytes in, {out} out"); 38 } else { 39 info!(target: "access", "{m} {p} -> {status} in {ms} ms, {b} bytes in, {out} out"); 40 } 41 if let Err(e) = request.respond(response) { 42 warn!(target: "access", "{m} {p}: the client went away before the response was sent: {e}"); 43 } 44 } 45}