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 |
34 | 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. |
43 | 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. |
52 | 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. |
61 | 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. |
70 | 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 { |
91 | 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&mut DebugTuple<'_, '_>.debug_tuple(name:"Timestamp" ) |
102 | .field(&TimestampValue(self)) |
103 | .finish() |
104 | } |
105 | } |
106 | |
107 | impl fmt::Display for Timestamp { |
108 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
109 | let formatter: fn(SystemTime) -> Rfc3339Timestamp = 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 | |