Создание плагинов log4j

204
19 августа 2018, 01:50

Пытаюсь написать свой Layout. Пишу простейший класс

package test;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.MessageLayout;
@Plugin(
    name = "TestLayout",
    category = "Core",
    elementType = "layout",
    printObject = true
)
public class TestLayout extends MessageLayout {
    @PluginFactory
    public static Layout<?> createLayout() {
        return new TestLayout();
    }
}

в файле конфигурации его вообще не упоминаю

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" strict="true" packages="test">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT"/>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

(наличие или отсутствие атрибута packages="test" на картину не влияет)

В проекте еще один класс

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Test {
    static public void main(String[] args) {
        Logger log = LogManager.getLogger("test");
        log.error("Test");
    }
}

при запуске из Intelij все работает (а если еще добавить свой Layout в конфигурацию, то он тоже начинает работать). А вот при запуске jar получаю картину

ERROR StatusLogger Unrecognized format specifier [d]
ERROR StatusLogger Unrecognized conversion specifier [d] starting at position 16 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [thread]
ERROR StatusLogger Unrecognized conversion specifier [thread] starting at position 25 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [level]
ERROR StatusLogger Unrecognized conversion specifier [level] starting at position 35 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [logger]
ERROR StatusLogger Unrecognized conversion specifier [logger] starting at position 47 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [msg]
ERROR StatusLogger Unrecognized conversion specifier [msg] starting at position 54 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [n]
ERROR StatusLogger Unrecognized conversion specifier [n] starting at position 56 in conversion pattern.
ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2
ERROR StatusLogger Unrecognized format specifier [d]
ERROR StatusLogger Unrecognized conversion specifier [d] starting at position 16 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [thread]
ERROR StatusLogger Unrecognized conversion specifier [thread] starting at position 25 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [level]
ERROR StatusLogger Unrecognized conversion specifier [level] starting at position 35 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [logger]
ERROR StatusLogger Unrecognized conversion specifier [logger] starting at position 47 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [msg]
ERROR StatusLogger Unrecognized conversion specifier [msg] starting at position 54 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [n]
ERROR StatusLogger Unrecognized conversion specifier [n] starting at position 56 in conversion pattern.
%d [%thread] %-5level %logger - %msg%n

Что я делаю не так? Если убрать класс TestLayout из проекта, то jar тоже начинает работать

Update

Если установить

log4j2.debug = true

и сравнить логи при наличии плагина и при его отсутствии, то получается такая картина:

  • при наличии

    DEBUG StatusLogger Not in a ServletContext environment, thus not loading WebLookup plugin.
    DEBUG StatusLogger Took 0,104801 seconds to load 205 plugins from sun.misc.Launcher$AppClassLoader@4e25154f
    DEBUG StatusLogger PluginManager 'Converter' found 44 plugins
    .........
    DEBUG StatusLogger Installed 1 script engine
    DEBUG StatusLogger Oracle Nashorn version: 1.8.0_25, language: ECMAScript, threading: Not Thread Safe, compile: true, names: [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript], factory class: jdk.nashorn.api.scripting.NashornScriptEngineFactory
    DEBUG StatusLogger PluginManager 'Core' found 116 plugins
    DEBUG StatusLogger PluginManager 'Level' found 0 plugins
    DEBUG StatusLogger PluginManager 'Lookup' found 13 plugins
    
  • при отсутствии

    DEBUG StatusLogger Not in a ServletContext environment, thus not loading WebLookup plugin.
    DEBUG StatusLogger Took 0,001875 seconds to load 1 plugins from sun.misc.Launcher$AppClassLoader@4e25154f
    DEBUG StatusLogger PluginManager 'Converter' found 0 plugins
    ...............
    DEBUG StatusLogger Installed 1 script engine
    DEBUG StatusLogger Oracle Nashorn version: 1.8.0_25, language: ECMAScript, threading: Not Thread Safe, compile: true, names: [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript], factory class: jdk.nashorn.api.scripting.NashornScriptEngineFactory
    DEBUG StatusLogger PluginManager 'Core' found 1 plugins
    DEBUG StatusLogger PluginManager 'Level' found 0 plugins
    

т.е. получается, что мой плагин почему-то мешает загружаться всем остальным

Answer 1

Причина найдена.

Список плагинов подгружается загрузчиком из бинарного файла

<JAR>/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat

Я собираю один jar со всеми зависимостями.

Когда я не определяю своего плагина, туда попадает Log4j2Plugins.dat из log4j-core-2.11.0.jar`. Когда же я определяю свой плагин, то в этот файл заносится информация только о моем плагине, перетирая стандартный список.

Варианты решения проблемы описаны здесь: https://stackoverflow.com/questions/25065580/log4j2-custom-plugins-annotation-processing-with-maven-assembly-plugin

  • либо разводить свои плагины и стандартные по разным jar
  • либо использовать maven плагин log4j2CacheTransformer для слияния этих двух файлов

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.1.1</version>
        <configuration>
            <transformers>
                <transformer
                    implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer" />
            </transformers>
        </configuration>
        <dependencies>
            <dependency>
                <groupId>com.github.edwgiz</groupId>
                <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
                <version>2.8.1</version>
            </dependency>
        </dependencies>
        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    
READ ALSO
Ошибка java.lang.ArrayIndexOutOfBoundsException: 1

Ошибка java.lang.ArrayIndexOutOfBoundsException: 1

При проходе по этой части кода возникает ошибкаВсё хорошо считывается при проходе первого фрагмента, дальше же возникает ошибка, возможно...

129
Вопрос по flexbox для RecyclerView

Вопрос по flexbox для RecyclerView

У меня есть RecyclerViewЯ добавил библиотеку от Google на Flexbox и сделал так:

132
Ошибка при компиляции, при включенном ProGuard

Ошибка при компиляции, при включенном ProGuard

Дописав в buildgradle строчку minifyEnabled true , при сборке apk выкидывает ошибку:

180
NPE при отработке выбора элемента списка

NPE при отработке выбора элемента списка

Учусь работать с DrawerLayoutДля обработки выбора элемента списка создал класс DrawerItemClickListener наследующий от ListView

117