Reports git-metadata watcher health (design D3/D5). The watcher lives in the daemon; its per-project state is only in-process, so this section sources telemetry the read-only way: recent `git_watch_*` events from the daemon log (systemd journal on Linux, launchd err-log on macOS). It reports whether the watcher is active vs degraded (mtime-poll fallback) per project. Absent telemetry is reported
(dc: &mut DoctorCounters)
| 571 | /// project. Absent telemetry is reported as info, not a failure — the watcher is |
| 572 | /// a best-effort freshness aid backed by the on-read/hook sync paths. |
| 573 | fn check_watcher(dc: &mut DoctorCounters) { |
| 574 | eprintln!("\n\x1b[1mWatcher\x1b[0m"); |
| 575 | |
| 576 | let config = crate::config::SyncConfig::default().with_env_overrides(); |
| 577 | if !config.auto_watch { |
| 578 | dc.info("Git-metadata watcher disabled (`sync.auto_watch = false`)"); |
| 579 | return; |
| 580 | } |
| 581 | |
| 582 | if !crate::daemon::daemon_reachable() { |
| 583 | dc.info("Daemon not running — watcher inactive; sync happens on hook/read events"); |
| 584 | return; |
| 585 | } |
| 586 | |
| 587 | #[cfg(unix)] |
| 588 | { |
| 589 | let events = crate::daemon::recent_watcher_events(2000); |
| 590 | if events.is_empty() { |
| 591 | dc.info("Daemon running; no recent watcher telemetry in the log yet"); |
| 592 | return; |
| 593 | } |
| 594 | let mut degraded = 0usize; |
| 595 | let mut active = 0usize; |
| 596 | let mut projects: Vec<_> = events.into_iter().collect(); |
| 597 | projects.sort_by(|a, b| a.0.cmp(&b.0)); |
| 598 | for (project, ev) in projects { |
| 599 | match ev.event.as_str() { |
| 600 | "git_watch_degraded" => { |
| 601 | degraded += 1; |
| 602 | dc.warn(&format!( |
| 603 | "{project}: degraded (mtime-poll fallback){}", |
| 604 | ev.detail.map(|d| format!(" — {d}")).unwrap_or_default() |
| 605 | )); |
| 606 | } |
| 607 | "git_watch_restart" => { |
| 608 | dc.warn(&format!("{project}: watcher restarting after failure")); |
| 609 | } |
| 610 | _ => { |
| 611 | active += 1; |
| 612 | dc.pass(&format!( |
| 613 | "{project}: active ({})", |
| 614 | ev.detail.unwrap_or_else(|| ev.event.clone()) |
| 615 | )); |
| 616 | } |
| 617 | } |
| 618 | } |
| 619 | if degraded == 0 && active > 0 { |
| 620 | dc.info(&format!("{active} project(s) watched, none degraded")); |
| 621 | } |
| 622 | } |
| 623 | |
| 624 | #[cfg(not(unix))] |
| 625 | dc.info("Git-metadata watcher is only available on Unix daemons"); |
| 626 | } |
| 627 | |
| 628 | /// Check user config file. |
| 629 | fn check_user_config(dc: &mut DoctorCounters) { |
no test coverage detected