Cron зелёный, а данные старые: метрика последнего успеха через textfile

Ночной скрипт формирует выгрузку. Процесс сейчас не работает, cron включён, а ошибок в свежем журнале нет. Но файл данных уже сутки не обновлялся. Для короткой пакетной задачи полезно наблюдать не наличие процесса, а время последнего успешного завершения. Его можно публиковать через textfile collector node_exporter.

Скрипт записывает метрику в файл, exporter читает такие файлы из настроенного каталога и отдаёт их вместе с метриками машины. Здесь не нужен постоянно работающий HTTP-сервер внутри каждого задания. Важно только выбрать корректный смысл события: «успех» должен фиксироваться после появления и проверки результата, а не сразу после старта shell.

Записать timestamp как значение метрики

Запустите node_exporter с параметром --collector.textfile.directory, указывающим на выделенный каталог. В конце успешного скрипта на Linux можно записать значение так:

metric_dir=/var/lib/node_exporter/textfile_collector
metric_tmp=$(mktemp "$metric_dir/report.XXXXXX")
printf 'report_last_success_unixtime %s\n' "$(date +%s)" > "$metric_tmp"
mv "$metric_tmp" "$metric_dir/report.prom"

Пользователь задания должен иметь доступ к каталогу, а exporter — читать итоговый файл. Временное имя не заканчивается на .prom, поэтому collector не должен воспринимать промежуточный документ как готовую метрику. Переименование в том же каталоге публикует полностью записанный результат. В рабочем скрипте также предусмотрите очистку временного файла при ошибке записи.

Число после имени — значение gauge с Unix-временем последнего успеха. Это не timestamp sample в формате exposition: textfile collector не поддерживает такие timestamps. Prometheus ставит время наблюдения при scrape, а возраст успешного результата вычисляется из значения метрики.

time() - report_last_success_unixtime

Получаются секунды с последнего успеха. Для суточной задачи порог нужно выбрать с учётом времени выполнения и допустимой задержки, например больше суток с запасом. Если задача ещё ни разу не выполнилась, самой серии может не быть; для этого нужен отдельный контроль отсутствия, а не только сравнение возраста.

Не обновлять метрику при неудаче

Запись должна происходить только после проверки выходного файла: ожидаемая структура, непустой набор данных или другой критерий конкретной выгрузки. Если команда завершилась нулём, но создала пустой отчёт, решите, считается ли это успехом по бизнес-контракту. Инфраструктура не определит такой смысл за вас.

На тестовом запуске выполните успешную обработку и проверьте значение через endpoint exporter. Затем вызовите контролируемую ошибку: timestamp должен остаться прежним, а возраст продолжить расти. Это проверяет главный контракт метрики. Дополнительно смотрите ошибки парсинга textfile, чтобы опечатка в формате не превратилась в молчаливую потерю сигнала.

Для нескольких заданий используйте небольшой стабильный набор меток, например job_name. Не создавайте новую серию на каждый идентификатор запуска. Историю отдельных попыток удобнее хранить в журнале, а метрика должна быстро отвечать на один операционный вопрос: насколько свеж последний пригодный результат.

Продолжить практику

Одно выражение или правило становится полезным, когда связано с конкретным действием инженера. В программе курса «Prometheus и Grafana: мониторинг и observability» — метрики учебного сервиса, exporters, обзорный и диагностический дашборды, SLI/SLO и алерты с инструкциями. Практика включает воспроизведение отказа или роста задержек и расследование по сигналам системы. Это продолжение для тех, кто хочет собрать мониторинг, по которому можно принимать решения во время сбоя.

Посмотреть программу курса

Источник: официальная документация.

Другие задачи по теме: Метрики и уведомления без неверных выводов.

Продолжить на практике

  • Prometheus и Grafana: мониторинг и observability ↗

    Замечайте сбои до жалоб пользователей. Соберите мониторинг приложения: метрики Prometheus, запросы PromQL, дашборды Grafana и алерты, по которым понятно, что делать. Итог — наблюдаемый сервис и разбор учебного инцидента.