Skip to content

Commit 5b5ebb6

Browse files
authored
Merge pull request #68 from hrmsk66/hrmsk66/higher-precision-with-decimals
Add Configuration for Higher Time Precision with Decimals
2 parents 8aa51bc + 4c66dca commit 5b5ebb6

File tree

2 files changed

+85
-31
lines changed

2 files changed

+85
-31
lines changed

src/format.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ pub struct Config {
6060
pub deferred_spans: bool,
6161
/// Print a label of the span mode (open/close etc).
6262
pub span_modes: bool,
63+
/// Whether to print the time with higher precision.
64+
pub higher_precision: bool,
6365
}
6466

6567
impl Config {
@@ -138,6 +140,13 @@ impl Config {
138140
}
139141
}
140142

143+
pub fn with_higher_precision(self, higher_precision: bool) -> Self {
144+
Self {
145+
higher_precision,
146+
..self
147+
}
148+
}
149+
141150
pub(crate) fn prefix(&self) -> String {
142151
let mut buf = String::new();
143152
if self.render_thread_ids {
@@ -177,6 +186,7 @@ impl Default for Config {
177186
bracketed_fields: false,
178187
deferred_spans: false,
179188
span_modes: false,
189+
higher_precision: false,
180190
}
181191
}
182192
}

src/lib.rs

Lines changed: 75 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,14 @@ where
233233
}
234234
}
235235

236+
/// Whether to print the time with higher precision.
237+
pub fn with_higher_precision(self, higher_precision: bool) -> Self {
238+
Self {
239+
config: self.config.with_higher_precision(higher_precision),
240+
..self
241+
}
242+
}
243+
236244
fn styled(&self, style: Style, text: impl AsRef<str>) -> String {
237245
if self.config.ansi {
238246
style.paint(text.as_ref()).to_string()
@@ -397,6 +405,70 @@ where
397405
let writer = self.make_writer.make_writer();
398406
bufs.flush_current_buf(writer)
399407
}
408+
409+
fn get_timestamp<S>(&self, span: SpanRef<S>) -> Option<String>
410+
where
411+
S: Subscriber + for<'span> LookupSpan<'span>,
412+
{
413+
let ext = span.extensions();
414+
let data = ext
415+
.get::<Data>()
416+
.expect("Data cannot be found in extensions");
417+
418+
if self.config.higher_precision {
419+
Some(self.format_timestamp_with_decimals(data.start))
420+
} else {
421+
Some(self.format_timestamp(data.start))
422+
}
423+
}
424+
425+
fn format_timestamp(&self, start: std::time::Instant) -> String {
426+
let elapsed = start.elapsed();
427+
let millis = elapsed.as_millis();
428+
let secs = elapsed.as_secs();
429+
430+
// Convert elapsed time to appropriate units: ms, s, or m.
431+
// - Less than 1s : use ms
432+
// - Less than 1m : use s
433+
// - 1m and above : use m
434+
let (n, unit) = if millis < 1000 {
435+
(millis as _, "ms")
436+
} else if secs < 60 {
437+
(secs, "s ")
438+
} else {
439+
(secs / 60, "m ")
440+
};
441+
442+
let timestamp = format!("{n:>3}");
443+
self.style_timestamp(timestamp, unit)
444+
}
445+
446+
fn format_timestamp_with_decimals(&self, start: std::time::Instant) -> String {
447+
let secs = start.elapsed().as_secs_f64();
448+
449+
// Convert elapsed time to appropriate units: μs, ms, or s.
450+
// - Less than 1ms: use μs
451+
// - Less than 1s : use ms
452+
// - 1s and above : use s
453+
let (n, unit) = if secs < 0.001 {
454+
(secs * 1_000_000.0, "μs")
455+
} else if secs < 1.0 {
456+
(secs * 1_000.0, "ms")
457+
} else {
458+
(secs, "s ")
459+
};
460+
461+
let timestamp = format!(" {n:.2}");
462+
self.style_timestamp(timestamp, unit)
463+
}
464+
465+
fn style_timestamp(&self, timestamp: String, unit: &str) -> String {
466+
format!(
467+
"{timestamp}{unit} ",
468+
timestamp = self.styled(Style::new().dimmed(), timestamp),
469+
unit = self.styled(Style::new().dimmed(), unit),
470+
)
471+
}
400472
}
401473

402474
impl<S, W, FT> Layer<S> for HierarchicalLayer<W, FT>
@@ -475,38 +547,10 @@ where
475547

476548
// check if this event occurred in the context of a span.
477549
// if it has, get the start time of this span.
478-
let start = match span {
479-
Some(span) => {
480-
// if the event is in a span, get the span's starting point.
481-
let ext = span.extensions();
482-
let data = ext
483-
.get::<Data>()
484-
.expect("Data cannot be found in extensions");
485-
486-
Some(data.start)
550+
if let Some(span) = span {
551+
if let Some(timestamp) = self.get_timestamp(span) {
552+
write!(&mut event_buf, "{}", timestamp).expect("Unable to write to buffer");
487553
}
488-
None => None,
489-
};
490-
491-
if let Some(start) = start {
492-
let elapsed = start.elapsed();
493-
let millis = elapsed.as_millis();
494-
let secs = elapsed.as_secs();
495-
let (n, unit) = if millis < 1000 {
496-
(millis as _, "ms")
497-
} else if secs < 60 {
498-
(secs, "s ")
499-
} else {
500-
(secs / 60, "m ")
501-
};
502-
let n = format!("{n:>3}");
503-
write!(
504-
&mut event_buf,
505-
"{timestamp}{unit} ",
506-
timestamp = self.styled(Style::new().dimmed(), n),
507-
unit = self.styled(Style::new().dimmed(), unit),
508-
)
509-
.expect("Unable to write to buffer");
510554
}
511555

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

0 commit comments

Comments
 (0)