Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions quickwit/quickwit-common/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
// limitations under the License.

use std::collections::{BTreeMap, HashMap};
use std::sync::OnceLock;
use std::sync::{LazyLock, OnceLock};

use once_cell::sync::Lazy;
use prometheus::{Gauge, HistogramOpts, Opts, TextEncoder};
pub use prometheus::{
Histogram, HistogramTimer, HistogramVec as PrometheusHistogramVec, IntCounter,
Expand Down Expand Up @@ -438,16 +437,17 @@ impl InFlightDataGauges {
}
}

/// This function returns `index_name` or projects it to `<any>` if per-index metrics are disabled.
pub fn index_label(index_name: &str) -> &str {
static PER_INDEX_METRICS_ENABLED: OnceLock<bool> = OnceLock::new();
let per_index_metrics_enabled: bool = *PER_INDEX_METRICS_ENABLED
.get_or_init(|| !crate::get_bool_from_env("QW_DISABLE_PER_INDEX_METRICS", false));
if per_index_metrics_enabled {
index_name
/// This function returns `index_id` as is if per-index metrics are enabled, or projects it to
/// `"__any__"` otherwise.
pub fn index_label(index_id: &str) -> &str {
static PER_INDEX_METRICS_ENABLED: LazyLock<bool> =
LazyLock::new(|| !crate::get_bool_from_env("QW_DISABLE_PER_INDEX_METRICS", false));

if *PER_INDEX_METRICS_ENABLED {
index_id
} else {
"__any__"
}
}

pub static MEMORY_METRICS: Lazy<MemoryMetrics> = Lazy::new(MemoryMetrics::default);
pub static MEMORY_METRICS: LazyLock<MemoryMetrics> = LazyLock::new(MemoryMetrics::default);
75 changes: 59 additions & 16 deletions quickwit/quickwit-common/src/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ impl<I> PrettySample<I> {
}
}

impl<I, T> fmt::Debug for PrettySample<I>
impl<I> fmt::Debug for PrettySample<I>
where
I: IntoIterator<Item = T> + Clone,
T: fmt::Debug,
I: IntoIterator + Clone,
I::Item: fmt::Debug,
{
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "[")?;
// in general we will get passed a reference (&[...], &HashMap...) or a Map<_> of them.

// In general, we will receive a reference (&[...], &HashMap...) or a Map<_> of them.
// So we either perform a Copy, or a cheap Clone of a simple struct
let mut iter = self.0.clone().into_iter().enumerate();
for (i, item) in &mut iter {
Expand All @@ -55,9 +56,9 @@ pub trait PrettyDisplay {
fn pretty_display(&self) -> impl fmt::Display;
}

struct PrettyDurationDisplay<'a>(&'a Duration);
struct DurationPrettyDisplay<'a>(&'a Duration);

impl fmt::Display for PrettyDurationDisplay<'_> {
impl fmt::Display for DurationPrettyDisplay<'_> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
// This is enough for my current use cases. To be extended as you see fit.
let duration_millis = self.0.as_millis();
Expand All @@ -76,7 +77,37 @@ impl fmt::Display for PrettyDurationDisplay<'_> {

impl PrettyDisplay for Duration {
fn pretty_display(&self) -> impl fmt::Display {
PrettyDurationDisplay(self)
DurationPrettyDisplay(self)
}
}

struct SequencePrettyDisplay<I>(I);

impl<I> fmt::Display for SequencePrettyDisplay<I>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code is similar enough to PrettySample that i wonder if SequencePrettyDisplay shouldn't just contain a PrettySample(_, u64::MAX)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PrettySample relies on Debug whereas for PrettyDisplay I really want to be able to use something other than Debug or Display.

where
I: IntoIterator + Clone,
I::Item: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[")?;

// In general, we will receive a reference (&[...], &HashMap...) or a Map<_> of them.
// So we either perform a Copy, or a cheap Clone of a simple struct
let mut iter = self.0.clone().into_iter().peekable();

while let Some(item) = iter.next() {
write!(f, "{item}")?;
if iter.peek().is_some() {
write!(f, ", ")?;
}
}
write!(f, "]")
}
}

impl<T: fmt::Display> PrettyDisplay for &[T] {
fn pretty_display(&self) -> impl fmt::Display {
SequencePrettyDisplay(*self)
}
}

Expand All @@ -103,17 +134,29 @@ mod tests {
}

#[test]
fn test_pretty_duration() {
let pretty_duration = Duration::from_millis(0);
assert_eq!(format!("{}", pretty_duration.pretty_display()), "0ms");
fn test_duration_pretty_display() {
let duration = Duration::from_millis(0);
assert_eq!(format!("{}", duration.pretty_display()), "0ms");

let pretty_duration = Duration::from_millis(125);
assert_eq!(format!("{}", pretty_duration.pretty_display()), "125ms");
let duration = Duration::from_millis(125);
assert_eq!(format!("{}", duration.pretty_display()), "125ms");

let duration = Duration::from_millis(1_000);
assert_eq!(format!("{}", duration.pretty_display()), "1.0s");

let duration = Duration::from_millis(1_125);
assert_eq!(format!("{}", duration.pretty_display()), "1.12s");
}

#[test]
fn test_sequence_pretty_display() {
let empty_slice: &[i32] = &[];
assert_eq!(format!("{}", empty_slice.pretty_display()), "[]");

let pretty_duration = Duration::from_millis(1_000);
assert_eq!(format!("{}", pretty_duration.pretty_display()), "1.0s");
let slice_one: &[i32] = &[1];
assert_eq!(format!("{}", slice_one.pretty_display()), "[1]");

let pretty_duration = Duration::from_millis(1_125);
assert_eq!(format!("{}", pretty_duration.pretty_display()), "1.12s");
let slice_two: &[i32] = &[1, 2];
assert_eq!(format!("{}", slice_two.pretty_display()), "[1, 2]");
}
}
Loading