- PVSM.RU - https://www.pvsm.ru -
log4j широкоизвестная библиотека логирования, нашедшая своё применение во многих проектах. Её возможности не ограничиваются «добавлением строчек в лог-файлы». На базе log4j можно организовать сложную систему агрегации логов на центральный сервер. Кроме того, сообщество располагает GUI утилитами для анализа логов, которые удобно подключать к центральному серверу для анализа логов.
Когда в компании появляется несколько серверов или россыпь разнообразных приложений логирующих данные в разные файлы, становится крайне не удобным отслеживать все события происходящие в приложениях. Иногда это становится не возможным ввиду отсутствия прав доступа к тому или иному серверу. Именно в таких системах возникает необходимость агрегирования данных на одном центральном сервере. Рассмотрим наиболее простой способ реализации такой системы с использованием библиотеки log4j.

Интеграция log4j в Java проект чрезвычайна проста. Нужно подключить саму библиотеку и создать файл конфигуарции log4j.properties или log4j.xml. Если рассматривать maven проект, то его конфигурация будет примерно следующая.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.github.caiiiycuk</groupId> <artifactId>log4j-app</artifactId> <version>1.0</version> <name>log4j app</name> <dependencies> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies> </project>
import org.apache.log4j.Logger;
public class Log4JApp {
private final static Logger LOGGER = Logger.getLogger(Log4JApp.class);
public static void main(String[] args) throws InterruptedException {
while (true) {
LOGGER.debug("I'm doing science and I'm still alive.");
LOGGER.info("I feel fantastic and I'm still alive.");
LOGGER.warn("While you're dying I'll be still alive.");
LOGGER.error("And when you're dead I will be, still alive.");
LOGGER.fatal("Still alive, still alive.");
Thread.sleep(1000);
}
}
}
log4j.rootLogger=debug, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Шаблон лог сообщения log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
Файл log4j.properties должен находиться в classpath, что бы log4j смог обнаружить его. Возможно явно указать расположения файла конфигурации с помощью аргумента командной строки java -Dlog4j.configuration=pathToFile, подробнее о конфигурации log4j [1].
В log4j есть понятие appender, он определяет обработчиков событий, в примере мы использовали стандартный ConsoleAppender который логирует все события в консоль. По счастью в стандартный набор входят так же SocketAppender и SocketHubAppender.
SocketAppender [2] создаёт подключение к удаленному лог серверу и отправляет события на этот сервер. Причем посылаются сериализованные LoggingEvent, т. е. передаётся вся информация о событии а не строка. В случае если удалённый сервер не доступен, сообщения будут отбрасываться, когда же сервер заработает вновь соеденение будет востановленно автоматически.
SocketHubAppender [3] похож на SocketAppender, но работает наоборот. SocketHubAppender создаёт сокет на который могут подключаться удалённые клиенты и при возникновении событий они отправляются всем подключенным клиентам.
Что бы настроить log4j на работу с удалённым сервером в конфигурацию нужно добавить следующее:
log4j.rootLogger=DEBUG, stdout, server (...) log4j.appender.server=org.apache.log4j.net.SocketAppender log4j.appender.server.Port=4560 log4j.appender.server.RemoteHost=localhost log4j.appender.server.ReconnectionDelay=10000 log4j.appender.server.Application=Log4JApp log4j.appender.server.LocationInfo=true
С такими настройками приложение будет пытаться подключится к localhost:4560 для отправки лог сообщений. Теперь, настало время настроить сервер который будет агрегировать сообщения. Такой сервер можно запустить одной командой.
java -classpath log4j.jar org.apache.log4j.net.SimpleSocketServer 4560 log4j-server.properties
Первый параметр это порт сервера, а второй конфигурация логера сервера. Все сообщения которые поступают на сервер будут обрабатываться так, как будто сам сервер сгенерировал эти события, т.е. так как вы сконфигурируете log4j-server.properties так и будут сообщения выводиться. Так можно организовывать сложные цепочки пересылки сообщения от сервера к серверу.
Если одновременно запустить сервер и клиент, то в консоле сервера будут печататься все сообщения которые произошли на клиенте (при условии что вы добавили ConsoleAppender).
log4j.rootLogger=debug, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Шаблон лог сообщения log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
Вывод в консоль
INFO [main] (SimpleSocketServer.java:60) - Listening on port 4560 INFO [main] (SimpleSocketServer.java:63) - Waiting to accept a new client. INFO [main] (SimpleSocketServer.java:65) - Connected to client at /127.0.0.1 INFO [main] (SimpleSocketServer.java:66) - Starting new socket node. INFO [main] (SimpleSocketServer.java:63) - Waiting to accept a new client. DEBUG [main] (Log4JApp.java:9) - I'm doing science and I'm still alive. INFO [main] (Log4JApp.java:10) - I feel fantastic and I'm still alive. WARN [main] (Log4JApp.java:11) - While you're dying I'll be still alive. ERROR [main] (Log4JApp.java:12) - And when you're dead I will be, still alive. INFO [SimpleSocketServer-4560] (SocketNode.java:94) - Caught java.io.EOFException closing conneciton.
Все логи теперь собираются на одном сервере, сконфигурируем сервер что бы он открывал сокет и отправлят события подключенным клиентам. Для этого нужно использовать SocketHubAppender.
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) — %m%n
log4j.appender.server=org.apache.log4j.net.SocketHubAppender
log4j.appender.server.Port=4561
log4j.appender.server.LocationInfo=true
С такой конфигурацией можно подключаться к серверу программами для анализа логов.
chainsaw [4] — программа зародившаяся в недрах log4j, позволяет подключаться к SocketHub и отображать информацию о событиях в реальном времени. Кажется что chainsaw давно умер, т.к. последний билд был аж в 2006 году. Тем неменее с задачей своей справляется.
После запуска в chainsaw неообходимо добавить источник данных, щелкнув по соотвествующему значку в правой панели. В контекстном меню нужно выбрать SocketHubReciver, затем указать хост, порт и имя. В случае успеха в главной панели появится одноимённая вкладка в которой будут отображаться последние произошедшие события. chainsaw обладает достаточно примитивными возможностями фильтрации событий по уровню и по приложению, все события хранит в памяти, поэтому при большом их количестве начинаются тормажения. Не рекомендую к использованию.
otroslogviewer [5] — более современная программа, которая активно развивается. Подключение к SocketHub выполняется через пункт меню File -> Connect to Log4J SocketHub. Точно так же указываете хост и порт. Отображение событий будет происходить в новой закладке в главной панели.
Внешне конечно выглядит страшно, Swing от него не уйдешь, но зато функционал здесь гораздо богаче. Гибкие фильтры по уровню, времени, вхождению строки, потокам и прочее прочее.
lilith [6] — автор заявляет, что данная программа может работать с SocketHub. Но я так и не понял как её настроить.
SocketHubAppender не предусматривает возможность какой-либо авторизации, т.е. теоретически к нему могут подключаться любые пользователи. Поэтому открыть в глобальный доступ такого рода сервер логов апрометчиво. Самый простой способ обезопаситься — пробрасывать порты через ssh тунель. Т.е. запускаем сервер на удаленной машине на порту 4561, но закрываем доступ на этот порт с помощью фаервола. Когда же появляется необходимость посмотреть последнии события пробрасываем порты командой.
ssh -L 4561:localhost:4561 remote-host
После этого можно подключаться анализаторами логов к localhost:4561.
P. S. Существуют и другие технологии решающие эту задачу например scribe [7] от facebook, но как мне кажется, для простых проектов его преимущества не значительны, а настроить его сложнее.
Автор: Caiiiycuk
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/29150
Ссылки в тексте:
[1] log4j: http://logging.apache.org/log4j/1.2/manual.html
[2] SocketAppender: http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/net/SocketAppender.html
[3] SocketHubAppender: http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/net/SocketHubAppender.html
[4] chainsaw: http://logging.apache.org/chainsaw/
[5] otroslogviewer: http://code.google.com/p/otroslogviewer/
[6] lilith: http://lilith.huxhorn.de/
[7] scribe: https://github.com/facebook/scribe
[8] Источник: http://habrahabr.ru/post/172075/
Нажмите здесь для печати.