Введение / Зачем это нужно
Systemd — это современная система инициализации и менеджер служб в большинстве дистрибутивов Linux. Мониторинг её сервисов критически важен для поддержания стабильности сервера или рабочей станции. Без регулярной проверки вы можете не заметить, как важный фоновый процесс (база данных, веб-сервер, агент бэкапа) остановился из-за ошибки или нехватки ресурсов.
Это руководство даёт вам полный набор инструментов для proactive monitoring: от однократной диагностики до настройки автоматических оповещений. Вы научитесь быстро определять, жив ли сервис, где искать логи при падении и как настроить систему на самоуведомление о проблемах.
Требования / Подготовка
- Доступ к терминалу с правами sudo или root для проверки системных служб. Для пользовательских служб (user services) права не требуются.
- Базовое понимание systemd: знание, что такое юнит (
.service), и как управлять службами (start,stop,enable). - Актуальная версия systemd (обычно 245+ на современных дистрибутивах). Проверить:
systemctl --version. - Для шага с
OnFailureпотребуется редактирование конфигурационных файлов в/etc/systemd/system/и выполнениеsystemctl daemon-reloadпосле изменений.
Шаг 1: Проверка базового статуса сервиса
Самый быстрый способ понять, что происходит с сервисом — команда systemctl status.
# Замените nginx на имя вашего сервиса
sudo systemctl status nginx
Что смотреть в выводе:
Active:— статус (active (running),inactive (dead),failed).Main PID:— ID главного процесса. Если 0, сервис, скорее всего, упал.CGroup:— дерево процессов, принадлежащих сервису.- Последние несколько строк журнала — самая ценная информация при сбое. Часто там указана прямая причина ошибки (например, "Permission denied" или "Port already in use").
Шаг 2: Глубокий анализ логов через journalctl
Если systemctl status не даёт достаточно деталей, используйте journalctl — основной инструмент для работы с журналом systemd.
# Показать все записи для конкретного сервиса
sudo journalctl -u nginx.service
# Следить за логами в реальном времени (как tail -f)
sudo journalctl -u nginx.service -f
# Показать только сообщения об ошибках и критических проблемах
sudo journalctl -u nginx.service -p err..crit
# Показать логи за последний час
sudo journalctl -u nginx.service --since "1 hour ago"
# Показать логи с момента последней загрузки системы
sudo journalctl -u nginx.service -b
Фильтрация по приоритету: Уровни: emerg (0), alert (1), crit (2), err (3), warning (4), notice (5), info (6), debug (7). -p err..crit покажет всё от ошибок и выше.
Шаг 3: Мониторинг нескольких сервисов одновременно
Для быстрого обзора состояния нескольких ключевых служб создайте простой скрипт.
#!/bin/bash
# Файл: monitor_critical.sh
SERVICES=("nginx" "postgresql" "redis-server" "ssh")
echo "=== Проверка статуса критичных сервисов $(date) ==="
for svc in "${SERVICES[@]}"; do
if systemctl is-active --quiet "$svc"; then
echo "✅ $svc: active"
else
echo "❌ $svc: INACTIVE or FAILED"
# Показать последние логи для упавшего сервиса
echo " Последние записи в journalctl:"
sudo journalctl -u "$svc" -n 5 --no-pager
fi
done
Сделайте скрипт исполняемым (chmod +x monitor_critical.sh) и запускайте его периодически через watch:
watch -n 30 ./monitor_critical.sh
Это обновляет вывод каждые 30 секунд.
Шаг 4: Настройка автоматических оповещений через systemd
Для критичных сервисов можно настроить реакцию systemd на сбой с помощью директивы OnFailure=. Это более надёжно, чем внешние скрипты-полинги.
- Создайте службу-нотификатор (например,
send-failure-alert.service):# /etc/systemd/system/send-failure-alert.service [Unit] Description=Send alert on service failure # Передаём имя упавшего сервиса через эквивалент %i # %i будет заменён на имя юнита, который вызвал OnFailure [Service] Type=oneshot ExecStart=/usr/local/bin/alert-script.sh %i - Создайте простой скрипт-нотификатор (настройте под вашу систему: email, slack, telegram):
#!/bin/bash # /usr/local/bin/alert-script.sh FAILED_SERVICE=$1 HOSTNAME=$(hostname) echo "Сбой сервиса $FAILED_SERVICE на хосте $HOSTNAME" | \ mail -s "ALERT: systemd failure on $HOSTNAME" admin@example.com - Добавьте
OnFailureв конфиг вашего сервиса:# /etc/systemd/system/your-critical.service [Unit] Description=My Critical App OnFailure=send-failure-alert.service ... - Перезагрузите демон systemd:
sudo systemctl daemon-reload.
Теперь при аварийном завершении your-critical.service будет запущен send-failure-alert.service.
Шаг 5: Визуализация и внешние инструменты
Для долгосрочного мониторинга и исторических графиков подключите систему к сборщику метрик.
- Netdata: Установите
netdata, и он автоматически обнаружит и начнёт отображать статус systemd-сервисов в веб-интерфейсе (http://server:19999). - Prometheus + node_exporter: Коллектор
node_exporterимеет текстовыйcollectorsystemd, который экспортирует метрикиsystemd_unit_state(1 для active, 0 для неактивного). Настройте алерты в Prometheus Alertmanager. - График загрузки:
systemd-analyze plot > boot.svgсоздаст SVG-файл с графиком времени загрузки каждого юнита. Полезно для поиска "тяжёлых" сервисов.
Шаг 6: Автоматизация ежедневных отчётов
Настройте cron-задачу для ежедневного отчёта об упавших сервисах.
# Откройте crontab для редактирования
sudo crontab -e
# Добавьте строку (отправлять отчёт в 8:00 утра)
0 8 * * * /usr/bin/systemctl list-units --type=service --state=failed --no-legend | \
awk '{print $1}' | \
while read unit; do
echo "=== $unit ==="
sudo journalctl -u "$unit" -n 10 --no-pager
echo ""
done | \
mail -s "Daily Systemd Failure Report for $(hostname)" admin@example.com
Если список упавших служб пуст, команда list-units ничего не выведет, и письмо не отправится (проверьте логи cron, если письмо приходит пустым).
Проверка результата
- Тест на сбой: Намеренно остановите тестовый сервис (
sudo systemctl stop nginx). Убедитесь, что:systemctl status nginxпоказываетinactive (dead)илиfailed.journalctl -u nginx.service -fпоказывает записи о остановке.- Если настраивали
OnFailure, ваш скрипт-нотификатор должен сработать.
- Проверка скрипта мониторинга: Запустите
./monitor_critical.shи убедитесь, что он корректно определяет статусы и выводит логи для неактивных сервисов. - Проверка cron-задачи: Можно запустить команду из crontab вручную и проверить, приходит ли письмо.
Возможные проблемы
Failed to connect to bus: No such file or directoryпри запускеsystemctlбез sudo от обычного пользователя. Решение: Используйтеsudoили настройте права через PolicyKit (продвинутая тема). Для пользовательских служб используйтеsystemctl --user status.Journal has been rotated since unit was startedили отсутствие логов вjournalctl. Решение: Логи могли быть очищены или перемещены. Проверьте место на диске в/var/log/journal/или/run/log/journal/. Убедитесь, что systemd-journald работает (systemctl status systemd-journald).- Сервис падает сразу после запуска, но
systemctl statusне показывает явной ошибки. Решение: Смотрите логи с самого начала загрузки юнита:sudo journalctl -u <сервис> -b -e(последние записи текущей загрузки) илиsudo journalctl -u <сервис> --since "5 minutes ago". - Оповещение через
OnFailureне срабатывает. Решение: Убедитесь, чтоsend-failure-alert.serviceсуществует, включён (systemctl enable send-failure-alert.service) и что в конфиге основного сервиса правильно указано имя службы-нотификатора. Проверьте логи самогоsend-failure-alert.serviceчерезjournalctl -u send-failure-alert.service.