Linux

Мониторинг systemd-сервисов: полное руководство по проверке статуса и логов

Это руководство научит вас comprehensively monitor systemd services: проверять их статус, анализировать логи в реальном времени и настраивать базовые оповещения. Вы сможете быстро диагностировать сбои и обеспечивать стабильность системы.

Обновлено 8 апреля 2026 г.
15-30 мин
Средняя
FixPedia Team
Применимо к:Ubuntu 20.04+CentOS/RHEL 8+Debian 11+Fedora 35+

Введение / Зачем это нужно

Systemd — это современная система инициализации и менеджер служб в большинстве дистрибутивов Linux. Мониторинг её сервисов критически важен для поддержания стабильности сервера или рабочей станции. Без регулярной проверки вы можете не заметить, как важный фоновый процесс (база данных, веб-сервер, агент бэкапа) остановился из-за ошибки или нехватки ресурсов.

Это руководство даёт вам полный набор инструментов для proactive monitoring: от однократной диагностики до настройки автоматических оповещений. Вы научитесь быстро определять, жив ли сервис, где искать логи при падении и как настроить систему на самоуведомление о проблемах.

Требования / Подготовка

  1. Доступ к терминалу с правами sudo или root для проверки системных служб. Для пользовательских служб (user services) права не требуются.
  2. Базовое понимание systemd: знание, что такое юнит (.service), и как управлять службами (start, stop, enable).
  3. Актуальная версия systemd (обычно 245+ на современных дистрибутивах). Проверить: systemctl --version.
  4. Для шага с 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=. Это более надёжно, чем внешние скрипты-полинги.

  1. Создайте службу-нотификатор (например, 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
    
  2. Создайте простой скрипт-нотификатор (настройте под вашу систему: 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
    
  3. Добавьте OnFailure в конфиг вашего сервиса:
    # /etc/systemd/system/your-critical.service
    [Unit]
    Description=My Critical App
    OnFailure=send-failure-alert.service
    ...
    
  4. Перезагрузите демон systemd: sudo systemctl daemon-reload.

Теперь при аварийном завершении your-critical.service будет запущен send-failure-alert.service.

Шаг 5: Визуализация и внешние инструменты

Для долгосрочного мониторинга и исторических графиков подключите систему к сборщику метрик.

  • Netdata: Установите netdata, и он автоматически обнаружит и начнёт отображать статус systemd-сервисов в веб-интерфейсе (http://server:19999).
  • Prometheus + node_exporter: Коллектор node_exporter имеет текстовыйcollector systemd, который экспортирует метрики 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, если письмо приходит пустым).

Проверка результата

  1. Тест на сбой: Намеренно остановите тестовый сервис (sudo systemctl stop nginx). Убедитесь, что:
    • systemctl status nginx показывает inactive (dead) или failed.
    • journalctl -u nginx.service -f показывает записи о остановке.
    • Если настраивали OnFailure, ваш скрипт-нотификатор должен сработать.
  2. Проверка скрипта мониторинга: Запустите ./monitor_critical.sh и убедитесь, что он корректно определяет статусы и выводит логи для неактивных сервисов.
  3. Проверка 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.

Часто задаваемые вопросы

В чём разница между `systemctl status` и `journalctl` для диагностики?
Как настроить автоматическое оповещение при падении критического сервиса?
Почему `journalctl` не показывает логи моего сервиса, хотя он работает?
Как мониторить службы без root-прав?

Полезное

Проверка базового статуса сервиса
Анализ логов через journalctl
Мониторинг нескольких сервисов одновременно
Настройка оповещений через systemd
Визуализация с помощью third-party инструментов
Автоматизация проверки и создания отчётов

Эта статья помогла вам решить проблему?