From d335c17cd5fd5f5e55ff83e29b881807b46afb6f Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Tue, 14 Dec 2021 14:49:55 +0000 Subject: [PATCH] Add options to use UTC timestamps This sidesteps issues users are having when using local times in conditions where the `time` crate cannot safely get the local time. Thanks to @uggla and @rye. https://github.com/borntyping/rust-simple_logger/issues/44 https://github.com/borntyping/rust-simple_logger/issues/43 --- Cargo.toml | 8 +- .../{timestamps.rs => timestamps_local.rs} | 2 +- examples/timestamps_utc.rs | 7 ++ src/lib.rs | 91 ++++++++++++++++--- 4 files changed, 94 insertions(+), 14 deletions(-) rename examples/{timestamps.rs => timestamps_local.rs} (58%) create mode 100644 examples/timestamps_utc.rs diff --git a/Cargo.toml b/Cargo.toml index 91d4a33..5f827bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "simple_logger" -version = "1.15.1" +version = "1.16.0" license = "MIT" authors = ["Sam Clements "] description = "A logger that prints all messages with a readable output format" @@ -33,5 +33,9 @@ name = "threads" required-features = ["threads"] [[example]] -name = "timestamps" +name = "timestamps_utc" +required-features = ["timestamps"] + +[[example]] +name = "timestamps_local" required-features = ["timestamps"] diff --git a/examples/timestamps.rs b/examples/timestamps_local.rs similarity index 58% rename from examples/timestamps.rs rename to examples/timestamps_local.rs index be3a1cc..fd8abe3 100644 --- a/examples/timestamps.rs +++ b/examples/timestamps_local.rs @@ -1,7 +1,7 @@ use simple_logger::SimpleLogger; fn main() { - SimpleLogger::new().with_timestamps(true).init().unwrap(); + SimpleLogger::new().with_utc_timestamps(true).init().unwrap(); log::warn!("This is an example message."); } diff --git a/examples/timestamps_utc.rs b/examples/timestamps_utc.rs new file mode 100644 index 0000000..fd8abe3 --- /dev/null +++ b/examples/timestamps_utc.rs @@ -0,0 +1,7 @@ +use simple_logger::SimpleLogger; + +fn main() { + SimpleLogger::new().with_utc_timestamps(true).init().unwrap(); + + log::warn!("This is an example message."); +} diff --git a/src/lib.rs b/src/lib.rs index 84673dd..3e80645 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,6 +69,12 @@ pub struct SimpleLogger { #[cfg(feature = "timestamps")] timestamps: bool, + /// Whether to show timestamps in UTC time (true) or local time (false) + /// + /// This field is only available if the `timestamps` feature is enabled. + #[cfg(feature = "timestamps")] + timestamps_utc: bool, + /// Whether to use color output or not. /// /// This field is only available if the `color` feature is enabled. @@ -99,6 +105,9 @@ impl SimpleLogger { #[cfg(feature = "timestamps")] timestamps: true, + #[cfg(feature = "timestamps")] + timestamps_utc: false, + #[cfg(feature = "colored")] colors: true, } @@ -236,11 +245,44 @@ impl SimpleLogger { /// Control whether timestamps are printed or not. /// + /// Timestamps will be displayed in the local timezone. + /// /// This method is only available if the `timestamps` feature is enabled. #[must_use = "You must call init() to begin logging"] #[cfg(feature = "timestamps")] + #[deprecated( + since = "1.16.0", + note = "Use [`with_local_timestamps`] or [`with_utc_timestamps`] instead. Will be removed in version 2.0.0." + )] pub fn with_timestamps(mut self, timestamps: bool) -> SimpleLogger { self.timestamps = timestamps; + self.timestamps_utc = false; + self + } + + /// Control whether timestamps are printed or not. + /// + /// Timestamps will be displayed in the local timezone. + /// + /// This method is only available if the `timestamps` feature is enabled. + #[must_use = "You must call init() to begin logging"] + #[cfg(feature = "timestamps")] + pub fn with_local_timestamps(mut self, timestamps: bool) -> SimpleLogger { + self.timestamps = timestamps; + self.timestamps_utc = false; + self + } + + /// Control whether timestamps are printed or not. + /// + /// Timestamps will be displayed in UTC. + /// + /// This method is only available if the `timestamps` feature is enabled. + #[must_use = "You must call init() to begin logging"] + #[cfg(feature = "timestamps")] + pub fn with_utc_timestamps(mut self, timestamps: bool) -> SimpleLogger { + self.timestamps = timestamps; + self.timestamps_utc = true; self } @@ -357,14 +399,18 @@ impl Log for SimpleLogger { let timestamp = { #[cfg(feature = "timestamps")] if self.timestamps { - format!("{} ", OffsetDateTime::now_local().expect(concat!( - "Could not determine the UTC offset on this system. ", - "Possible causes are that the time crate does not implement \"local_offset_at\" ", - "on your system, or that you are running in a multi-threaded environment and ", - "the time crate is returning \"None\" from \"local_offset_at\" to avoid unsafe ", - "behaviour. See the time crate's documentation for more information. ", - "(https://time-rs.github.io/internal-api/time/index.html#feature-flags)" - )).format(&TIMESTAMP_FORMAT).unwrap()) + if self.timestamps_utc { + format!("{} ", OffsetDateTime::now_utc()) + } else { + format!("{} ", OffsetDateTime::now_local().expect(concat!( + "Could not determine the UTC offset on this system. ", + "Possible causes are that the time crate does not implement \"local_offset_at\" ", + "on your system, or that you are running in a multi-threaded environment and ", + "the time crate is returning \"None\" from \"local_offset_at\" to avoid unsafe ", + "behaviour. See the time crate's documentation for more information. ", + "(https://time-rs.github.io/internal-api/time/index.html#feature-flags)" + )).format(&TIMESTAMP_FORMAT).unwrap()) + } } else { "".to_string() } @@ -496,12 +542,35 @@ mod test { #[test] #[cfg(feature = "timestamps")] - fn test_with_timestamps() { - let mut builder = SimpleLogger::new(); + fn test_timestamps_defaults() { + let builder = SimpleLogger::new(); assert!(builder.timestamps == true); + assert!(builder.timestamps_utc == false); + } - builder = builder.with_timestamps(false); + #[test] + #[cfg(feature = "timestamps")] + #[allow(deprecated)] + fn test_with_timestamps() { + let builder = SimpleLogger::new().with_timestamps(false); assert!(builder.timestamps == false); + assert!(builder.timestamps_utc == false); + } + + #[test] + #[cfg(feature = "timestamps")] + fn test_with_utc_timestamps() { + let builder = SimpleLogger::new().with_utc_timestamps(true); + assert!(builder.timestamps == true); + assert!(builder.timestamps_utc == true); + } + + #[test] + #[cfg(feature = "timestamps")] + fn test_with_local_timestamps() { + let builder = SimpleLogger::new().with_local_timestamps(true); + assert!(builder.timestamps == true); + assert!(builder.timestamps_utc == false); } #[test]