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