diff --git a/crates/mem-cli/src/http_server.rs b/crates/mem-cli/src/http_server.rs index 2eb75e6..5f88039 100644 --- a/crates/mem-cli/src/http_server.rs +++ b/crates/mem-cli/src/http_server.rs @@ -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 }