faces: surface enabled/disabled state + per-tick candidate count

Manual deploy debugging: 'Saved thumbnail' logs were visible (boot-time
thumbnail backfill) but no face_watch logs were appearing, with no
obvious way to tell whether the integration was disabled, hadn't reached
a full scan yet, or had simply seen no new files.

Two log lines:
  - watch_files startup: 'Face detection: ENABLED' / 'DISABLED (set
    APOLLO_FACE_API_BASE_URL or APOLLO_API_BASE_URL to enable)' so
    you can tell at a glance whether the env wired through.
  - process_new_files (debug-level): 'face_watch: scan tick — N image
    file(s) walked, M candidate(s) (library 'main', modified_since=...)'
    so an empty-candidate scan is distinguishable from a misconfigured
    or skipped one without bumping log level for the rest of the
    watcher.

No behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cameron Cordes
2026-04-29 20:19:17 +00:00
parent 41f93d70d1
commit 23f4941471

View File

@@ -1810,6 +1810,18 @@ fn watch_files(
info!("Starting optimized file watcher"); info!("Starting optimized file watcher");
info!(" Quick scan interval: {} seconds", quick_interval_secs); info!(" Quick scan interval: {} seconds", quick_interval_secs);
info!(" Full scan interval: {} seconds", full_interval_secs); info!(" Full scan interval: {} seconds", full_interval_secs);
// Surface face-detection state at boot so it's obvious whether
// the watcher will hit Apollo. The branch silently no-ops when
// disabled (intentional for legacy deploys), which makes "why
// aren't faces being detected?" hard to diagnose otherwise.
if face_client.is_enabled() {
info!(" Face detection: ENABLED");
} else {
info!(
" Face detection: DISABLED (set APOLLO_FACE_API_BASE_URL \
or APOLLO_API_BASE_URL to enable)"
);
}
for lib in &libs { for lib in &libs {
info!( info!(
" Watching library '{}' (id={}) at {}", " Watching library '{}' (id={}) at {}",
@@ -2115,6 +2127,13 @@ fn process_new_files(
// up; the watcher remains usable on legacy deploys. // up; the watcher remains usable on legacy deploys.
if face_client.is_enabled() { if face_client.is_enabled() {
let candidates = build_face_candidates(&context, &files, &exif_dao, &face_dao); let candidates = build_face_candidates(&context, &files, &exif_dao, &face_dao);
debug!(
"face_watch: scan tick — {} image file(s) walked, {} candidate(s) (library '{}', modified_since={})",
files.iter().filter(|(p, _)| !is_video_file(p)).count(),
candidates.len(),
library.name,
modified_since.is_some(),
);
if !candidates.is_empty() { if !candidates.is_empty() {
face_watch::run_face_detection_pass( face_watch::run_face_detection_pass(
library, library,