Skip to content

Commit

Permalink
Merge pull request #68 from hrmsk66/hrmsk66/higher-precision-with-dec…
Browse files Browse the repository at this point in the history
…imals

Add Configuration for Higher Time Precision with Decimals
  • Loading branch information
oli-obk committed Sep 27, 2023
2 parents 8aa51bc + 4c66dca commit 5b5ebb6
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 31 deletions.
10 changes: 10 additions & 0 deletions src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ pub struct Config {
pub deferred_spans: bool,
/// Print a label of the span mode (open/close etc).
pub span_modes: bool,
/// Whether to print the time with higher precision.
pub higher_precision: bool,
}

impl Config {
Expand Down Expand Up @@ -138,6 +140,13 @@ impl Config {
}
}

pub fn with_higher_precision(self, higher_precision: bool) -> Self {
Self {
higher_precision,
..self
}
}

pub(crate) fn prefix(&self) -> String {
let mut buf = String::new();
if self.render_thread_ids {
Expand Down Expand Up @@ -177,6 +186,7 @@ impl Default for Config {
bracketed_fields: false,
deferred_spans: false,
span_modes: false,
higher_precision: false,
}
}
}
Expand Down
106 changes: 75 additions & 31 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,14 @@ where
}
}

/// Whether to print the time with higher precision.
pub fn with_higher_precision(self, higher_precision: bool) -> Self {
Self {
config: self.config.with_higher_precision(higher_precision),
..self
}
}

fn styled(&self, style: Style, text: impl AsRef<str>) -> String {
if self.config.ansi {
style.paint(text.as_ref()).to_string()
Expand Down Expand Up @@ -397,6 +405,70 @@ where
let writer = self.make_writer.make_writer();
bufs.flush_current_buf(writer)
}

fn get_timestamp<S>(&self, span: SpanRef<S>) -> Option<String>
where
S: Subscriber + for<'span> LookupSpan<'span>,
{
let ext = span.extensions();
let data = ext
.get::<Data>()
.expect("Data cannot be found in extensions");

if self.config.higher_precision {
Some(self.format_timestamp_with_decimals(data.start))
} else {
Some(self.format_timestamp(data.start))
}
}

fn format_timestamp(&self, start: std::time::Instant) -> String {
let elapsed = start.elapsed();
let millis = elapsed.as_millis();
let secs = elapsed.as_secs();

// Convert elapsed time to appropriate units: ms, s, or m.
// - Less than 1s : use ms
// - Less than 1m : use s
// - 1m and above : use m
let (n, unit) = if millis < 1000 {
(millis as _, "ms")
} else if secs < 60 {
(secs, "s ")
} else {
(secs / 60, "m ")
};

let timestamp = format!("{n:>3}");
self.style_timestamp(timestamp, unit)
}

fn format_timestamp_with_decimals(&self, start: std::time::Instant) -> String {
let secs = start.elapsed().as_secs_f64();

// Convert elapsed time to appropriate units: μs, ms, or s.
// - Less than 1ms: use μs
// - Less than 1s : use ms
// - 1s and above : use s
let (n, unit) = if secs < 0.001 {
(secs * 1_000_000.0, "μs")
} else if secs < 1.0 {
(secs * 1_000.0, "ms")
} else {
(secs, "s ")
};

let timestamp = format!(" {n:.2}");
self.style_timestamp(timestamp, unit)
}

fn style_timestamp(&self, timestamp: String, unit: &str) -> String {
format!(
"{timestamp}{unit} ",
timestamp = self.styled(Style::new().dimmed(), timestamp),
unit = self.styled(Style::new().dimmed(), unit),
)
}
}

impl<S, W, FT> Layer<S> for HierarchicalLayer<W, FT>
Expand Down Expand Up @@ -475,38 +547,10 @@ where

// check if this event occurred in the context of a span.
// if it has, get the start time of this span.
let start = match span {
Some(span) => {
// if the event is in a span, get the span's starting point.
let ext = span.extensions();
let data = ext
.get::<Data>()
.expect("Data cannot be found in extensions");

Some(data.start)
if let Some(span) = span {
if let Some(timestamp) = self.get_timestamp(span) {
write!(&mut event_buf, "{}", timestamp).expect("Unable to write to buffer");
}
None => None,
};

if let Some(start) = start {
let elapsed = start.elapsed();
let millis = elapsed.as_millis();
let secs = elapsed.as_secs();
let (n, unit) = if millis < 1000 {
(millis as _, "ms")
} else if secs < 60 {
(secs, "s ")
} else {
(secs / 60, "m ")
};
let n = format!("{n:>3}");
write!(
&mut event_buf,
"{timestamp}{unit} ",
timestamp = self.styled(Style::new().dimmed(), n),
unit = self.styled(Style::new().dimmed(), unit),
)
.expect("Unable to write to buffer");
}

#[cfg(feature = "tracing-log")]
Expand Down

0 comments on commit 5b5ebb6

Please sign in to comment.