Мониторинг работы с помощью syslog

С помощью syslog удобно отслеживать работу системы. Так выглядят сообщения из сислога, по которым можно искать, либо передавать на анализ в другие системы:

Сбор данных

Предварительно необходимо настроить syslog, чтобы в него попадали сообщения (на убунте было выключено, и *.warning никуда не писался).

Включение записи в syslog

Отредактируем файл конфигурации:

sudo vim /etc/rsyslog.d/50-default.conf

В нем добавить или подправить: *.info;mail.none;authpriv.none;cron.none /var/log/messages.

Фильтрация сислога PHP в отдельный файл

Для удобства можно все нужные сообщения писать в отдельный файл, для чего сделать отдельный конфиг с фильтром:

echo ':syslogtag,contains,"php" /var/log/php.log' > /etc/rsyslog.d/10-php.conf
sudo service rsyslog restart

На одном сервере можно в сислоге найти сообщения от php, php56 и php56-cgi. Эти различия объясняются вариантами версий и SAPI.

При получении такого сообщения:

Feb 4 13:06:02 web rsyslogd-2177: imuxsock lost 433 messages from pid 9620 due to rate-limiting

можно увеличить лимит SystemLogRateLimitInterval и SystemLogRateLimitBurst

Какие фильтры сислога существуют

:property, compare-operation, "value"

- фильтр по свойству, где compare-operation может быть contains, isequal, startswith, regex, ereregex.

:msg, contains, "error"

- фильтр по тексту error

:msg, regex, "login .* failed"

- регулярка по тексту

Выставление уровня ошибок

Какой уровень фильтрации ошибок выставить? Информация для размышления:

  • Уровней ошибок 6 + 1 (отладка)
  • Уровень ошибки в лог не пишется (но можно по этому признаку писать в разные файлы)
  • LOG_EMERG использовать осторожно, так как вывод также попадает в Linux-консоль, и будет очень трудно работать на сервере, если таких сообщений будет много (например, при каждом открытии страницы будет ошибка соединения с БД)

Как писать в лог из PHP

функции openlog() и closelog() не обязательно использовать, достаточно syslog().

syslog.php
// будет заменен тег "php" => "myapp", эту часть можно добавить в `auto_prepend_file` или единую точку входа `index.php`
openlog("myapp", LOG_PID | LOG_ODELAY | LOG_PERROR, LOG_LOCAL0); // не обязательно
 
// LOG_PID - писать PID
// LOG_ODELAY - отложить открытие syslog до первого сообщения об ошибке
// LOG_PERROR - также выводить в STD_ERR
// LOG_LOCAL0 - "тип". @see http://php.net/manual/ru/function.openlog.php
 
syslog(LOG_EMERG,   'система непригодна'); // также выводится во все терминалы
syslog(LOG_ALERT,   'необходимы незамедлительные меры');
syslog(LOG_CRIT,    'критические условия');
syslog(LOG_ERR,     'условия ошибки');
syslog(LOG_WARNING, 'условия предупреждения');
syslog(LOG_NOTICE,  'нормальные, но значительные условия');
syslog(LOG_INFO,    'информационное сообщение');
syslog(LOG_DEBUG,   'сообщение отладки'); // обычно не попадает в журнал syslog
 
// Использование closelog() - опционально
closelog();

Для себя я определил 4 уровня, которые также передаются в тексте сообщения:

syslog.php
// Необходимо срочно починить, перестал работать Sphinx
syslog(LOG_ALERT, '[Sign][docs.list][alert]Sphinx is gone away');
 
// Ошибка, веб-сервис не ответил
syslog(LOG_ERR, '[1C exchange][ws.debt][error]Empty response from web service');
 
// У пользователи произошел сбой, но это скорее его вина
syslog(LOG_WARNING, '[Sign][user.sign][warning]User has wrong sign');
 
// Информационное сообщение (для статистики)
syslog(LOG_INFO, '[Sign][doc.sign][info][1100]Document was signed');

Формат сообщения

Для удобства анализа следует выработать единый формат сообщения, например такой:

[раздел сайта][действие или процесс][результат][прочие теги]: описание сообщения

Подробнее о формате сообщения для syslog

Как писать в лог из других языков

Bash:

logger "[LK 2.0] Hello from bash"

NodeJS:

nodejs ~/myapp.js 2>&1 | logger &

Куда можно писать сислог

Строка конфигурации Куда идет запись
auth.err /var/log/messages В файл /var/log/messages
daemon.* /dev/lpr2 Распечатка на принтере lpr2
auth-priv root,likegeeks В терминал пользователям root и likegeeks, если они залогинены
kern.crit |/var/log/mypipe В пайп /var/log/mypipe, который можно создать через mkfifo
mail @@likegeeks.local Письмо на хост likegeeks.local по TCP, порт 514; rsyslog нужно запустить с опцией -r; @@ - указание на использование TCP
auth.* >dbhost,dbname,dbuser,dbpassword;dbtemplate В базу данных

Взято отсюда

Анализ полученных данных

Собранный syslog возможно либо грепить grep, либо передавать и использовать в более продвинутой системе ELK.

Для информации, можно посмотреть процессы, которые пишут в сислог:

sudo cat /var/log/messages | cut -d" " -f5 | sort | uniq

Ссылки