GET /v1/status Returns node status, cluster topology (if clustered), and resource usage. Requires authentication (any valid identity). Response: ```json { "node_id": 1, "wal_next_lsn": 42, "active_sessions": 3, "users": 5, "tenants": 2, "cluster": { "nodes": [...], "raft_groups": [...] } // if clustered } ```
(
headers: HeaderMap,
State(state): State<AppState>,
)
| 27 | /// } |
| 28 | /// ``` |
| 29 | pub async fn status( |
| 30 | headers: HeaderMap, |
| 31 | State(state): State<AppState>, |
| 32 | ) -> Result<impl IntoResponse, ApiError> { |
| 33 | let _identity = resolve_identity(&headers, &state, "http")?; |
| 34 | |
| 35 | let wal_next_lsn = state.shared.wal.next_lsn().as_u64(); |
| 36 | let node_id = state.shared.node_id; |
| 37 | let user_count = state.shared.credentials.list_user_details().len(); |
| 38 | |
| 39 | // Tenant count from known users. |
| 40 | let user_details = state.shared.credentials.list_user_details(); |
| 41 | let mut tenant_ids = std::collections::HashSet::new(); |
| 42 | for user in &user_details { |
| 43 | tenant_ids.insert(user.tenant_id.as_u64()); |
| 44 | } |
| 45 | let tenant_count = tenant_ids.len(); |
| 46 | |
| 47 | // Audit log size. |
| 48 | let audit_entries = match state.shared.audit.lock() { |
| 49 | Ok(log) => log.all().len(), |
| 50 | Err(p) => p.into_inner().all().len(), |
| 51 | }; |
| 52 | |
| 53 | let mut result = serde_json::json!({ |
| 54 | "node_id": node_id, |
| 55 | "wal_next_lsn": wal_next_lsn, |
| 56 | "users": user_count, |
| 57 | "tenants": tenant_count, |
| 58 | "audit_entries": audit_entries, |
| 59 | }); |
| 60 | |
| 61 | // Add cluster info if available. |
| 62 | if let Some(ref topo) = state.shared.cluster_topology { |
| 63 | let topo = topo.read().unwrap_or_else(|p| p.into_inner()); |
| 64 | let nodes: Vec<serde_json::Value> = topo |
| 65 | .all_nodes() |
| 66 | .map(|n| { |
| 67 | serde_json::json!({ |
| 68 | "node_id": n.node_id, |
| 69 | "addr": n.addr, |
| 70 | "state": format!("{:?}", n.state), |
| 71 | }) |
| 72 | }) |
| 73 | .collect(); |
| 74 | |
| 75 | let raft_groups = if let Some(ref routing) = state.shared.cluster_routing { |
| 76 | let routing = routing.read().unwrap_or_else(|p| p.into_inner()); |
| 77 | routing |
| 78 | .group_ids() |
| 79 | .iter() |
| 80 | .filter_map(|&gid| { |
| 81 | routing.group_info(gid).map(|info| { |
| 82 | serde_json::json!({ |
| 83 | "group_id": gid, |
| 84 | "leader": info.leader, |
| 85 | "members": info.members, |
| 86 | "vshard_count": routing.vshards_for_group(gid).len(), |
nothing calls this directly
no test coverage detected