diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index 100da643ca..ea205be5f9 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -50,6 +50,7 @@ once_cell = { optional = true, version = "1.13.0" } tracing-log = { path = "../tracing-log", version = "0.2", optional = true, default-features = false, features = ["log-tracer", "std"] } nu-ansi-term = { version = "0.46.0", optional = true } time = { version = "0.3.2", features = ["formatting"], optional = true } +chrono = { version = "0.4.26" } # only required by the json feature serde_json = { version = "1.0.82", optional = true } diff --git a/tracing-subscriber/src/fmt/time/chrono_crate.rs b/tracing-subscriber/src/fmt/time/chrono_crate.rs new file mode 100644 index 0000000000..64be7d2e73 --- /dev/null +++ b/tracing-subscriber/src/fmt/time/chrono_crate.rs @@ -0,0 +1,57 @@ +use crate::fmt::format::Writer; +use crate::fmt::time::FormatTime; + +/// Formats [local time]s and [UTC time]s with [formatter] implementations +/// that use the [`chrono` crate]. +/// +/// [local time]: https://docs.rs/chrono/0.4.26/chrono/offset/struct.Local.html +/// [UTC time]: https://docs.rs/chrono/0.4.26/chrono/offset/struct.Utc.html +/// [`chrono` crate]: https://docs.rs/chrono/0.4.26/chrono/ +/// [formatter]: https://docs.rs/time/0.3/time/formatting/trait.Formattable.html + +/// Tag-type (indicating UTC timezone) enabling static dispatch +/// to `chrono::Local` functions. +#[derive(Debug)] +pub struct LocalTime; + +impl FormatTime for LocalTime { + fn format_time(&self, w: &mut Writer<'_>) -> alloc::fmt::Result { + w.write_str(&chrono::Local::now().to_rfc3339()) + } +} + +/// Tag-type (indicating the "local" timezone) enabling static +/// dispatch to `chrono::Utc` functions. +#[derive(Debug)] +pub struct Utc; + +impl FormatTime for Utc { + fn format_time(&self, w: &mut Writer<'_>) -> alloc::fmt::Result { + w.write_str(&chrono::Utc::now().to_rfc3339()) + } +} + +#[cfg(test)] +mod tests { + use crate::fmt::format::Writer; + use crate::fmt::time::FormatTime; + + use super::LocalTime; + use super::Utc; + + #[test] + fn test_chrono_format_time_utc() { + let mut buf = String::new(); + let mut dst: Writer<'_> = Writer::new(&mut buf); + assert!(!FormatTime::format_time(&Utc, &mut dst).is_err()); + // e.g. `buf` contains "2023-08-18T19:05:08.662499+00:00" + } + + #[test] + fn test_chrono_format_time_local() { + let mut buf = String::new(); + let mut dst: Writer<'_> = Writer::new(&mut buf); + assert!(!FormatTime::format_time(&LocalTime, &mut dst).is_err()); + // e.g. `buf` contains "2023-08-18T14:59:08.662499-04:00". + } +} diff --git a/tracing-subscriber/src/fmt/time/mod.rs b/tracing-subscriber/src/fmt/time/mod.rs index 21d692bbb0..be450a9a98 100644 --- a/tracing-subscriber/src/fmt/time/mod.rs +++ b/tracing-subscriber/src/fmt/time/mod.rs @@ -15,6 +15,9 @@ pub use time_crate::UtcTime; #[cfg_attr(docsrs, doc(cfg(all(unsound_local_offset, feature = "local-time"))))] pub use time_crate::LocalTime; +/// [`Chrono`]-based implementation for time. +pub mod chrono_crate; + /// A type that can measure and format the current time. /// /// This trait is used by `Format` to include a timestamp with each `Event` when it is logged.