fix: separate compaction metric correlation

This commit is contained in:
2026-09-16 06:34:15 +09:00
parent b6960878a6
commit ffc1933f06
5 changed files with 40 additions and 14 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ use session_metrics::{
let metric = Metric::now("compact.start") let metric = Metric::now("compact.start")
.with_value(12_345.0) .with_value(12_345.0)
.with_dimension("trigger", "automatic") .with_dimension("trigger", "pre_run")
.with_correlation_id("018f6f8a-9822-7b11-8b35-706f30313700"); .with_correlation_id("018f6f8a-9822-7b11-8b35-706f30313700");
record_metric( record_metric(
&store, &store,
+32 -7
View File
@@ -266,7 +266,7 @@ impl CompactAttempt {
self.source_segment_id.to_string(), self.source_segment_id.to_string(),
), ),
("mode".into(), self.mode.as_str().into()), ("mode".into(), self.mode.as_str().into()),
("trigger".into(), self.mode.as_str().into()), ("trigger".into(), self.threshold_policy.as_str().into()),
( (
"threshold_policy".into(), "threshold_policy".into(),
self.threshold_policy.as_str().into(), self.threshold_policy.as_str().into(),
@@ -305,6 +305,15 @@ fn metric_with_context(
metric metric
} }
pub(crate) fn new_compact_metric_correlation_id(lifecycle_id: &str) -> String {
loop {
let correlation_id = uuid::Uuid::now_v7().to_string();
if correlation_id != lifecycle_id {
return correlation_id;
}
}
}
pub(crate) fn correlated_post_request_metric( pub(crate) fn correlated_post_request_metric(
kind: PostRequestMetric, kind: PostRequestMetric,
correlation_id: &str, correlation_id: &str,
@@ -330,10 +339,10 @@ pub(crate) fn safe_metric_number(value: u64) -> f64 {
fn estimate_source(source: EstimateSource) -> &'static str { fn estimate_source(source: EstimateSource) -> &'static str {
match source { match source {
EstimateSource::Measured => "measured", EstimateSource::Measured => "provider",
EstimateSource::Interpolated => "interpolated", EstimateSource::Interpolated | EstimateSource::Extrapolated | EstimateSource::NoData => {
EstimateSource::Extrapolated => "extrapolated", "fallback"
EstimateSource::NoData => "no_data", }
} }
} }
@@ -357,14 +366,30 @@ mod tests {
assert_eq!(start.name, "compact.start"); assert_eq!(start.name, "compact.start");
assert_eq!(start.value, Some(MAX_SAFE_INTEGER as f64)); assert_eq!(start.value, Some(MAX_SAFE_INTEGER as f64));
assert_eq!(start.dimensions["mode"], "automatic"); assert_eq!(start.dimensions["mode"], "automatic");
assert_eq!(start.dimensions["trigger"], "automatic"); assert_eq!(start.dimensions["trigger"], "request_threshold");
assert_eq!(start.dimensions["threshold_policy"], "request_threshold"); assert_eq!(start.dimensions["threshold_policy"], "request_threshold");
assert_eq!(start.dimensions["occupancy_source"], "measured"); assert_eq!(start.dimensions["occupancy_source"], "provider");
assert!(start.correlation_id.is_some()); assert!(start.correlation_id.is_some());
assert!(start.dimensions.keys().all(|key| key.len() <= 32)); assert!(start.dimensions.keys().all(|key| key.len() <= 32));
assert!(start.dimensions.values().all(|value| value.len() <= 64)); assert!(start.dimensions.values().all(|value| value.len() <= 64));
} }
#[test]
fn occupancy_sources_match_the_public_provider_fallback_schema() {
assert_eq!(estimate_source(EstimateSource::Measured), "provider");
assert_eq!(estimate_source(EstimateSource::Interpolated), "fallback");
assert_eq!(estimate_source(EstimateSource::Extrapolated), "fallback");
assert_eq!(estimate_source(EstimateSource::NoData), "fallback");
}
#[test]
fn metric_correlation_id_is_distinct_from_lifecycle_identity() {
let lifecycle_id = uuid::Uuid::now_v7().to_string();
let correlation_id = new_compact_metric_correlation_id(&lifecycle_id);
assert_ne!(correlation_id, lifecycle_id);
assert!(uuid::Uuid::parse_str(&correlation_id).is_ok());
}
#[test] #[test]
fn post_request_metric_saturates_values_above_json_safe_integer() { fn post_request_metric_saturates_values_above_json_safe_integer() {
let record = UsageRecord { let record = UsageRecord {
+3 -2
View File
@@ -42,7 +42,7 @@ use manifest::{
use crate::compact::state::CompactState; use crate::compact::state::CompactState;
use crate::compact::telemetry::{ use crate::compact::telemetry::{
CompactAttempt, CompactFailureCategory, CompactMode, CompactSuccessStats, CompactAttempt, CompactFailureCategory, CompactMode, CompactSuccessStats,
CompactThresholdPolicy, correlated_post_request_metric, CompactThresholdPolicy, correlated_post_request_metric, new_compact_metric_correlation_id,
}; };
use crate::compact::usage_tracker::UsageTracker; use crate::compact::usage_tracker::UsageTracker;
use crate::feature::background::{BackgroundTaskRewriteGuard, FeatureBackgroundTaskRegistry}; use crate::feature::background::{BackgroundTaskRewriteGuard, FeatureBackgroundTaskRegistry};
@@ -4991,8 +4991,9 @@ impl<C: LlmClient + 'static, St: Store> Worker<C, St> {
let history_items = self.session.history().items_cloned(); let history_items = self.session.history().items_cloned();
let usage_history = self.usage_history(); let usage_history = self.usage_history();
let pre_context = agen::token_counter::total_tokens(&history_items, &usage_history); let pre_context = agen::token_counter::total_tokens(&history_items, &usage_history);
let metric_correlation_id = new_compact_metric_correlation_id(&lifecycle.compaction_id);
let attempt = CompactAttempt::new( let attempt = CompactAttempt::new(
lifecycle.compaction_id.clone(), metric_correlation_id,
source_location.session_id, source_location.session_id,
source_location.segment_id, source_location.segment_id,
match trigger { match trigger {
+3 -3
View File
@@ -760,7 +760,7 @@ async fn compact_emits_session_start_carrying_summary_and_task_snapshot() {
assert_eq!(starts.len(), 1); assert_eq!(starts.len(), 1);
assert_eq!(starts[0].segment_id, source_segment_id); assert_eq!(starts[0].segment_id, source_segment_id);
assert_eq!(starts[0].metric.dimensions["mode"], "automatic"); assert_eq!(starts[0].metric.dimensions["mode"], "automatic");
assert_eq!(starts[0].metric.dimensions["trigger"], "automatic"); assert_eq!(starts[0].metric.dimensions["trigger"], "request_threshold");
assert_eq!( assert_eq!(
starts[0].metric.dimensions["threshold_policy"], starts[0].metric.dimensions["threshold_policy"],
"request_threshold" "request_threshold"
@@ -970,7 +970,7 @@ async fn pre_run_compact_publishes_runtime_progress_phases() {
.unwrap(); .unwrap();
assert_eq!(start.segment_id, segment_before); assert_eq!(start.segment_id, segment_before);
assert_eq!(start.metric.dimensions["mode"], "automatic"); assert_eq!(start.metric.dimensions["mode"], "automatic");
assert_eq!(start.metric.dimensions["trigger"], "automatic"); assert_eq!(start.metric.dimensions["trigger"], "pre_run");
assert_eq!(start.metric.dimensions["threshold_policy"], "pre_run"); assert_eq!(start.metric.dimensions["threshold_policy"], "pre_run");
let finish = metrics let finish = metrics
.iter() .iter()
@@ -1027,7 +1027,7 @@ async fn request_threshold_compact_publishes_runtime_progress() {
.iter() .iter()
.find(|record| record.metric.name == "compact.start") .find(|record| record.metric.name == "compact.start")
.unwrap(); .unwrap();
assert_eq!(start.metric.dimensions["trigger"], "automatic"); assert_eq!(start.metric.dimensions["trigger"], "request_threshold");
assert_eq!( assert_eq!(
start.metric.dimensions["threshold_policy"], start.metric.dimensions["threshold_policy"],
"request_threshold" "request_threshold"
+1 -1
View File
@@ -35,7 +35,7 @@ The important property is explainability: after compaction, records should still
## Metrics and comparison procedure ## Metrics and comparison procedure
Compaction measurements stay out of the ordinary transcript. They are appended as Compaction measurements stay out of the ordinary transcript. They are appended as
`session.metrics` extensions and are read only through the explicit `metrics` extensions and are read only through the explicit
`session-metrics` reader/export path. `read_session_metrics` attaches the durable `session-metrics` reader/export path. `read_session_metrics` attaches the durable
`segment_id` and `SegmentStart.compacted_from` lineage to each record. `segment_id` and `SegmentStart.compacted_from` lineage to each record.