1 use std::fmt; 2 use std::time::SystemTime; 3 4 use humantime::{ 5 format_rfc3339_micros, format_rfc3339_millis, format_rfc3339_nanos, format_rfc3339_seconds, 6 }; 7 8 use crate::fmt::{Formatter, TimestampPrecision}; 9 10 pub(in crate::fmt) mod glob { 11 pub use super::*; 12 } 13 14 impl Formatter { 15 /// Get a [`Timestamp`] for the current date and time in UTC. 16 /// 17 /// # Examples 18 /// 19 /// Include the current timestamp with the log record: 20 /// 21 /// ``` 22 /// use std::io::Write; 23 /// 24 /// let mut builder = env_logger::Builder::new(); 25 /// 26 /// builder.format(|buf, record| { 27 /// let ts = buf.timestamp(); 28 /// 29 /// writeln!(buf, "{}: {}: {}", ts, record.level(), record.args()) 30 /// }); 31 /// ``` 32 /// 33 /// [`Timestamp`]: struct.Timestamp.html timestamp(&self) -> Timestamp34 pub fn timestamp(&self) -> Timestamp { 35 Timestamp { 36 time: SystemTime::now(), 37 precision: TimestampPrecision::Seconds, 38 } 39 } 40 41 /// Get a [`Timestamp`] for the current date and time in UTC with full 42 /// second precision. timestamp_seconds(&self) -> Timestamp43 pub fn timestamp_seconds(&self) -> Timestamp { 44 Timestamp { 45 time: SystemTime::now(), 46 precision: TimestampPrecision::Seconds, 47 } 48 } 49 50 /// Get a [`Timestamp`] for the current date and time in UTC with 51 /// millisecond precision. timestamp_millis(&self) -> Timestamp52 pub fn timestamp_millis(&self) -> Timestamp { 53 Timestamp { 54 time: SystemTime::now(), 55 precision: TimestampPrecision::Millis, 56 } 57 } 58 59 /// Get a [`Timestamp`] for the current date and time in UTC with 60 /// microsecond precision. timestamp_micros(&self) -> Timestamp61 pub fn timestamp_micros(&self) -> Timestamp { 62 Timestamp { 63 time: SystemTime::now(), 64 precision: TimestampPrecision::Micros, 65 } 66 } 67 68 /// Get a [`Timestamp`] for the current date and time in UTC with 69 /// nanosecond precision. timestamp_nanos(&self) -> Timestamp70 pub fn timestamp_nanos(&self) -> Timestamp { 71 Timestamp { 72 time: SystemTime::now(), 73 precision: TimestampPrecision::Nanos, 74 } 75 } 76 } 77 78 /// An [RFC3339] formatted timestamp. 79 /// 80 /// The timestamp implements [`Display`] and can be written to a [`Formatter`]. 81 /// 82 /// [RFC3339]: https://www.ietf.org/rfc/rfc3339.txt 83 /// [`Display`]: https://doc.rust-lang.org/stable/std/fmt/trait.Display.html 84 /// [`Formatter`]: struct.Formatter.html 85 pub struct Timestamp { 86 time: SystemTime, 87 precision: TimestampPrecision, 88 } 89 90 impl fmt::Debug for Timestamp { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 92 /// A `Debug` wrapper for `Timestamp` that uses the `Display` implementation. 93 struct TimestampValue<'a>(&'a Timestamp); 94 95 impl<'a> fmt::Debug for TimestampValue<'a> { 96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 97 fmt::Display::fmt(&self.0, f) 98 } 99 } 100 101 f.debug_tuple("Timestamp") 102 .field(&TimestampValue(self)) 103 .finish() 104 } 105 } 106 107 impl fmt::Display for Timestamp { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result108 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 109 let formatter = match self.precision { 110 TimestampPrecision::Seconds => format_rfc3339_seconds, 111 TimestampPrecision::Millis => format_rfc3339_millis, 112 TimestampPrecision::Micros => format_rfc3339_micros, 113 TimestampPrecision::Nanos => format_rfc3339_nanos, 114 }; 115 116 formatter(self.time).fmt(f) 117 } 118 } 119