2015-10-19 32 views
1

我的迁移EAR应用程序从log4jlog4j2。我有类扩展appender,过滤器,在不同的罐子里的布局和现在,我已经将它们转换为插件。这意味着我有多个jar中的自定义插件(假设有3个jar)。自定义插件不在EAR得到检测与log4j2 API

我不使用log4j2.xmlpackages属性和我通过使用Dlog4j.configurationFile JVM参数指向log4j2.xml位置EAR的META-INF初始化日志系统。

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

<plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <executions> 
       <execution> 
        <id>log4j-plugin-processor</id> 
        <goals> 
         <goal>compile</goal> 
        </goals> 
        <phase>process-classes</phase> 
        <configuration> 
         <proc>only</proc> 
         <annotationProcessors> 
          <annotationProcessor>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</annotationProcessor> 
         </annotationProcessors> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 

模式布局: 在下面的图案布局,e就是一个自定义模式转换器插件被写入到这个字符串转换自定义模式。对于上述图案布局(在jar1)

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

定制转换器插件:

jar1具有org.apache..META-INFLog4J2Plugins.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.jarlog4j-core-2.4.jarlog4j-jcl-2.4.jarlog4j-web-2.4.1.jarcommons-logging-1.1.1.jar在EAR罐子。

我已经定义了一个自定义模式转换器插件,并期望该转换器被应用到所有的图案布局,包括使用<patternlayout>定义的默认模式布局。这是正确的吗 ?

如果是,请帮助,如果任何人面对这个问题,并指导我,如果我错了,因为他们都没有得到来自EAR罐检测定义自定义插件。

回答

1

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

log4j的核 - 2.x.x.jar还包含定义其高速缓存数据的Log4j2Plugins.dat。

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

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

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

下面的函数实现了...

private static void mergeLog4J2Log4j2PluginsFile(JavaArchive ja, Class... uniqueJARClasses) { 
    // @Author: Johnathan Ingram <[email protected]> 
    // 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.x.x 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.x.x.jar 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<URL> datUrls = new Vector<URL>(); 
    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);