log4j2配置不会加载自定义模式转换器

时间:2014-07-23 19:03:40

标签: java logging plugins converter log4j2

我正在尝试为log4j 2.0创建自定义模式转换器,但是在让我的log4j配置识别模式时遇到问题。这是自定义转换器:

package com.test.log4j.plugins;

import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.pattern.ConverterKeys;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;

@Plugin(name="MarkerNamePatternConverter", category="Converter")
@ConverterKeys({"markername"})
public class MarkerNamePatternConverter extends LogEventPatternConverter {

    public static MarkerNamePatternConverter newInstance(final String[] options) {
        return new MarkerNamePatternConverter("markername", "markername");
    }

    protected MarkerNamePatternConverter(String name, String style) {
        super(name, style);
    }

    @Override
    public void format(LogEvent event, StringBuilder toAppendTo) {
        Marker marker = event.getMarker();
        if (marker != null) {
            // MarkerPatternConverter appends Marker.toString()
            // which includes the parents of the marker.  We just
            // want the marker's name
            toAppendTo.append(marker.getName());
        }
    }
}

这是我的log4j配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" packages="com.test.log4j.plugins">
  <Appenders>
    <Console name="console" target="SYSTEM_OUT">
      <PatternLayout pattern=" %-6level %markername  %d{YYYY-MM-dd HH:mm:ss}  %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="debug">
      <AppenderRef ref="console"/>
    </Root>
  </Loggers>
</Configuration>

请注意,我在我的配置中包含了包含自定义转换器的软件包,在使用自定义插件时,缺少该软件包似乎是导致问题的常见原因。

执行测试代码时,配置状态输出并不表示插件已加载或找到,而log4j将%markername视为&#34;%marker&#34;转换模式后跟&#34; name&#34;。例如,

Marker marker = MarkerManager.getMarker("TEST");
log.info(marker, "test message");

产生以下输出:

INFO   TESTname  2014-07-23 14:47:57  test message

我尝试将转换键更改为不以标准转换模式开头的值,例如&#34; fmarker&#34;,执行时log4j产生以下错误:

2014-07-23 14:44:55,814 ERROR Unrecognized format specifier [fmarker]
2014-07-23 14:44:55,816 ERROR Unrecognized conversion specifier [fmarker] starting at     position 18 in conversion pattern.
INFO   %fmarker  2014-07-23 14:44:55  test message

文档表明插件是在构建时而不是运行时收集的,但是我还没有找到任何表明我需要做一些特定的事情来获取我的自定义转换器而不是:

  1. 使用@Plugin和@ConverterKeys
  2. 进行注释
  3. 将插件的类别指定为&#34;转换器&#34;
  4. 包含静态&#34; newInstance(String [])&#34;方法
  5. 实施&#34;格式&#34;方法
  6. 使用配置&#34; packages&#34;指定插件包。参数。
  7. 有一个Maven插件的文档,但我的简单测试只是Eclipse中开发的一个基本Java项目。

    关于我做错的任何想法?

2 个答案:

答案 0 :(得分:2)

简而言之,从版本2.0-rc2开始,packages属性不再起作用。相反,log4j-core中有一个注释处理器,它将(应该?)在构建期间运行,并将为您的jar文件中的自定义插件生成元数据文件。当log4j2启动时,它将在所有jar文件中查找元数据文件,并快速发现所有可用的插件。

注释处理器在使用Maven或普通javac进行编译时可以正常工作,但在Eclipse中进行编译时可能效果不佳。您需要通过右键单击项目来启用注释处理&gt;属性&gt; Java编译器&gt;注释处理。

尽管如此,我并非100%确定这可以在Eclipse中运行。目前,另一种方法是使用Maven构建自定义插件。

我将尝试在即将发布的版本中再次使packages属性工作。

此处跟踪此问题:https://issues.apache.org/jira/browse/LOG4J2-741

更新(7/28)这在主干中已修复,将包含在2.0.1版本中。

答案 1 :(得分:0)

我花了几个小时努力解决这个问题......

显然,这完全是关于课堂加载的!

使用这个技巧:

使用 -verbose:class 运行您的应用程序(它将按照订单打印JVM加载的所有类)

e.g。

java -verbose:class -cp <your_jar> <your_main_class> ...

搜索 log4j2 转换器类;在你的情况下,它应该是这样的:

[Loaded com.test.log4j.plugins.MarkerNamePatternConverter from jar:file: ...]     

您可能会注意到转换器类的加载时间相对较晚(我假设在log4j2插件应该加载之后)。

要解决此问题,您可以尝试以下方法之一:

  1. 显式加载转换器类,即Class.forName(...)
  2. 更改转换器类位置:将其放在主类旁边或其下方(根据包层次结构)
  3. 我尝试了这两个选项 - 第二个适合我!

    古德勒克