From 36f984ebb95d8519fc32a55aae3772eadd5f1d68 Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Wed, 19 Jan 2022 17:35:31 +0000 Subject: [PATCH 1/4] Make UTC the default timestamps option, and change the output format to include the timezone This works around the issue of potentially silently changing the timezone used in logfiles (and not leaving the user any way to notice the change) by changing the timezone format used from one that is timezone agnostic to one that includes the timezone. Since it's alreday changing from one that perfectly matches Supervisord, this uses the well known RFC 3339 format that implements ISO 8601 (and happens to currently be the only format provided by the `time` crate that I don't have to implement myself). --- Cargo.toml | 2 +- README.md | 9 +++++++-- src/lib.rs | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5f827bd..ab2aa85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "simple_logger" -version = "1.16.0" +version = "2.0.0" license = "MIT" authors = ["Sam Clements "] description = "A logger that prints all messages with a readable output format" diff --git a/README.md b/README.md index 1d466c0..5b02948 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,17 @@ A logger that prints all messages with a readable output format. -The output format is based on the format used by [Supervisord](http://supervisord.org/). +The output format is based on the format used by [Supervisord](http://supervisord.org/), with timestamps in [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339) format. * [Source on GitHub](https://github.com/borntyping/rust-simple_logger) * [Packages on Crates.io](https://crates.io/crates/simple_logger) * [Documentation on Docs.rs](https://docs.rs/simple_logger) +Breaking changes +---------------- + +- **Version 2.0.0 changes the default from displaying timestamps in the local timezone to displaying timestamps in UTC.** See issue [#52](https://github.com/borntyping/rust-simple_logger/issues/52) for more information. + Usage ----- @@ -24,7 +29,7 @@ fn main() { This outputs: ``` -2015-02-24 01:05:20 WARN [logging_example] This is an example message. +2022-01-19T17:27:07.013874956Z WARN [logging_example] This is an example message. ``` You can run the above example with: diff --git a/src/lib.rs b/src/lib.rs index 027c65d..7a841dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,12 +35,7 @@ use colored::*; use log::{Level, LevelFilter, Log, Metadata, Record, SetLoggerError}; use std::collections::HashMap; #[cfg(feature = "timestamps")] -use time::{format_description::FormatItem, OffsetDateTime}; - -#[cfg(feature = "timestamps")] -const TIMESTAMP_FORMAT: &[FormatItem] = time::macros::format_description!( - "[year]-[month]-[day] [hour]:[minute]:[second],[subsecond digits:3]" -); +use time::{format_description::well_known::Rfc3339, OffsetDateTime, UtcOffset}; #[cfg(feature = "timestamps")] #[derive(PartialEq)] @@ -48,6 +43,7 @@ enum Timestamps { None, Local, Utc, + UtcOffset(UtcOffset), } /// Implements [`Log`] and a set of simple builder methods for configuration. @@ -105,7 +101,7 @@ impl SimpleLogger { threads: false, #[cfg(feature = "timestamps")] - timestamps: Timestamps::Local, + timestamps: Timestamps::Utc, #[cfg(feature = "colored")] colors: true, @@ -292,6 +288,16 @@ impl SimpleLogger { self } + /// Display timestamps using a static UTC offset. + /// + /// 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_offset(mut self, offset: UtcOffset) -> SimpleLogger { + self.timestamps = Timestamps::UtcOffset(offset); + self + } + /// Control whether messages are colored or not. /// /// This method is only available if the `colored` feature is enabled. @@ -408,13 +414,15 @@ impl Log for SimpleLogger { Timestamps::None => "".to_string(), Timestamps::Local => format!("{} ", OffsetDateTime::now_local().expect(concat!( "Could not determine the UTC offset on this system. ", + "Consider displaying UTC time instead. ", "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()), - Timestamps::Utc => format!("{} ", OffsetDateTime::now_utc().format(&TIMESTAMP_FORMAT).unwrap()), + )).format(&Rfc3339).unwrap()), + Timestamps::Utc => format!("{} ", OffsetDateTime::now_utc().format(&Rfc3339).unwrap()), + Timestamps::UtcOffset(offset) => format!("{} ", OffsetDateTime::now_utc().to_offset(offset).format(&Rfc3339).unwrap()), } #[cfg(not(feature = "timestamps"))] @@ -478,6 +486,17 @@ pub fn init() -> Result<(), SetLoggerError> { SimpleLogger::new().init() } +/// Initialise the logger with it's default configuration. +/// +/// Log messages will not be filtered. +/// The `RUST_LOG` environment variable is not used. +/// +/// This function is only available if the `timestamps` feature is enabled. +#[cfg(feature = "timestamps")] +pub fn init_utc() -> Result<(), SetLoggerError> { + SimpleLogger::new().with_utc_timestamps().init() +} + /// Initialise the logger with the `RUST_LOG` environment variable. /// /// Log messages will be filtered based on the `RUST_LOG` environment variable. @@ -546,7 +565,7 @@ mod test { #[cfg(feature = "timestamps")] fn test_timestamps_defaults() { let builder = SimpleLogger::new(); - assert!(builder.timestamps == Timestamps::Local); + assert!(builder.timestamps == Timestamps::Utc); } #[test] From 63519f5d550eb7a28a7b60480ba045690c9d8c5b Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Wed, 19 Jan 2022 17:46:05 +0000 Subject: [PATCH 2/4] Add a timestamp option using a static UTC offset Closes https://github.com/borntyping/rust-simple_logger/issues/50 --- examples/timestamps_utc_offset.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 examples/timestamps_utc_offset.rs diff --git a/examples/timestamps_utc_offset.rs b/examples/timestamps_utc_offset.rs new file mode 100644 index 0000000..b70ec01 --- /dev/null +++ b/examples/timestamps_utc_offset.rs @@ -0,0 +1,12 @@ +use simple_logger::SimpleLogger; +use time::UtcOffset; + +fn main() { + SimpleLogger::new() + .with_utc_offset(UtcOffset::from_hms(14, 0, 0).unwrap()) + .init() + .unwrap(); + + log::warn!("This is an example message using a static UTC offset."); + log::info!("Daylight savings or other timezone changes will not be respected."); +} From 8dad7548e1bbafe618b4f1548185402cd5a018d2 Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Wed, 19 Jan 2022 18:03:14 +0000 Subject: [PATCH 3/4] Add an example for Timezones::None --- examples/timestamps_none.rs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 examples/timestamps_none.rs diff --git a/examples/timestamps_none.rs b/examples/timestamps_none.rs new file mode 100644 index 0000000..9f7b98d --- /dev/null +++ b/examples/timestamps_none.rs @@ -0,0 +1,7 @@ +use simple_logger::SimpleLogger; + +fn main() { + SimpleLogger::new().without_timestamps().init().unwrap(); + + log::warn!("This is an example message."); +} From ee4c93d0e5514a1869c5810d0329e72664f3b29a Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Wed, 19 Jan 2022 18:13:07 +0000 Subject: [PATCH 4/4] Set required-features for examples --- Cargo.toml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ab2aa85..7f6cbfb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,10 +32,18 @@ required-features = ["colors"] name = "threads" required-features = ["threads"] +[[example]] +name = "timestamps_local" +required-features = ["timestamps"] + +[[example]] +name = "timestamps_none" +required-features = ["timestamps"] + [[example]] name = "timestamps_utc" required-features = ["timestamps"] [[example]] -name = "timestamps_local" +name = "timestamps_utc_offset" required-features = ["timestamps"]