Skip to content

Commit 5aab142

Browse files
committed
Fix parsing of timestamps with newer lava
In the latest version of lava the dt field is created with atetime.datetime.now(datetime.UTC).isoformat() rather then datetime.datetime.utcnow().isoformat(). This causes the timezone specifier to be added (always +00:00 as the logs are UTC)'. From a Rust perspective the former is a `NaiveDateTime` (no timezone) while the later is a `DateTime<Utc>`. Adjust the parsing to try both, but convert to NaiveDateTime to keep the same user API. In future potentially this could be moved to always be a DateTime to make it more clear to the end-user what the stamp is
1 parent 65295ba commit 5aab142

1 file changed

Lines changed: 36 additions & 1 deletion

File tree

lava-api/src/joblog.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::task::Poll;
55
use std::time::Duration;
66

77
use bytes::{Bytes, BytesMut};
8-
use chrono::NaiveDateTime;
8+
use chrono::{DateTime, NaiveDateTime, Utc};
99
use futures::future::BoxFuture;
1010
use futures::stream::BoxStream;
1111
use futures::{prelude::*, ready};
@@ -218,8 +218,25 @@ pub enum JobLogLevel {
218218
Exception,
219219
}
220220

221+
fn job_deserialize_dt<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
222+
where
223+
D: Deserializer<'de>,
224+
{
225+
#[derive(Deserialize)]
226+
#[serde(untagged)]
227+
enum DorN {
228+
D(DateTime<Utc>),
229+
N(NaiveDateTime),
230+
}
231+
match DorN::deserialize(d)? {
232+
DorN::D(d) => Ok(d.naive_utc()),
233+
DorN::N(n) => Ok(n),
234+
}
235+
}
236+
221237
#[derive(Debug, Clone, Deserialize)]
222238
pub struct JobLogEntry {
239+
#[serde(deserialize_with = "job_deserialize_dt")]
223240
pub dt: NaiveDateTime,
224241
pub lvl: JobLogLevel,
225242
pub ns: Option<String>,
@@ -302,3 +319,21 @@ impl Stream for JobLog<'_> {
302319
}
303320
}
304321
}
322+
323+
#[cfg(test)]
324+
mod tests {
325+
use super::*;
326+
327+
#[test]
328+
fn job_log_entry_deserialisation() {
329+
let entry0: JobLogEntry = serde_json::from_str(
330+
r#"{"dt": "2026-06-02T12:16:27.730458", "lvl": "results", "msg": {"definition": "lava", "case": "job", "result": "pass"}}"#,
331+
)
332+
.unwrap();
333+
let entry1: JobLogEntry = serde_json::from_str(
334+
r#"{"dt": "2026-06-02T12:16:27.730458+00:00", "lvl": "results", "msg": {"definition": "lava", "case": "job", "result": "pass"}}"#,
335+
)
336+
.unwrap();
337+
assert_eq!(entry0.dt, entry1.dt);
338+
}
339+
}

0 commit comments

Comments
 (0)