refactor: use jiff in logger

This commit is contained in:
Rob Ede 2026-04-12 14:32:48 +01:00
parent 3556ae0b4f
commit e3715386bd
No known key found for this signature in database
GPG Key ID: F5E3FCAA33CBF062
3 changed files with 40 additions and 25 deletions

19
Cargo.lock generated
View File

@ -356,6 +356,7 @@ dependencies = [
"futures-util", "futures-util",
"impl-more", "impl-more",
"itoa", "itoa",
"jiff",
"language-tags", "language-tags",
"log", "log",
"mime", "mime",
@ -374,7 +375,6 @@ dependencies = [
"smallvec", "smallvec",
"socket2 0.6.3", "socket2 0.6.3",
"static_assertions", "static_assertions",
"time",
"tokio", "tokio",
"tokio-util", "tokio-util",
"tracing", "tracing",
@ -1813,10 +1813,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359"
dependencies = [ dependencies = [
"jiff-static", "jiff-static",
"jiff-tzdb-platform",
"log", "log",
"portable-atomic", "portable-atomic",
"portable-atomic-util", "portable-atomic-util",
"serde_core", "serde_core",
"windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -1830,6 +1832,21 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "jiff-tzdb"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c900ef84826f1338a557697dc8fc601df9ca9af4ac137c7fb61d4c6f2dfd3076"
[[package]]
name = "jiff-tzdb-platform"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8"
dependencies = [
"jiff-tzdb",
]
[[package]] [[package]]
name = "jobserver" name = "jobserver"
version = "0.1.34" version = "0.1.34"

View File

@ -152,6 +152,7 @@ futures-core = { version = "0.3.17", default-features = false }
futures-util = { version = "0.3.17", default-features = false } futures-util = { version = "0.3.17", default-features = false }
impl-more = "0.1.4" impl-more = "0.1.4"
itoa = "1" itoa = "1"
jiff = "0.2"
language-tags = "0.3" language-tags = "0.3"
log = "0.4" log = "0.4"
mime = "0.3" mime = "0.3"
@ -164,7 +165,6 @@ serde_json = "1.0"
serde_urlencoded = "0.7" serde_urlencoded = "0.7"
smallvec = "1.6.1" smallvec = "1.6.1"
socket2 = "0.6" socket2 = "0.6"
time = { version = "0.3", default-features = false, features = ["formatting"] }
tracing = "0.1.30" tracing = "0.1.30"
url = "2.5.4" url = "2.5.4"

View File

@ -16,13 +16,13 @@ use actix_service::{Service, Transform};
use actix_utils::future::{ready, Ready}; use actix_utils::future::{ready, Ready};
use bytes::Bytes; use bytes::Bytes;
use futures_core::ready; use futures_core::ready;
use jiff::Timestamp;
use log::{debug, warn, Level}; use log::{debug, warn, Level};
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
#[cfg(feature = "unicode")] #[cfg(feature = "unicode")]
use regex::Regex; use regex::Regex;
#[cfg(not(feature = "unicode"))] #[cfg(not(feature = "unicode"))]
use regex_lite::Regex; use regex_lite::Regex;
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
use crate::{ use crate::{
body::{BodySize, MessageBody}, body::{BodySize, MessageBody},
@ -330,13 +330,13 @@ where
LoggerResponse { LoggerResponse {
fut: self.service.call(req), fut: self.service.call(req),
format: None, format: None,
time: OffsetDateTime::now_utc(), time: Timestamp::now(),
log_target: Cow::Borrowed(""), log_target: Cow::Borrowed(""),
log_level: self.inner.log_level, log_level: self.inner.log_level,
_phantom: PhantomData, _phantom: PhantomData,
} }
} else { } else {
let now = OffsetDateTime::now_utc(); let now = Timestamp::now();
let mut format = self.inner.format.clone(); let mut format = self.inner.format.clone();
for unit in &mut format.0 { for unit in &mut format.0 {
@ -363,7 +363,7 @@ pin_project! {
{ {
#[pin] #[pin]
fut: S::Future, fut: S::Future,
time: OffsetDateTime, time: Timestamp,
format: Option<Format>, format: Option<Format>,
log_target: Cow<'static, str>, log_target: Cow<'static, str>,
log_level: Level, log_level: Level,
@ -432,7 +432,7 @@ pin_project! {
body: B, body: B,
format: Option<Format>, format: Option<Format>,
size: usize, size: usize,
time: OffsetDateTime, time: Timestamp,
log_target: Cow<'static, str>, log_target: Cow<'static, str>,
log_level: Level log_level: Level
} }
@ -614,20 +614,18 @@ impl FormatText {
&self, &self,
fmt: &mut fmt::Formatter<'_>, fmt: &mut fmt::Formatter<'_>,
size: usize, size: usize,
entry_time: OffsetDateTime, entry_time: Timestamp,
) -> Result<(), fmt::Error> { ) -> Result<(), fmt::Error> {
match self { match self {
FormatText::Str(ref string) => fmt.write_str(string), FormatText::Str(ref string) => fmt.write_str(string),
FormatText::Percent => "%".fmt(fmt), FormatText::Percent => "%".fmt(fmt),
FormatText::ResponseSize => size.fmt(fmt), FormatText::ResponseSize => size.fmt(fmt),
FormatText::Time => { FormatText::Time => {
let rt = OffsetDateTime::now_utc() - entry_time; let rt = entry_time.duration_until(Timestamp::now()).as_secs_f64();
let rt = rt.as_seconds_f64();
fmt.write_fmt(format_args!("{:.6}", rt)) fmt.write_fmt(format_args!("{:.6}", rt))
} }
FormatText::TimeMillis => { FormatText::TimeMillis => {
let rt = OffsetDateTime::now_utc() - entry_time; let rt = entry_time.duration_until(Timestamp::now()).as_millis_f64();
let rt = (rt.whole_nanoseconds() as f64) / 1_000_000.0;
fmt.write_fmt(format_args!("{:.6}", rt)) fmt.write_fmt(format_args!("{:.6}", rt))
} }
FormatText::EnvironHeader(ref name) => { FormatText::EnvironHeader(ref name) => {
@ -669,7 +667,7 @@ impl FormatText {
} }
} }
fn render_request(&mut self, now: OffsetDateTime, req: &ServiceRequest) { fn render_request(&mut self, now: Timestamp, req: &ServiceRequest) {
match self { match self {
FormatText::RequestLine => { FormatText::RequestLine => {
*self = if req.query_string().is_empty() { *self = if req.query_string().is_empty() {
@ -690,7 +688,7 @@ impl FormatText {
}; };
} }
FormatText::UrlPath => *self = FormatText::Str(req.path().to_string()), FormatText::UrlPath => *self = FormatText::Str(req.path().to_string()),
FormatText::RequestTime => *self = FormatText::Str(now.format(&Rfc3339).unwrap()), FormatText::RequestTime => *self = FormatText::Str(now.to_string()),
FormatText::RequestHeader(ref name) => { FormatText::RequestHeader(ref name) => {
let s = if let Some(val) = req.headers().get(name) { let s = if let Some(val) = req.headers().get(name) {
String::from_utf8_lossy(val.as_bytes()).into_owned() String::from_utf8_lossy(val.as_bytes()).into_owned()
@ -805,7 +803,7 @@ mod tests {
)) ))
.to_srv_request(); .to_srv_request();
let now = OffsetDateTime::now_utc(); let now = Timestamp::now();
for unit in &mut format.0 { for unit in &mut format.0 {
unit.render_request(now, &req); unit.render_request(now, &req);
} }
@ -816,7 +814,7 @@ mod tests {
unit.render_response(&res); unit.render_response(&res);
} }
let entry_time = OffsetDateTime::now_utc(); let entry_time = Timestamp::now();
let render = |fmt: &mut fmt::Formatter<'_>| { let render = |fmt: &mut fmt::Formatter<'_>| {
for unit in &format.0 { for unit in &format.0 {
unit.render(fmt, 1024, entry_time)?; unit.render(fmt, 1024, entry_time)?;
@ -838,7 +836,7 @@ mod tests {
.uri("/test/route/yeah") .uri("/test/route/yeah")
.to_srv_request(); .to_srv_request();
let now = OffsetDateTime::now_utc(); let now = Timestamp::now();
for unit in &mut format.0 { for unit in &mut format.0 {
unit.render_request(now, &req); unit.render_request(now, &req);
} }
@ -871,7 +869,7 @@ mod tests {
.peer_addr("127.0.0.1:8081".parse().unwrap()) .peer_addr("127.0.0.1:8081".parse().unwrap())
.to_srv_request(); .to_srv_request();
let now = OffsetDateTime::now_utc(); let now = Timestamp::now();
for unit in &mut format.0 { for unit in &mut format.0 {
unit.render_request(now, &req); unit.render_request(now, &req);
} }
@ -882,7 +880,7 @@ mod tests {
unit.render_response(&res); unit.render_response(&res);
} }
let entry_time = OffsetDateTime::now_utc(); let entry_time = Timestamp::now();
let render = |fmt: &mut fmt::Formatter<'_>| { let render = |fmt: &mut fmt::Formatter<'_>| {
for unit in &format.0 { for unit in &format.0 {
unit.render(fmt, 1024, entry_time)?; unit.render(fmt, 1024, entry_time)?;
@ -901,7 +899,7 @@ mod tests {
let mut format = Format::new("%t"); let mut format = Format::new("%t");
let req = TestRequest::default().to_srv_request(); let req = TestRequest::default().to_srv_request();
let now = OffsetDateTime::now_utc(); let now = Timestamp::now();
for unit in &mut format.0 { for unit in &mut format.0 {
unit.render_request(now, &req); unit.render_request(now, &req);
} }
@ -919,7 +917,7 @@ mod tests {
Ok(()) Ok(())
}; };
let s = format!("{}", FormatDisplay(&render)); let s = format!("{}", FormatDisplay(&render));
assert!(s.contains(&now.format(&Rfc3339).unwrap())); assert!(s.contains(&now.to_string()));
} }
#[actix_rt::test] #[actix_rt::test]
@ -933,7 +931,7 @@ mod tests {
)) ))
.to_srv_request(); .to_srv_request();
let now = OffsetDateTime::now_utc(); let now = Timestamp::now();
for unit in &mut format.0 { for unit in &mut format.0 {
unit.render_request(now, &req); unit.render_request(now, &req);
} }
@ -944,7 +942,7 @@ mod tests {
unit.render_response(&res); unit.render_response(&res);
} }
let entry_time = OffsetDateTime::now_utc(); let entry_time = Timestamp::now();
let render = |fmt: &mut fmt::Formatter<'_>| { let render = |fmt: &mut fmt::Formatter<'_>| {
for unit in &format.0 { for unit in &format.0 {
unit.render(fmt, 1024, entry_time)?; unit.render(fmt, 1024, entry_time)?;
@ -971,7 +969,7 @@ mod tests {
assert_eq!(label, "CUSTOM"); assert_eq!(label, "CUSTOM");
let req = TestRequest::default().to_srv_request(); let req = TestRequest::default().to_srv_request();
let now = OffsetDateTime::now_utc(); let now = Timestamp::now();
unit.render_request(now, &req); unit.render_request(now, &req);
@ -1004,7 +1002,7 @@ mod tests {
let req = TestRequest::default().to_http_request(); let req = TestRequest::default().to_http_request();
let resp_ok = ServiceResponse::new(req, HttpResponse::Ok().finish()); let resp_ok = ServiceResponse::new(req, HttpResponse::Ok().finish());
let now = OffsetDateTime::now_utc(); let now = Timestamp::now();
unit.render_response(&resp_ok); unit.render_response(&resp_ok);
let render = |fmt: &mut fmt::Formatter<'_>| unit.render(fmt, 1024, now); let render = |fmt: &mut fmt::Formatter<'_>| unit.render(fmt, 1024, now);