使用log4j2 API无法在EAR中检测到自定义插件

我正在将一个EAR应用程序从log4j迁移到log4j2 。 我有类在不同的EARjar中扩展appender,filter,布局,现在,我已将它们转换为插件。 这意味着我在多个jar中有自定义插件(假设有3个jar子)。

我没有在log4j2.xml使用packages属性, log4j2.xml使用Dlog4j.configurationFile JVM参数初始化日志系统, Dlog4j.configurationFile JVM参数指向EAR的META-INFlog4j2.xml位置。

在所有三个jar项目中添加以下插件都不起作用。

  org.apache.maven.plugins maven-compiler-plugin   log4j-plugin-processor  compile  process-classes  only  org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor      

模式布局:在下面的模式布局中, e是自定义模式,其中编写自定义模式转换器插件以转换此字符串。

 %d %-5p [%c{1}] [EventId: %e] [%t] %m%n 

用于上述模式布局的自定义转换器插件(在jar1中):

jar1在org.apache..文件夹中的META-INF下有Log4J2Plugins.dat文件。

 @Plugin(name = "EventPatternConverter", category = "Converter") @ConverterKeys({"e"}) public class EventPatternConverter extends LogEventPatternConverter { protected EventPatternConverter(String name, String style) { super(name, style); } public static EventPatternConverter newInstance(String[] options) { return new EventPatternConverter("e", "e"); } @Override public void format(LogEvent event, StringBuilder toAppendTo) { String eventId= ""; // Append empty string (OR) value toAppendTo.append(eventId); } } 

但是,我收到以下错误

 ERROR Unrecognized format specifier [e] 

甚至,没有任何自定义插件被识别为我正在获取其他自定义插件的invalid element ,这些插件在jar2,jar3中都可用,并且它们都具有Log4J2Plugins.dat文件。

 ERROR File contains an invalid element or attribute "TestFilter" 

我在log4j-api-2.4.jar使用log4j-api-2.4.jarlog4j-core-2.4.jarlog4j-jcl-2.4.jarlog4j-web-2.4.1.jarcommons-logging-1.1.1.jar jars 。

我已经定义了一个自定义模式转换器插件,并期望此转换器应用于所有模式布局,包括使用定义的默认模式布局。 这是正确的吗 ?

如果是,请帮助,如果有人遇到这个问题,并指导我,如果我错误定义自定义插件,因为他们都没有从EAR中的jar子中检测到。

在编译自定义插件时,Log4J pom.xml定义了一个插件,可以自动生成文件中的缓存数据META-INF / org / apache / logging / log4j / core / config / plugins / Log4j2Plugins.dat你可以在你的目标下看到这个/ Maven项目中的类。

log4j-core-2.xxjar还包含一个定义其缓存数据的Log4j2Plugins.dat。

问题是在使用ShrinkWrap测试EAR时会创建一个JAR,并且通常将log4j-core-2.xxjar Log4j2Plugins.dat添加到测试JAR中,因为它很可能是类路径中的第一个。

这意味着您的自定义插件缓存缺失。

使用ShrinkWrap的解决方案是创建一个新的Log4j2Plugins.dat,将所有必需的自定义插件缓存文件与核心合并,然后将其添加到JAR。

以下function实现了……

 private static void mergeLog4J2Log4j2PluginsFile(JavaArchive ja, Class... uniqueJARClasses) { // @Author: Johnathan Ingram  // Log4J2 uses /META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat within a JAR to define custom plugins // This is automatically generated by the plugin defined in the log4j-core-2.xx pom.xml when compiling your custom plugin // The problem with shrinkwrap is that the JAR is not preserved and only a single // /META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat // file can exist as JAR files cannot be added to a JAR file as a library. // This is normally the default contained in log4j-core-2.xxjar which does not expose any custom plugins // To rectify, both the core and the custom plugin JAR file Log4j2Plugins.dat need to be merged into a single Log4j2Plugins.dat try { // List of a unique class in each JAR containing a Log4j2Plugins.dat requiring merging Vector datUrls = new Vector(); for (Class klass : uniqueJARClasses) { // Find the JAR the class belongs to URL classLoc = klass.getProtectionDomain().getCodeSource().getLocation(); URL resourceURL = classLoc.toString().endsWith(".jar") ? new URL("jar:" + URLDecoder.decode(classLoc.toString(), "UTF-8") + "!/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat") : new URL(URLDecoder.decode(classLoc.toString(), "UTF-8") + "/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat"); datUrls.add(resourceURL); } // Use the Log4J2 PluginCache to build a merged Log4j2Plugins.dat File mergedDatFile = new File("target/Log4j2Plugins.dat"); try (FileOutputStream fo = new FileOutputStream(mergedDatFile)) { org.apache.logging.log4j.core.config.plugins.processor.PluginCache pc = new org.apache.logging.log4j.core.config.plugins.processor.PluginCache(); pc.loadCacheFiles(datUrls.elements()); pc.writeCache(fo); } // Replace the default Log4j2Plugins.dat if present ja.delete("/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat"); ja.addAsManifestResource(mergedDatFile, "org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat"); } catch (Exception ex) { ex.printStackTrace(System.err); } } 

要使用您的示例运行:

 JavaArchive ja = ShrinkWrap.create(JavaArchive.class, "my-test.jar"); ... mergeLog4J2Log4j2PluginsFile(ja, org.apache.logging.log4j.core.config.plugins.processor.PluginCache.class, EventPatternConverter.class);