Skip to content

Commit f6359ae

Browse files
refactor(metrics): colocate stage histogram boundaries
Signed-off-by: nachiketb <nachiketb@nvidia.com>
1 parent d250577 commit f6359ae

5 files changed

Lines changed: 27 additions & 43 deletions

File tree

crates/libsy/src/algorithms/util/stage.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ const EXPLORING_METRIC: &str = "switchyard.stage_router.exploring";
6262
/// Distribution of production-oriented tool activity.
6363
const PRODUCTION_INTENSITY_METRIC: &str = "switchyard.stage_router.production_intensity";
6464

65+
// Histogram boundaries live with the instruments so every host exports the
66+
// same stage-router distributions without duplicating algorithm knowledge.
67+
const SCORE_BUCKETS: &[f64] = &[-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0];
68+
const UNIT_BUCKETS: &[f64] = &[0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0];
69+
6570
/// The two tiers a turn can route to.
6671
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6772
pub enum Tier {
@@ -288,15 +293,23 @@ fn record_score_metrics(signal: &ToolSignals, outcome: &PickOutcome) {
288293
};
289294
let dimensions = dimensions_from_signal(signal);
290295
let meter = meter();
291-
for (name, value) in [
292-
(SCORE_METRIC, score),
293-
(CONFIDENCE_METRIC, confidence),
294-
(SEVERITY_METRIC, dimensions.severity),
295-
(SPINNING_METRIC, dimensions.spinning),
296-
(EXPLORING_METRIC, dimensions.exploring),
297-
(PRODUCTION_INTENSITY_METRIC, dimensions.production_intensity),
296+
for (name, value, boundaries) in [
297+
(SCORE_METRIC, score, SCORE_BUCKETS),
298+
(CONFIDENCE_METRIC, confidence, UNIT_BUCKETS),
299+
(SEVERITY_METRIC, dimensions.severity, UNIT_BUCKETS),
300+
(SPINNING_METRIC, dimensions.spinning, UNIT_BUCKETS),
301+
(EXPLORING_METRIC, dimensions.exploring, UNIT_BUCKETS),
302+
(
303+
PRODUCTION_INTENSITY_METRIC,
304+
dimensions.production_intensity,
305+
UNIT_BUCKETS,
306+
),
298307
] {
299-
meter.f64_histogram(name).build().record(value, &[]);
308+
meter
309+
.f64_histogram(name)
310+
.with_boundaries(boundaries.to_vec())
311+
.build()
312+
.record(value, &[]);
300313
}
301314
}
302315

crates/switchyard-server/src/metrics.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fn initialize() -> Result<Metrics, String> {
4242
.map_err(|error| format!("failed to initialize Prometheus metrics: {error}"))?;
4343
let mut builder = SdkMeterProvider::builder()
4444
.with_reader(exporter)
45-
.with_view(histogram_buckets)
45+
.with_view(routing_overhead_buckets)
4646
.with_resource(crate::observability::resource());
4747
if crate::observability::otlp_enabled("METRICS") {
4848
let exporter = opentelemetry_otlp::MetricExporter::builder()
@@ -70,15 +70,13 @@ pub(crate) fn flush() {
7070
}
7171
}
7272

73-
fn histogram_buckets(instrument: &Instrument) -> Option<Stream> {
74-
let boundaries = if instrument.name() == "switchyard.routing_overhead_ms" {
75-
ROUTING_OVERHEAD_BUCKETS_MS
76-
} else {
77-
crate::stats::algorithm_histogram_buckets(instrument.name())?
78-
};
73+
fn routing_overhead_buckets(instrument: &Instrument) -> Option<Stream> {
74+
if instrument.name() != "switchyard.routing_overhead_ms" {
75+
return None;
76+
}
7977
Stream::builder()
8078
.with_aggregation(Aggregation::ExplicitBucketHistogram {
81-
boundaries: boundaries.to_vec(),
79+
boundaries: ROUTING_OVERHEAD_BUCKETS_MS.to_vec(),
8280
// Cumulative min/max cover the whole process, so they aren't useful.
8381
record_min_max: false,
8482
})

crates/switchyard-server/src/stats.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,4 @@ mod algorithms;
88
mod cache_eligibility;
99

1010
pub(crate) use accumulator::{StatsAccumulator, StatsSnapshot, TokenUsage};
11-
pub(crate) use algorithms::histogram_buckets as algorithm_histogram_buckets;
1211
pub(crate) use cache_eligibility::{prefix_probe, tracking_enabled_from_env};

crates/switchyard-server/src/stats/algorithms.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,3 @@ impl AlgorithmStats {
5858
}
5959
}
6060
}
61-
62-
pub(crate) fn histogram_buckets(metric: &str) -> Option<&'static [f64]> {
63-
stage_router::histogram_buckets(metric)
64-
}

crates/switchyard-server/src/stats/algorithms/stage_router.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,6 @@ const SPINNING_METRIC: &str = "switchyard_stage_router_spinning";
1616
const EXPLORING_METRIC: &str = "switchyard_stage_router_exploring";
1717
const PRODUCTION_INTENSITY_METRIC: &str = "switchyard_stage_router_production_intensity";
1818

19-
const SCORE_INSTRUMENT: &str = "switchyard.stage_router.score";
20-
const UNIT_INSTRUMENTS: &[&str] = &[
21-
"switchyard.stage_router.confidence",
22-
"switchyard.stage_router.severity",
23-
"switchyard.stage_router.spinning",
24-
"switchyard.stage_router.exploring",
25-
"switchyard.stage_router.production_intensity",
26-
];
27-
28-
const SCORE_BUCKETS: &[f64] = &[-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0];
29-
const UNIT_BUCKETS: &[f64] = &[0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0];
30-
3119
#[derive(Clone, Debug, Default)]
3220
pub(super) struct StageRouterCumulative {
3321
decisions: BTreeMap<DecisionKey, u64>,
@@ -204,16 +192,6 @@ fn round4(value: f64) -> f64 {
204192
if rounded == 0.0 { 0.0 } else { rounded }
205193
}
206194

207-
pub(super) fn histogram_buckets(metric: &str) -> Option<&'static [f64]> {
208-
if metric == SCORE_INSTRUMENT {
209-
Some(SCORE_BUCKETS)
210-
} else if UNIT_INSTRUMENTS.contains(&metric) {
211-
Some(UNIT_BUCKETS)
212-
} else {
213-
None
214-
}
215-
}
216-
217195
#[cfg(test)]
218196
mod tests {
219197
use opentelemetry::KeyValue;

0 commit comments

Comments
 (0)