feat(O5): write volume + storage metrics with background collector

- Track entity/edge/chunk writes and errors
- Track bytes written per write operation
- Background task: collect DB row counts every 60s
- Background task: collect pool size/idle stats
- Metrics: W1-W12 (12 metrics instrumented)
This commit is contained in:
2026-09-13 21:48:15 +09:00
parent 853c78bbdb
commit 60e77929de
+30 -1
View File
@@ -374,6 +374,30 @@ pub async fn start_server(port: u16, api_key: String, database_url: &str) -> Res
});
tracing::info!("Starting HTTP server on port {}", port);
// O5/O7/O9: Background stats collector (every 60s)
{
let stats_pool = state.get_ref().pool.clone();
tokio::spawn(async move {
let mut interval = tokio::time::interval(std::time::Duration::from_secs(60));
loop {
interval.tick().await;
// O5: Table row counts
if let Ok(row) = sqlx::query_as::<_, (i64,)>("SELECT COUNT(*) FROM memory_entity")
.fetch_one(&stats_pool).await {
crate::metrics::DB_TABLE_ENTITY_ROWS.set(row.0 as u64);
}
if let Ok(row) = sqlx::query_as::<_, (i64,)>("SELECT COUNT(*) FROM memory_edge")
.fetch_one(&stats_pool).await {
crate::metrics::DB_TABLE_EDGE_ROWS.set(row.0 as u64);
}
// O9: Pool stats
crate::metrics::DB_POOL_SIZE.set(stats_pool.size() as u64);
crate::metrics::DB_POOL_IDLE.set(stats_pool.num_idle() as u64);
}
});
}
tracing::info!("Creating HttpServer instance...");
let server = HttpServer::new(move || {
@@ -792,8 +816,13 @@ async fn store_compacted_memory(
.await;
match result {
Ok(_) => true,
Ok(_) => {
crate::metrics::WRITE_CHUNKS_TOTAL.inc();
crate::metrics::WRITE_BYTES_TOTAL.inc_by(memory.len() as u64);
true
}
Err(e) => {
crate::metrics::WRITE_ERRORS_TOTAL.inc();
tracing::error!("Failed to store compacted memory: {}", e);
false
}