Статьи

Новый log4j 2.0

Вскоре была выпущена новая основная версия хорошо известного каркаса log4j. С момента появления первой альфа-версии произошло еще 4 релиза!

Видите ли, активность намного выше, чем у предшественника log4j 1. И, если серьезно, несмотря на молодой возраст log4j 2s, это намного лучше.

В этом блоге дается обзор некоторых замечательных возможностей Apache log4j 2.0 .

Современный API

В старые времена люди писали такие вещи:

1
2
3
if(logger.isDebugEnabled()) {
   logger.debug('Hi, ' + u.getA() + “ “ + u.getB());
}

Многие жаловались на это: это очень нечитаемо. А если забыть окружающее условие if, результатом будет множество ненужных строк. В наши дни создание String, скорее всего, оптимизируется современной JVM, но стоит ли полагаться на JVM-оптимизацию?

Команда log4j 2.0 подумала о таких вещах и улучшила API. Теперь вы можете написать так же, как это:

1
logger.debug('Hi, {} {}', u.getA(), u.getB());

Новый и улучшенный API поддерживает заполнители с переменными аргументами, как это делают другие современные каркасы журналирования.

Существует больше сладостей API, таких как маркеры и отслеживание потока :

1
2
3
4
5
6
7
8
9
private Logger logger = LogManager.getLogger(MyApp.class.getName());
private static final Marker QUERY_MARKER = MarkerManager.getMarker('SQL');
...
 
public String doQuery(String table) {
   logger.entry(param);
   logger.debug(QUERY_MARKER, 'SELECT * FROM {}', table);
   return logger.exit();
}

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

1
2
19:08:07.056 TRACE com.test.TestService 19 retrieveMessage - entry
19:08:07.060 TRACE com.test.TestService 46 getKey - entry

Плагин Архитектура

log4j 2.0 поддерживает архитектуру плагинов. Расширение log4j 2 для ваших собственных нужд стало невероятно простым. Вы можете создавать свои расширения в выбранном вами пространстве имен, и вам просто нужно указать платформе, где искать.

1
<configuration packages='de.grobmeier.examples.log4j2.plugins'>

С вышеупомянутой конфигурацией log4j 2 будет искать плагины в пакете de.grobmeier.examples.log4j2.plugins. Если у вас есть несколько пространств имен, нет проблем. Это список через запятую.

Простой плагин выглядит так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
@Plugin(name = 'Sandbox', type = 'Core', elementType = 'appender')
public class SandboxAppender extends AppenderBase {
 
    private SandboxAppender(String name, Filter filter) {
        super(name, filter, null);
    }
 
    public void append(LogEvent event) {
        System.out.println(event.getMessage().getFormattedMessage());
    }
 
    @PluginFactory
    public static SandboxAppender createAppender(
         @PluginAttr('name') String name,
         @PluginElement('filters') Filter filter) {
        return new SandboxAppender(name, filter);
    }
}

Метод с аннотацией @PluginFactory выглядит как фабричный. Два аргумента фабрики считываются напрямую из файла конфигурации. Я достиг такого поведения с использованием @PluginAttr и @PluginElement в своих аргументах.

Остальное тоже довольно тривиально. Поскольку я написал appender, я решил расширить AppenderBase. Это заставляет меня реализовать метод append (), который выполняет реальную работу. Помимо Appenders, вы даже можете написать свой собственный регистратор или фильтр. Просто взгляните на документы .

Мощная конфигурация

Новая конфигурация log4j 2 стала проще. Не волнуйтесь, если вы могли бы понять старый способ настройки log4j, вам понадобится совсем немного времени, чтобы изучить отличия от нового способа. Это выглядит так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<?xml version='1.0' encoding='UTF-8'?>
<configuration status='OFF'>
  <appenders>
    <Console name='Console' target='SYSTEM_OUT'>
      <PatternLayout pattern='%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n'/>
    </Console>
  </appenders>
  <loggers>
    <logger name='com.foo.Bar' level='trace' additivity='false'>
      <appender-ref ref='Console'/>
    </logger>
    <root level='error'>
      <appender-ref ref='Console'/>
    </root>
  </loggers>
</configuration>

Пожалуйста, посмотрите на раздел appenders. Вы можете использовать речевые теги, например, совпадающие с именем аппендера. Нет больше имен классов. Ну, этот документ XML не может быть проверен, конечно. В случае, если вам срочно требуется проверка XML, вы все равно можете использовать более строгий формат xml, который напоминает старый формат:

1
2
3
4
5
6
<appenders>
   <appender type='type' name='name'>
     <filter type='type' ... />
   </appender>
   ...
</appenders>

Но это не все. Вы даже можете перезагрузить свою конфигурацию автоматически :

1
2
3
4
<?xml version='1.0' encoding='UTF-8'?>
<configuration monitorInterval='30'>
...
</configuration>

Интервал мониторинга — это значение в секундах, минимальное значение — 5. Это означает, что log4j 2 перенастроит ведение журнала на случай, если что-то изменилось в вашей конфигурации. Если установлено в ноль или пропущено, обнаружение изменений не произойдет. Лучшее: log4j 2.0 не теряет события регистрации во время реконфигурации , в отличие от многих других платформ.

Но есть еще более захватывающие вещи. Если вы предпочитаете JSON XML, вы можете использовать конфигурацию JSON:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
    'configuration': {
        'appenders': {
            'Console': {
                'name': 'STDOUT',
                'PatternLayout': {
                    'pattern': '%m%n'
                }
            }
        },
        'loggers': {
            'logger': {
                'name': 'EventLogger',
                'level': 'info',
                'additivity': 'false',
                'appender-ref': {
                    'ref': 'Routing'
                }
            },
            'root': {
                'level': 'error',
                'appender-ref': {
                    'ref': 'STDOUT'
                }
            }
        }
    }
}

Новая конфигурация действительно мощная и поддерживает такие вещи, как подстановка свойств . Проверьте их более подробно на страницах руководства .

log4j 2.0 — командный игрок: slf4j и друзья

Apache log4j 2.0 имеет много интеграций. Это хорошо работает, если ваше приложение все еще работает с Commons Logging . Мало того, вы можете использовать его с slf4j . Вы можете подключить приложение log4j 1.x к использованию log4j 2 в фоновом режиме. И еще одна возможность: log4j 2 поддерживает Apache Flume . Flume — это распределенный, надежный и доступный сервис для эффективного сбора, агрегирования и перемещения больших объемов данных журнала .

Java 5 параллелизм

Из документов: «log4j 2 использует поддержку параллелизма Java 5 и выполняет блокировку на самом низком возможном уровне». Apache log4j 2.0 решает многие проблемы взаимоблокировок, которые все еще находятся в log4j 1.x. Если вы страдаете от утечек памяти в log4j 1.x, вам обязательно стоит взглянуть на log4j 2.0.

Построен на Apache Software Foundation

Как log4j 1.x, log4j 2.x является проектом Apache Software Foundation. Это означает, что он лицензирован с помощью «Apache License 2.0? и таким образом останется свободным. Вы можете создать свой собственный продукт на нем, вы можете изменять его в соответствии со своими потребностями, и вы можете распространять его, даже в коммерческих целях.
Вам не нужно заботиться об интеллектуальной собственности. Apache Software Foundation заботится об этом. Если вы хотите узнать больше о лицензировании и о том, как вы можете использовать log4j 2.0 для своего собственного проекта, я отсылаю вас к FAQ по лицензированию .

Ссылка: новый log4j 2.0 от нашего партнера по JCG Кристиана Гробмайера в блоге PHP и Java Entwickler .