summaryrefslogtreecommitdiffstats
path: root/vendor/tracing-subscriber/src/fmt/time/time_crate.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/tracing-subscriber/src/fmt/time/time_crate.rs')
-rw-r--r--vendor/tracing-subscriber/src/fmt/time/time_crate.rs470
1 files changed, 470 insertions, 0 deletions
diff --git a/vendor/tracing-subscriber/src/fmt/time/time_crate.rs b/vendor/tracing-subscriber/src/fmt/time/time_crate.rs
new file mode 100644
index 000000000..60d57fd0b
--- /dev/null
+++ b/vendor/tracing-subscriber/src/fmt/time/time_crate.rs
@@ -0,0 +1,470 @@
+use crate::fmt::{format::Writer, time::FormatTime, writer::WriteAdaptor};
+use std::fmt;
+use time::{format_description::well_known, formatting::Formattable, OffsetDateTime, UtcOffset};
+
+/// Formats the current [local time] using a [formatter] from the [`time` crate].
+///
+/// To format the current [UTC time] instead, use the [`UtcTime`] type.
+///
+/// <div class="example-wrap" style="display:inline-block">
+/// <pre class="compile_fail" style="white-space:normal;font:inherit;">
+/// <strong>Warning</strong>: The <a href = "https://docs.rs/time/0.3/time/"><code>time</code>
+/// crate</a> must be compiled with <code>--cfg unsound_local_offset</code> in order to use
+/// local timestamps. When this cfg is not enabled, local timestamps cannot be recorded, and
+/// events will be logged without timestamps.
+///
+/// Alternatively, [`OffsetTime`] can log with a local offset if it is initialized early.
+///
+/// See the <a href="https://docs.rs/time/0.3.4/time/#feature-flags"><code>time</code>
+/// documentation</a> for more details.
+/// </pre></div>
+///
+/// [local time]: time::OffsetDateTime::now_local
+/// [UTC time]: time::OffsetDateTime::now_utc
+/// [formatter]: time::formatting::Formattable
+/// [`time` crate]: time
+#[derive(Clone, Debug)]
+#[cfg_attr(
+ docsrs,
+ doc(cfg(all(unsound_local_offset, feature = "time", feature = "local-time")))
+)]
+#[cfg(feature = "local-time")]
+pub struct LocalTime<F> {
+ format: F,
+}
+
+/// Formats the current [UTC time] using a [formatter] from the [`time` crate].
+///
+/// To format the current [local time] instead, use the [`LocalTime`] type.
+///
+/// [local time]: time::OffsetDateTime::now_local
+/// [UTC time]: time::OffsetDateTime::now_utc
+/// [formatter]: time::formatting::Formattable
+/// [`time` crate]: time
+#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
+#[derive(Clone, Debug)]
+pub struct UtcTime<F> {
+ format: F,
+}
+
+/// Formats the current time using a fixed offset and a [formatter] from the [`time` crate].
+///
+/// This is typically used as an alternative to [`LocalTime`]. `LocalTime` determines the offset
+/// every time it formats a message, which may be unsound or fail. With `OffsetTime`, the offset is
+/// determined once. This makes it possible to do so while the program is still single-threaded and
+/// handle any errors. However, this also means the offset cannot change while the program is
+/// running (the offset will not change across DST changes).
+///
+/// [formatter]: time::formatting::Formattable
+/// [`time` crate]: time
+#[derive(Clone, Debug)]
+#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
+pub struct OffsetTime<F> {
+ offset: time::UtcOffset,
+ format: F,
+}
+
+// === impl LocalTime ===
+
+#[cfg(feature = "local-time")]
+impl LocalTime<well_known::Rfc3339> {
+ /// Returns a formatter that formats the current [local time] in the
+ /// [RFC 3339] format (a subset of the [ISO 8601] timestamp format).
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time};
+ ///
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(time::LocalTime::rfc_3339());
+ /// # drop(collector);
+ /// ```
+ ///
+ /// [local time]: time::OffsetDateTime::now_local
+ /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339
+ /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601
+ pub fn rfc_3339() -> Self {
+ Self::new(well_known::Rfc3339)
+ }
+}
+
+#[cfg(feature = "local-time")]
+impl<F: Formattable> LocalTime<F> {
+ /// Returns a formatter that formats the current [local time] using the
+ /// [`time` crate] with the provided provided format. The format may be any
+ /// type that implements the [`Formattable`] trait.
+ ///
+ ///
+ /// <div class="example-wrap" style="display:inline-block">
+ /// <pre class="compile_fail" style="white-space:normal;font:inherit;">
+ /// <strong>Warning</strong>: The <a href = "https://docs.rs/time/0.3/time/">
+ /// <code>time</code> crate</a> must be compiled with <code>--cfg
+ /// unsound_local_offset</code> in order to use local timestamps. When this
+ /// cfg is not enabled, local timestamps cannot be recorded, and
+ /// events will be logged without timestamps.
+ ///
+ /// See the <a href="https://docs.rs/time/0.3.4/time/#feature-flags">
+ /// <code>time</code> documentation</a> for more details.
+ /// </pre></div>
+ ///
+ /// Typically, the format will be a format description string, or one of the
+ /// `time` crate's [well-known formats].
+ ///
+ /// If the format description is statically known, then the
+ /// [`format_description!`] macro should be used. This is identical to the
+ /// [`time::format_description::parse`] method, but runs at compile-time,
+ /// throwing an error if the format description is invalid. If the desired format
+ /// is not known statically (e.g., a user is providing a format string), then the
+ /// [`time::format_description::parse`] method should be used. Note that this
+ /// method is fallible.
+ ///
+ /// See the [`time` book] for details on the format description syntax.
+ ///
+ /// # Examples
+ ///
+ /// Using the [`format_description!`] macro:
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time::LocalTime};
+ /// use time::macros::format_description;
+ ///
+ /// let timer = LocalTime::new(format_description!("[hour]:[minute]:[second]"));
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(timer);
+ /// # drop(collector);
+ /// ```
+ ///
+ /// Using [`time::format_description::parse`]:
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time::LocalTime};
+ ///
+ /// let time_format = time::format_description::parse("[hour]:[minute]:[second]")
+ /// .expect("format string should be valid!");
+ /// let timer = LocalTime::new(time_format);
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(timer);
+ /// # drop(collector);
+ /// ```
+ ///
+ /// Using the [`format_description!`] macro requires enabling the `time`
+ /// crate's "macros" feature flag.
+ ///
+ /// Using a [well-known format][well-known formats] (this is equivalent to
+ /// [`LocalTime::rfc_3339`]):
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time::LocalTime};
+ ///
+ /// let timer = LocalTime::new(time::format_description::well_known::Rfc3339);
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(timer);
+ /// # drop(collector);
+ /// ```
+ ///
+ /// [local time]: time::OffsetDateTime::now_local()
+ /// [`time` crate]: time
+ /// [`Formattable`]: time::formatting::Formattable
+ /// [well-known formats]: time::format_description::well_known
+ /// [`format_description!`]: time::macros::format_description!
+ /// [`time::format_description::parse`]: time::format_description::parse()
+ /// [`time` book]: https://time-rs.github.io/book/api/format-description.html
+ pub fn new(format: F) -> Self {
+ Self { format }
+ }
+}
+
+#[cfg(feature = "local-time")]
+impl<F> FormatTime for LocalTime<F>
+where
+ F: Formattable,
+{
+ fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
+ let now = OffsetDateTime::now_local().map_err(|_| fmt::Error)?;
+ format_datetime(now, w, &self.format)
+ }
+}
+
+#[cfg(feature = "local-time")]
+impl<F> Default for LocalTime<F>
+where
+ F: Formattable + Default,
+{
+ fn default() -> Self {
+ Self::new(F::default())
+ }
+}
+
+// === impl UtcTime ===
+
+impl UtcTime<well_known::Rfc3339> {
+ /// Returns a formatter that formats the current [UTC time] in the
+ /// [RFC 3339] format, which is a subset of the [ISO 8601] timestamp format.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time};
+ ///
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(time::UtcTime::rfc_3339());
+ /// # drop(collector);
+ /// ```
+ ///
+ /// [local time]: time::OffsetDateTime::now_utc
+ /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339
+ /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601
+ pub fn rfc_3339() -> Self {
+ Self::new(well_known::Rfc3339)
+ }
+}
+
+impl<F: Formattable> UtcTime<F> {
+ /// Returns a formatter that formats the current [UTC time] using the
+ /// [`time` crate], with the provided provided format. The format may be any
+ /// type that implements the [`Formattable`] trait.
+ ///
+ /// Typically, the format will be a format description string, or one of the
+ /// `time` crate's [well-known formats].
+ ///
+ /// If the format description is statically known, then the
+ /// [`format_description!`] macro should be used. This is identical to the
+ /// [`time::format_description::parse`] method, but runs at compile-time,
+ /// failing an error if the format description is invalid. If the desired format
+ /// is not known statically (e.g., a user is providing a format string), then the
+ /// [`time::format_description::parse`] method should be used. Note that this
+ /// method is fallible.
+ ///
+ /// See the [`time` book] for details on the format description syntax.
+ ///
+ /// # Examples
+ ///
+ /// Using the [`format_description!`] macro:
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time::UtcTime};
+ /// use time::macros::format_description;
+ ///
+ /// let timer = UtcTime::new(format_description!("[hour]:[minute]:[second]"));
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(timer);
+ /// # drop(collector);
+ /// ```
+ ///
+ /// Using the [`format_description!`] macro requires enabling the `time`
+ /// crate's "macros" feature flag.
+ ///
+ /// Using [`time::format_description::parse`]:
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time::UtcTime};
+ ///
+ /// let time_format = time::format_description::parse("[hour]:[minute]:[second]")
+ /// .expect("format string should be valid!");
+ /// let timer = UtcTime::new(time_format);
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(timer);
+ /// # drop(collector);
+ /// ```
+ ///
+ /// Using a [well-known format][well-known formats] (this is equivalent to
+ /// [`UtcTime::rfc_3339`]):
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time::UtcTime};
+ ///
+ /// let timer = UtcTime::new(time::format_description::well_known::Rfc3339);
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(timer);
+ /// # drop(collector);
+ /// ```
+ ///
+ /// [UTC time]: time::OffsetDateTime::now_utc()
+ /// [`time` crate]: time
+ /// [`Formattable`]: time::formatting::Formattable
+ /// [well-known formats]: time::format_description::well_known
+ /// [`format_description!`]: time::macros::format_description!
+ /// [`time::format_description::parse`]: time::format_description::parse
+ /// [`time` book]: https://time-rs.github.io/book/api/format-description.html
+ pub fn new(format: F) -> Self {
+ Self { format }
+ }
+}
+
+impl<F> FormatTime for UtcTime<F>
+where
+ F: Formattable,
+{
+ fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
+ format_datetime(OffsetDateTime::now_utc(), w, &self.format)
+ }
+}
+
+impl<F> Default for UtcTime<F>
+where
+ F: Formattable + Default,
+{
+ fn default() -> Self {
+ Self::new(F::default())
+ }
+}
+
+// === impl OffsetTime ===
+
+#[cfg(feature = "local-time")]
+impl OffsetTime<well_known::Rfc3339> {
+ /// Returns a formatter that formats the current time using the [local time offset] in the [RFC
+ /// 3339] format (a subset of the [ISO 8601] timestamp format).
+ ///
+ /// Returns an error if the local time offset cannot be determined. This typically occurs in
+ /// multithreaded programs. To avoid this problem, initialize `OffsetTime` before forking
+ /// threads. When using Tokio, this means initializing `OffsetTime` before the Tokio runtime.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time};
+ ///
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(time::OffsetTime::local_rfc_3339().expect("could not get local offset!"));
+ /// # drop(collector);
+ /// ```
+ ///
+ /// Using `OffsetTime` with Tokio:
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::time::OffsetTime;
+ ///
+ /// #[tokio::main]
+ /// async fn run() {
+ /// tracing::info!("runtime initialized");
+ ///
+ /// // At this point the Tokio runtime is initialized, and we can use both Tokio and Tracing
+ /// // normally.
+ /// }
+ ///
+ /// fn main() {
+ /// // Because we need to get the local offset before Tokio spawns any threads, our `main`
+ /// // function cannot use `tokio::main`.
+ /// tracing_subscriber::fmt()
+ /// .with_timer(OffsetTime::local_rfc_3339().expect("could not get local time offset"))
+ /// .init();
+ ///
+ /// // Even though `run` is written as an `async fn`, because we used `tokio::main` on it
+ /// // we can call it as a synchronous function.
+ /// run();
+ /// }
+ /// ```
+ ///
+ /// [local time offset]: time::UtcOffset::current_local_offset
+ /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339
+ /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601
+ pub fn local_rfc_3339() -> Result<Self, time::error::IndeterminateOffset> {
+ Ok(Self::new(
+ UtcOffset::current_local_offset()?,
+ well_known::Rfc3339,
+ ))
+ }
+}
+
+impl<F: time::formatting::Formattable> OffsetTime<F> {
+ /// Returns a formatter that formats the current time using the [`time` crate] with the provided
+ /// provided format and [timezone offset]. The format may be any type that implements the
+ /// [`Formattable`] trait.
+ ///
+ ///
+ /// Typically, the offset will be the [local offset], and format will be a format description
+ /// string, or one of the `time` crate's [well-known formats].
+ ///
+ /// If the format description is statically known, then the
+ /// [`format_description!`] macro should be used. This is identical to the
+ /// [`time::format_description::parse`] method, but runs at compile-time,
+ /// throwing an error if the format description is invalid. If the desired format
+ /// is not known statically (e.g., a user is providing a format string), then the
+ /// [`time::format_description::parse`] method should be used. Note that this
+ /// method is fallible.
+ ///
+ /// See the [`time` book] for details on the format description syntax.
+ ///
+ /// # Examples
+ ///
+ /// Using the [`format_description!`] macro:
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time::OffsetTime};
+ /// use time::macros::format_description;
+ /// use time::UtcOffset;
+ ///
+ /// let offset = UtcOffset::current_local_offset().expect("should get local offset!");
+ /// let timer = OffsetTime::new(offset, format_description!("[hour]:[minute]:[second]"));
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(timer);
+ /// # drop(collector);
+ /// ```
+ ///
+ /// Using [`time::format_description::parse`]:
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time::OffsetTime};
+ /// use time::UtcOffset;
+ ///
+ /// let offset = UtcOffset::current_local_offset().expect("should get local offset!");
+ /// let time_format = time::format_description::parse("[hour]:[minute]:[second]")
+ /// .expect("format string should be valid!");
+ /// let timer = OffsetTime::new(offset, time_format);
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(timer);
+ /// # drop(collector);
+ /// ```
+ ///
+ /// Using the [`format_description!`] macro requires enabling the `time`
+ /// crate's "macros" feature flag.
+ ///
+ /// Using a [well-known format][well-known formats] (this is equivalent to
+ /// [`OffsetTime::local_rfc_3339`]):
+ ///
+ /// ```
+ /// use tracing_subscriber::fmt::{self, time::OffsetTime};
+ /// use time::UtcOffset;
+ ///
+ /// let offset = UtcOffset::current_local_offset().expect("should get local offset!");
+ /// let timer = OffsetTime::new(offset, time::format_description::well_known::Rfc3339);
+ /// let collector = tracing_subscriber::fmt()
+ /// .with_timer(timer);
+ /// # drop(collector);
+ /// ```
+ ///
+ /// [`time` crate]: time
+ /// [timezone offset]: time::UtcOffset
+ /// [`Formattable`]: time::formatting::Formattable
+ /// [local offset]: time::UtcOffset::current_local_offset()
+ /// [well-known formats]: time::format_description::well_known
+ /// [`format_description!`]: time::macros::format_description
+ /// [`time::format_description::parse`]: time::format_description::parse
+ /// [`time` book]: https://time-rs.github.io/book/api/format-description.html
+ pub fn new(offset: time::UtcOffset, format: F) -> Self {
+ Self { offset, format }
+ }
+}
+
+impl<F> FormatTime for OffsetTime<F>
+where
+ F: time::formatting::Formattable,
+{
+ fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
+ let now = OffsetDateTime::now_utc().to_offset(self.offset);
+ format_datetime(now, w, &self.format)
+ }
+}
+
+fn format_datetime(
+ now: OffsetDateTime,
+ into: &mut Writer<'_>,
+ fmt: &impl Formattable,
+) -> fmt::Result {
+ let mut into = WriteAdaptor::new(into);
+ now.format_into(&mut into, fmt)
+ .map_err(|_| fmt::Error)
+ .map(|_| ())
+}