use super::*;
pub(in crate::commands::ops) fn build_replay_profile(
input_path: PathBuf,
) -> Result<serde_json::Value, String> {
let replay = FileReplaySession::open(&input_path)
.map_err(|err| format!("open bag file {} failed: {err}", input_path.display()))?;
let entries = replay.entries();
let total_entries = entries.len();
let topic_count = entries
.iter()
.map(|entry| entry.topic.as_str())
.collect::<HashSet<_>>()
.len();
let capture_span_ns = match (entries.first(), entries.last()) {
(Some(first), Some(last)) => {
(last.captured_at.0.saturating_sub(first.captured_at.0)) as u64
}
_ => 0,
};
Ok(serde_json::json!({
"api_version": OPS_REPLAY_API_VERSION,
"input": input_path,
"total_entries": total_entries,
"topic_count": topic_count,
"capture_span_ns": capture_span_ns,
}))
}
pub(in crate::commands::ops) fn build_obs_profile(
snapshot: &StatusSnapshot,
format: &str,
) -> Result<serde_json::Value, String> {
let aggregator = build_obs_aggregator(snapshot);
match format {
"prometheus" => Ok(serde_json::json!({
"format": "prometheus",
"metrics": export_prometheus_text(&aggregator),
})),
"otel" => Ok(serde_json::json!({
"format": "otel",
"metrics": export_otel_json_value(&aggregator),
})),
"both" => Ok(serde_json::json!({
"format": "both",
"metrics": {
"prometheus": export_prometheus_text(&aggregator),
"otel": export_otel_json_value(&aggregator),
}
})),
other => Err(format!(
"unsupported --obs-format value: {other} (expected prometheus|otel|both)"
)),
}
}
pub(in crate::commands::ops) fn build_obs_aggregator(
snapshot: &StatusSnapshot,
) -> MetricsAggregator {
crate::commands::snapshot_shared::build_snapshot_aggregator(snapshot)
}