Где логи cron и как сохранять вывод задач
Cron хранит две разные вещи, и их часто ищут не там. Лог cron записывает, что команда была запущена. Вывод задачи — всё, что команда напечатала, — уходит в другое место или пропадает совсем. Здесь — где найти и то и другое в популярных системах и как сохранять вывод, чтобы потом его прочитать.
Где лог cron
| Система | Где смотреть |
|---|---|
| Ubuntu, Debian с rsyslog | grep CRON /var/log/syslog |
| Debian 12 и другие системы только с journald | journalctl -u cron --since today |
| RHEL, Rocky, AlmaLinux, Fedora, CentOS | /var/log/cron или journalctl -u crond |
| Alpine (crond из BusyBox) | /var/log/messages, если запущен syslog |
| macOS | log show --last 1h --predicate 'process == "cron"' |
Обычная строка выглядит так:
Nov 6 03:17:01 web1 CRON[48211]: (deploy) CMD (/srv/backup.sh)
Она говорит, что в 03:17 cron запустил /srv/backup.sh от пользователя deploy. Но не говорит, сработал ли скрипт. Если в нужное время такой строки нет, проблема в расписании, в crontab или в самом демоне; всё это по порядку разобрано в чек-листе для незапускающейся задачи.
Куда по умолчанию уходит вывод
Всё, что печатает задача, cron отправляет письмом владельцу crontab через локальную почту. На современном сервере её обычно нет, и вывод выбрасывается. Debian и Ubuntu честно пишут об этом в лог:
CRON[48211]: (CRON) info (No MTA installed, discarding output)
Направить письма на другой адрес можно строкой MAILTO=you@example.com в начале crontab, но только если сервер действительно умеет отправлять почту. MAILTO="" отключает письма.
Сохраните вывод в файл
Самое простое — перенаправить оба потока вывода в файл:
17 3 * * * /srv/backup.sh >> /var/log/backup.log 2>&1
>>дописывает в конец, так что каждый запуск добавляется к файлу, а не затирает его.2>&1отправляет ошибки в тот же файл. Порядок важен: при2>&1 >> fileошибки по-прежнему уходят в почту cron.- Пользователь, от которого работает задача, должен иметь право писать в файл. Создайте его один раз с нужным владельцем:
touch /var/log/backup.log && chown deploy /var/log/backup.log.
Добавьте время
Лог без времени трудно читать, когда задача запускается раз в несколько минут. Перенесите перенаправление и строку о старте в сам скрипт:
#!/bin/sh exec >> /var/log/backup.log 2>&1 echo "$(date '+%F %T') start" pg_dump -Fc app > /backups/app-$(date +%F).dump status=$? echo "$(date '+%F %T') done, exit $status" exit $status
Дата внутри скрипта заодно избавляет от классической ловушки: в строке crontab знак % означает перевод строки, и там date +%F пришлось бы писать как date +\%F.
Или отправьте вывод в syslog
Чтобы вывод задачи лежал рядом с остальными системными логами, передайте его в logger:
17 3 * * * /srv/backup.sh 2>&1 | logger -t backup
Читать — journalctl -t backup или grep backup /var/log/syslog. Одна тонкость: код завершения такой строки — это код logger, а не бэкапа, поэтому всё, что его проверяет, увидит успех.
Не дайте файлу расти бесконечно
Задача, которая запускается каждую минуту, может забить диск своим логом. Добавьте правило logrotate:
# /etc/logrotate.d/backup
/var/log/backup.log {
weekly
rotate 8
compress
missingok
notifempty
}
Лог показывает, что случилось, но не то, чего не случилось
Даже идеальный лог помогает, только если его кто-то читает. Если задача перестала запускаться, в лог не пишется ничего, а пустой лог выглядит так же, как спокойный. Обычное решение — пульс: задача после каждого запуска отправляет пинг на адрес, и вы получаете алерт, если пинг не пришёл вовремя или сообщил об ошибке.
С утилитой heartcron это одна правка строки crontab. Она сообщает о старте, код завершения и конец вывода, так что вывод упавшего запуска будет прямо в алерте:
17 3 * * * heartcron run nightly-backup -- /srv/backup.sh >> /var/log/backup.log 2>&1
Без утилиты сначала сохраните код завершения, а потом отправьте его вместе с выводом:
out=$(/srv/backup.sh 2>&1); code=$? printf '%s' "$out" | tail -c 100000 | curl -fsS -m 10 --data-binary @- https://ping.heartcron.com/<uuid>/$code
Создайте проверку с тем же расписанием, что и в crontab; расшифровщик cron-выражений покажет ближайшие запуски, если хотите перепроверить. Все сигналы — в документации.