mirror of
https://github.com/whit3rabbit/anyllm-proxy.git
synced 2026-09-22 00:00:50 +00:00
feat: compute requests_per_second from SQLite in admin metrics snapshot
This commit is contained in:
@@ -373,6 +373,18 @@ pub fn purge_old_logs(conn: &Connection, retention_days: u32) -> rusqlite::Resul
|
||||
Ok(changed)
|
||||
}
|
||||
|
||||
/// Count request log entries with a timestamp >= `since_epoch` (Unix seconds).
|
||||
/// Used to compute requests-per-second for the metrics dashboard.
|
||||
pub fn count_requests_since(conn: &Connection, since_epoch: u64) -> rusqlite::Result<u64> {
|
||||
let since_iso = epoch_to_iso8601(since_epoch);
|
||||
let count: i64 = conn.query_row(
|
||||
"SELECT COUNT(*) FROM request_log WHERE timestamp >= ?1",
|
||||
rusqlite::params![since_iso],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
Ok(count.max(0) as u64)
|
||||
}
|
||||
|
||||
/// Spawn the write buffer background task. Returns the sender for proxy handlers.
|
||||
/// Flushes every 100ms or 100 rows, whichever comes first.
|
||||
pub fn spawn_write_buffer(db: Arc<Mutex<Connection>>) -> mpsc::Sender<RequestLogEntry> {
|
||||
@@ -1052,4 +1064,31 @@ mod tests {
|
||||
query_request_log(&conn, 10, 0, None, None, Some("garbage"), None).unwrap();
|
||||
assert_eq!(results.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn count_requests_since_returns_zero_on_empty_log() {
|
||||
let conn = in_memory_db();
|
||||
let count = count_requests_since(&conn, 0).unwrap();
|
||||
assert_eq!(count, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn count_requests_since_counts_recent_entries() {
|
||||
let conn = in_memory_db();
|
||||
|
||||
// Insert a recent entry (sample_entry uses current time).
|
||||
let recent = sample_entry();
|
||||
insert_request_log(&conn, &recent).unwrap();
|
||||
|
||||
// Insert an old entry.
|
||||
let mut old = sample_entry();
|
||||
old.request_id = "old-req".to_string();
|
||||
old.timestamp = "2020-01-01T00:00:00Z".to_string();
|
||||
insert_request_log(&conn, &old).unwrap();
|
||||
|
||||
// Count since 2025-01-01 should include only the recent entry.
|
||||
let since_2025: u64 = 1735689600; // 2025-01-01T00:00:00Z
|
||||
let count = count_requests_since(&conn, since_2025).unwrap();
|
||||
assert_eq!(count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,12 +400,28 @@ async fn main() {
|
||||
backends.insert(name.clone(), snap);
|
||||
}
|
||||
let error_rate = aggregate.error_rate();
|
||||
// Count requests in the last 60 seconds for RPS.
|
||||
let rps = {
|
||||
let db = snapshot_shared.db.clone();
|
||||
let now_secs = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs();
|
||||
let since = now_secs.saturating_sub(60);
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let conn = db.lock().unwrap_or_else(|e| e.into_inner());
|
||||
admin::db::count_requests_since(&conn, since).unwrap_or(0)
|
||||
})
|
||||
.await
|
||||
.unwrap_or(0) as f64
|
||||
/ 60.0
|
||||
};
|
||||
let snapshot = admin::state::MetricsSnapshotData {
|
||||
backends,
|
||||
latency_p50_ms: None, // Computed on demand by REST endpoint
|
||||
latency_p95_ms: None,
|
||||
latency_p99_ms: None,
|
||||
requests_per_second: 0.0, // TODO: compute from recent request log
|
||||
requests_per_second: rps,
|
||||
error_rate,
|
||||
};
|
||||
let _ = snapshot_shared
|
||||
|
||||
Reference in New Issue
Block a user