1//! Formatters for event timestamps.
2use crate::fmt::format::Writer;
3use std::fmt;
4use std::time::Instant;
5
6mod datetime;
7
8#[cfg(feature = "time")]
9mod time_crate;
10#[cfg(feature = "time")]
11#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
12pub use time_crate::UtcTime;
13
14#[cfg(feature = "local-time")]
15#[cfg_attr(docsrs, doc(cfg(all(unsound_local_offset, feature = "local-time"))))]
16pub use time_crate::LocalTime;
17
18#[cfg(feature = "time")]
19#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
20pub use time_crate::OffsetTime;
21
22/// A type that can measure and format the current time.
23///
24/// This trait is used by `Format` to include a timestamp with each `Event` when it is logged.
25///
26/// Notable default implementations of this trait are `SystemTime` and `()`. The former prints the
27/// current time as reported by `std::time::SystemTime`, and the latter does not print the current
28/// time at all. `FormatTime` is also automatically implemented for any function pointer with the
29/// appropriate signature.
30///
31/// The full list of provided implementations can be found in [`time`].
32///
33/// [`time`]: self
34pub trait FormatTime {
35 /// Measure and write out the current time.
36 ///
37 /// When `format_time` is called, implementors should get the current time using their desired
38 /// mechanism, and write it out to the given `fmt::Write`. Implementors must insert a trailing
39 /// space themselves if they wish to separate the time from subsequent log message text.
40 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result;
41}
42
43/// Returns a new `SystemTime` timestamp provider.
44///
45/// This can then be configured further to determine how timestamps should be
46/// configured.
47///
48/// This is equivalent to calling
49/// ```rust
50/// # fn timer() -> tracing_subscriber::fmt::time::SystemTime {
51/// tracing_subscriber::fmt::time::SystemTime::default()
52/// # }
53/// ```
54pub fn time() -> SystemTime {
55 SystemTime::default()
56}
57
58/// Returns a new `Uptime` timestamp provider.
59///
60/// With this timer, timestamps will be formatted with the amount of time
61/// elapsed since the timestamp provider was constructed.
62///
63/// This can then be configured further to determine how timestamps should be
64/// configured.
65///
66/// This is equivalent to calling
67/// ```rust
68/// # fn timer() -> tracing_subscriber::fmt::time::Uptime {
69/// tracing_subscriber::fmt::time::Uptime::default()
70/// # }
71/// ```
72pub fn uptime() -> Uptime {
73 Uptime::default()
74}
75
76impl<'a, F> FormatTime for &'a F
77where
78 F: FormatTime,
79{
80 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
81 (*self).format_time(w)
82 }
83}
84
85impl FormatTime for () {
86 fn format_time(&self, _: &mut Writer<'_>) -> fmt::Result {
87 Ok(())
88 }
89}
90
91impl FormatTime for fn(&mut Writer<'_>) -> fmt::Result {
92 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
93 (*self)(w)
94 }
95}
96
97/// Retrieve and print the current wall-clock time.
98#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
99pub struct SystemTime;
100
101/// Retrieve and print the relative elapsed wall-clock time since an epoch.
102///
103/// The `Default` implementation for `Uptime` makes the epoch the current time.
104#[derive(Debug, Clone, Copy, Eq, PartialEq)]
105pub struct Uptime {
106 epoch: Instant,
107}
108
109impl Default for Uptime {
110 fn default() -> Self {
111 Uptime {
112 epoch: Instant::now(),
113 }
114 }
115}
116
117impl From<Instant> for Uptime {
118 fn from(epoch: Instant) -> Self {
119 Uptime { epoch }
120 }
121}
122
123impl FormatTime for SystemTime {
124 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
125 write!(
126 w,
127 "{}",
128 datetime::DateTime::from(std::time::SystemTime::now())
129 )
130 }
131}
132
133impl FormatTime for Uptime {
134 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
135 let e: Duration = self.epoch.elapsed();
136 write!(w, "{:4}.{:09}s", e.as_secs(), e.subsec_nanos())
137 }
138}
139