Сторож смотрел колонку scrape_runs.total_seen, у которой DEFAULT 0. Замер на
проде (53 источника): колонку заполняет только lots_fetched — 21 источник, 455
прогонов. Ещё 4 источника (133 прогона, full-load'ы avito/cian/yandex) пишут
unique_fetched, которого сторож не знал, хотя у cian_full_load 6 из 38 успешных
прогонов дали настоящий ноль. Оставшиеся 28 источников (2650 прогонов) не пишут
ни одного результатного ключа вовсе: proxy_healthcheck 1650, три detail-
backfill'а, все deactivate_stale_*, refresh_search_matview с буквально пустыми
{} во всех 55 строках.
Для этих 28 сторож читал 0 ВСЕГДА, в том числе у полностью успешного прогона →
стрик не прерывался никогда → анти-спам «один раз на стрик» превращался в «один
раз навсегда»: сработав однажды на третьем прогоне источника, сторож замолкал
навсегда, продолжая выглядеть настроенным.
Свести счётчики к словарю сторожа невозможно: у 28 источников 28 разных
словарей (deactivated / rows_written / poi_loaded / snapshotted / upserted /
listings_matched …), у трёх мониторов результата нет по смыслу, а ноль у
deactivate_stale_* — здоровый ответ. Поэтому:
- признак берётся из counters, а не из колонки: «не измерено» (None) отличимо
от «измерено, ноль»;
- прогон без результатной метрики стрик ПРЕРЫВАЕТ — недостижимое условие
прерывания стало невозможным по построению, а не по корректности счётчиков;
- слепая зона логируется явно (раз на источник за процесс), а не молчит;
- в словарь добавлен unique_fetched — 4 full-load'а входят в зону видимости
сторожа и перестают показывать total_seen=0 в админке.
Доставка уведомлений этим НЕ чинится: получатель в GlitchTip не настроен (#2673),
за всю историю наружу не ушло ни одного события.
Refs #2703