Nix Observability Daemon
observability nix
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

other stuff

+20 -8
+20 -8
src/main.rs
··· 223 223 .context("Failed to create schema")?; 224 224 conn.execute_batch(&format!("PRAGMA user_version = {}", SCHEMA_VERSION)) 225 225 .context("Failed to set schema version")?; 226 - conn.execute_batch("PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL;") 227 - .context("Failed to configure WAL mode")?; 226 + conn.execute_batch(" 227 + PRAGMA journal_mode = WAL; 228 + PRAGMA synchronous = NORMAL; 229 + PRAGMA locking_mode = EXCLUSIVE; 230 + PRAGMA temp_store = MEMORY; 231 + PRAGMA mmap_size = 134217728; 232 + PRAGMA cache_size = -8000; 233 + PRAGMA wal_autocheckpoint = 0; 234 + ").context("Failed to configure database")?; 228 235 229 236 Ok(conn) 230 237 } ··· 365 372 let db = state.lock().unwrap().db.clone(); 366 373 tokio::task::spawn_blocking(move || -> Result<()> { 367 374 let conn = db.lock().unwrap(); 368 - conn.execute_batch("DELETE FROM events; VACUUM;")?; 375 + conn.execute_batch("DELETE FROM events; VACUUM; PRAGMA wal_checkpoint(TRUNCATE);")?; 369 376 Ok(()) 370 377 }).await??; 371 378 writer.write_all(b"ok\n").await?; ··· 448 455 ); 449 456 450 457 let drv_path = act.fields.get(0).and_then(|v| v.as_str()).map(|s| s.to_string()); 451 - let cache_url = if act_type == ActivityType::QueryPathInfo { 452 - act.fields.get(1).and_then(|v| v.as_str()).map(|s| s.to_string()) 453 - } else { 454 - None 458 + // Both Substitute (fields[1] = substituter URL) and QueryPathInfo (fields[1] = cache URL) 459 + // have the same layout. Store cache_url for both. 460 + let cache_url = match act_type { 461 + ActivityType::Substitute | ActivityType::QueryPathInfo => { 462 + act.fields.get(1).and_then(|v| v.as_str()).map(|s| s.to_string()) 463 + } 464 + _ => None, 455 465 }; 456 466 457 467 let conn = s.db.lock().unwrap(); ··· 511 521 }) 512 522 })?.filter_map(|r| r.ok()).collect(); 513 523 524 + // Use Substitute (108) events for cache latency — these measure full download time 525 + // per substituter, not just metadata query time (QueryPathInfo). 514 526 let mut stmt = conn.prepare( 515 527 "SELECT cache_url, AVG(duration_ms), COUNT(*) 516 - FROM events WHERE cache_url IS NOT NULL 528 + FROM events WHERE event_type = 108 AND cache_url IS NOT NULL 517 529 GROUP BY cache_url ORDER BY AVG(duration_ms) DESC", 518 530 ).context("Failed to prepare cache latency query")?; 519 531 let cache_latency: Vec<CacheStat> = stmt.query_map([], |r| {