Tuesday, March 22, 2011

Выделенный сервер логов

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

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

  • единое место хранения / формат логов;

  • удобство настройки политики обработки логов;

  • вынос с серверов приложений непрофильной для них задачи;

  • повышение безопасности (чистка логов становится не такой простой задачей).



Как же нам реализовать такой выделенный сервер логов? К счастью, у нас есть *nix с его с его системой логирвания - syslog. Syslog - это демон, способный обрабатывать запросы на логирование от ядра системы, различных служб и приложений, а так же удалённых серверов. Протокол работы syslog стандартизирован в RFC 3164.

Существует несколько реализаций syslog'a: syslogd, syslog-ng, rsyslogd (реализации расположены в порядке возрастания их навороченности). В данной статье приводятся примеры для syslog-ng.



Syslog оперирует следующими понятиями (настраиваемыми в его конфиге - /etc/syslog-ng/syslog-ng.conf):

  • source - источник логов (файл, сеть и т.д.);

  • filter - фильтр логов (тип сервиса, приоритет, имя приложения, хост, regexp и т.д.);

  • destination - направление записи лога (файл, консоль, сеть и т.д.);

  • log - структура, объединяющая source, filter, destination.


Более подробное описание можно посмотреть в man-странице конфига (man syslog-ng.conf).

Ещё двумя важными атрибутами syslog являются тип источника сообщения (facility) и уровень логирования (severity). Оба атрибута очень удобно применять для фильтрации.

Рассмотрим пример конфигурации syslog для обработки логов некоторого приложения:

# Источник
source s_all {
# Собственные сообщения
internal();

# Стандартный источник логов в Linux (место, куда пишет функция syslog())
unix-stream("/dev/log");

# Сообщения от ядра
file("/proc/kmsg" log_prefix("kernel: "));

# Сообщения по UDP (порт 514)
udp();
};

# Направления
destination df_my_app_err { file("/var/log/my-app.err.log" template("$MESSAGE\n")); };
destination df_my_app_common { file("/var/log/my-app.log" template("$MESSAGE\n")); };

# Фильтры
filter f_my_app_err { facility(user) and level(err,crit,warn,notice); };
filter f_my_app_common { facility(user) and program(my_app) and not level(err,crit,warn,notice); };

# Логи
log {
source(s_all);
filter(f_my_app_err);
destination(df_my_app_err);
flags(final);
};
log {
source(s_all);
filter(f_my_app_common);
destination(df_my_app_common);
flags(final);
};


Настройки для ротации и сжатия находятся в отдельном конфигурационном файле (/etc/logrotate.d/syslog-ng).


Log4J


Работа с syslog'ом реализована уже почти во всех уважающих себя фреймворках для логирования. Так, например, Log4J имеет специальный appender для записи в syslog:

#log4j.appender.syslog=org.apache.log4j.net.SyslogAppender
#log4j.appender.syslog.syslogHost=log-server
#log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
#log4j.appender.syslog.layout.ConversionPattern=my-app: %d{yyyy-MM-dd HH:mm:ss} %5p - %m%n
#log4j.appender.syslog.Facility=USER


Стоит заметить, что syslog довольно криво обрабатывает stacktrace'ы, в виду того, что экранирует все управляющие символы (\t, \n) и удаляет пробелы из начала строк. Решением тут может послужить кастомизация стандартного SyslogAppender для Log4J с учётом всех странностей особенностей syslog.


PHP



В PHP есть нативная поддержка работы с syslog (функция syslog). Однако, не всё так просто - работать PHP умеет только с локальным сервером syslog (это же касается и Log4PHP, суть соответствующего appender'а которого сводиться к вызову PHP-фунции syslog). Для работы с удалённым сервером придётся писать свою реализацию клиента, работающего через запись в сокет.


Полезные ссылки



1 comment:

  1. Юзаю log4cpp в проекте, пишу в syslog на удаленной машине - красота))

    ReplyDelete