diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fd311f..0991166 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,11 @@ All notable changes to this project will be documented in this file. * `EnvFilter`'s constructors (`from_env`, etc.) are moved to `EnvFilterBuilder`. * Upgrade to opentelemetry 0.31.0. +### Notable changes + +* Timestamp format in `TextLayout`, `JsonLayout`, and `LogfmtLayout` is changed from RFC 9557 to RFC 3339 format. + * That is, from "2025-01-10T15:22:37.868815+08:00[Asia/Shanghai]" to "2025-01-10T15:22:37.868815+08:00". + ## [0.27.0] 2025-08-18 ### Notable changes diff --git a/src/diagnostic/fastrace.rs b/src/diagnostic/fastrace.rs index b7a172a..6670e7c 100644 --- a/src/diagnostic/fastrace.rs +++ b/src/diagnostic/fastrace.rs @@ -21,11 +21,11 @@ use crate::diagnostic::Visitor; /// Output format: /// /// ```text -/// 2025-01-10T15:22:37.868815+08:00[Asia/Shanghai] ERROR fastrace: fastrace.rs:39 Hello syslog error! trace_id=37f9c45f918cbb477089afb0d7162e7e -/// 2025-01-10T15:22:37.868890+08:00[Asia/Shanghai] WARN fastrace: fastrace.rs:40 Hello syslog warn! trace_id=37f9c45f918cbb477089afb0d7162e7e -/// 2025-01-10T15:22:37.868921+08:00[Asia/Shanghai] INFO fastrace: fastrace.rs:41 Hello syslog info! trace_id=37f9c45f918cbb477089afb0d7162e7e -/// 2025-01-10T15:22:37.868949+08:00[Asia/Shanghai] DEBUG fastrace: fastrace.rs:42 Hello syslog debug! trace_id=37f9c45f918cbb477089afb0d7162e7e -/// 2025-01-10T15:22:37.868976+08:00[Asia/Shanghai] TRACE fastrace: fastrace.rs:43 Hello syslog trace! trace_id=37f9c45f918cbb477089afb0d7162e7e +/// 2025-01-10T15:22:37.868815+08:00 ERROR fastrace: fastrace.rs:39 Hello syslog error! trace_id=37f9c45f918cbb477089afb0d7162e7e +/// 2025-01-10T15:22:37.868890+08:00 WARN fastrace: fastrace.rs:40 Hello syslog warn! trace_id=37f9c45f918cbb477089afb0d7162e7e +/// 2025-01-10T15:22:37.868921+08:00 INFO fastrace: fastrace.rs:41 Hello syslog info! trace_id=37f9c45f918cbb477089afb0d7162e7e +/// 2025-01-10T15:22:37.868949+08:00 DEBUG fastrace: fastrace.rs:42 Hello syslog debug! trace_id=37f9c45f918cbb477089afb0d7162e7e +/// 2025-01-10T15:22:37.868976+08:00 TRACE fastrace: fastrace.rs:43 Hello syslog trace! trace_id=37f9c45f918cbb477089afb0d7162e7e /// ``` /// /// ## Example diff --git a/src/layout/google_cloud_logging.rs b/src/layout/google_cloud_logging.rs index 651a533..608de03 100644 --- a/src/layout/google_cloud_logging.rs +++ b/src/layout/google_cloud_logging.rs @@ -224,6 +224,8 @@ where impl Layout for GoogleCloudLoggingLayout { fn format(&self, record: &Record, diags: &[Box]) -> Result, Error> { + let timestamp = jiff::Timestamp::now(); + let mut visitor = KvCollector { layout: self, payload_fields: BTreeMap::new(), @@ -243,7 +245,7 @@ impl Layout for GoogleCloudLoggingLayout { let record_line = RecordLine { extra_fields: visitor.payload_fields, - timestamp: jiff::Timestamp::now(), + timestamp, severity: record.level().as_str(), message: record.args(), labels: visitor.labels, diff --git a/src/layout/json.rs b/src/layout/json.rs index 9f2c7c5..d4ec4b7 100644 --- a/src/layout/json.rs +++ b/src/layout/json.rs @@ -16,9 +16,9 @@ use std::borrow::Cow; use std::collections::BTreeMap; use std::fmt::Arguments; -use jiff::Timestamp; use jiff::Zoned; use jiff::tz::TimeZone; +use jiff::{Timestamp, TimestampDisplayWithOffset}; use log::Record; use serde::Serialize; use serde_json::Map; @@ -102,8 +102,8 @@ impl Visitor for DiagsCollector<'_> { #[derive(Debug, Clone, Serialize)] struct RecordLine<'a> { - #[serde(serialize_with = "serialize_time_zone")] - timestamp: Zoned, + #[serde(serialize_with = "serialize_timestamp")] + timestamp: TimestampDisplayWithOffset, level: &'a str, target: &'a str, file: &'a str, @@ -116,7 +116,10 @@ struct RecordLine<'a> { diags: BTreeMap, } -fn serialize_time_zone(timestamp: &Zoned, serializer: S) -> Result +fn serialize_timestamp( + timestamp: &TimestampDisplayWithOffset, + serializer: S, +) -> Result where S: serde::Serializer, { @@ -134,6 +137,12 @@ impl Layout for JsonLayout { fn format(&self, record: &Record, diags: &[Box]) -> Result, Error> { let diagnostics = diags; + let time = match self.tz.clone() { + None => Zoned::now(), + Some(tz) => Timestamp::now().to_zoned(tz), + }; + let timestamp = time.timestamp().display_with_offset(time.offset()); + let mut kvs = Map::new(); let mut kvs_visitor = KvCollector { kvs: &mut kvs }; record @@ -148,10 +157,7 @@ impl Layout for JsonLayout { } let record_line = RecordLine { - timestamp: match self.tz.clone() { - Some(tz) => Timestamp::now().to_zoned(tz), - None => Zoned::now(), - }, + timestamp, level: record.level().as_str(), target: record.target(), file: record.file().unwrap_or_default(), diff --git a/src/layout/logfmt.rs b/src/layout/logfmt.rs index f52cf26..5f4f37d 100644 --- a/src/layout/logfmt.rs +++ b/src/layout/logfmt.rs @@ -117,9 +117,11 @@ impl Visitor for KvFormatter { impl Layout for LogfmtLayout { fn format(&self, record: &Record, diags: &[Box]) -> Result, Error> { let time = match self.tz.clone() { - Some(tz) => Timestamp::now().to_zoned(tz), None => Zoned::now(), + Some(tz) => Timestamp::now().to_zoned(tz), }; + let time = time.timestamp().display_with_offset(time.offset()); + let level = record.level().to_string(); let target = record.target(); let file = filename(record); diff --git a/src/layout/text.rs b/src/layout/text.rs index 69e40d1..a6f803e 100644 --- a/src/layout/text.rs +++ b/src/layout/text.rs @@ -184,9 +184,11 @@ impl Visitor for KvWriter { impl Layout for TextLayout { fn format(&self, record: &Record, diags: &[Box]) -> Result, Error> { let time = match self.tz.clone() { - Some(tz) => Timestamp::now().to_zoned(tz), None => Zoned::now(), + Some(tz) => Timestamp::now().to_zoned(tz), }; + let time = time.timestamp().display_with_offset(time.offset()); + let level = self.format_record_level(record.level()); let target = record.target(); let file = filename(record);