fn live_status_payload(state: &App) -> Value { let snapshot = state.config.load_full(); let stream_metrics = state.active_streams.iter().filter_map(|stream| { state.stream_metrics.get(&stream.id).map(|metrics| (stream.id.clone(), metrics.view())) }).collect::>(); json!({ "version": env!("CARGO_PKG_VERSION"), "uptime_seconds": state.started.elapsed().as_secs(), "revision": snapshot.envelope.revision, "listeners": { "active_endpoints": state.active_listeners, "desired_endpoints": snapshot.listeners, "restart_required": snapshot.listeners != state.active_listeners }, "metrics": state.metrics.view(), "cache": state.cache.view(), "transform_metrics": state.transform_metrics.total(), "logs_dropped": state.logs.dropped.load(Ordering::Relaxed), "backends": snapshot.envelope.config.vhosts.iter().map(|v| v.backends.len()).sum::(), "backend_pools": snapshot.pools.iter().map(|p| p.view()).collect::>(), "vhost_metrics": snapshot.vhost_metrics.iter().map(|(id, metrics)| (id.clone(), metrics.view())).collect::>(), "streams": {"metrics": stream_metrics}, "logging": {"sinks": state.logs.stats(), "error_file": crate::logging::error_log_stats()} }) } #[derive(Default, Deserialize)] #[serde(default, deny_unknown_fields)] struct StatusQuery { view: Option, } async fn status(State(state): State>, Query(query): Query) -> Result, ApiError> { match query.view.as_deref() { None => Ok(Json(status_payload(&state))), Some("live") => Ok(Json(live_status_payload(&state))), _ => Err(ApiError(StatusCode::BAD_REQUEST, "invalid status view".into())), } } async fn system_info(State(state): State>) -> Json { Json(system_info_payload(&state)) }