log4j2配置不会加载自定义模式转换器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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视为“%marker”转换模式,后跟“name”。例如,
Marker marker = MarkerManager.getMarker("TEST");
log.info(marker, "test message");
产生以下输出:
INFO TESTname 2014-07-23 14:47:57 test message
我尝试将转换键更改为不以标准转换模式开头的值,例如“fmarker”,并在执行时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
文档表明插件是在构建时而不是运行时收集的,但我没有找到任何表明我需要做一些特定的事情来获取我的自定义转换器而不是:
- 用@Plugin和@ConverterKeys注释它
- 将插件的类别指定为“转换器”
- 包含静态“newInstance(String [])”方法
- 实现“格式”方法
- 使用配置的“packages”参数指定插件包。
有一个Maven插件的文档,但我的简单测试只是在Eclipse中开发的一个基本Java项目。
关于我做错了什么的任何想法?
简而言之,从版本2.0-rc2开始,packages属性不再起作用。相反,log4j-core中有一个注释处理器,它将(应该?)在构建期间运行,并将为您的jar文件中的自定义插件生成元数据文件。当log4j2启动时,它将在所有jar文件中查找元数据文件,并快速发现所有可用的插件。
注释处理器在使用Maven或普通javac进行编译时可以正常工作,但在Eclipse中进行编译时可能效果不佳。您需要通过右键单击项目> Properties> Java Compiler> Annotation Processing来启用注释处理。
尽管如此,我并不是100%确定这可以从Eclipse中运行。目前,另一种方法是使用Maven构建自定义插件。
我将尝试在即将发布的版本中再次使packages属性工作。
这个问题在这里被跟踪:https://issues.apache.org/jira/browse/LOG4J2-741
更新(7/28)这在trunk中修复,将包含在2.0.1版本中。
我花了几个小时努力与这个...
显然,这都是关于课堂加载的!
使用这个技巧:
使用-verbose:class运行您的应用程序(它将打印JVM按其顺序加载的所有类)
EG
java -verbose:class -cp <your_jar> <your_main_class> ...
搜索log4j2转换器类;在你的情况下,它应该是这样的:
[Loaded com.test.log4j.plugins.MarkerNamePatternConverter from jar:file: ...]
您可能会注意到转换器类的加载时间相对较晚(我假设在log4j2插件应该加载之后)。
要解决此问题,您可以尝试以下方法之一:
- 显式加载转换器类,即Class.forName(...)
- 更改转换器类位置:将其放在主类旁边或其下方(就包层次结构而言)
我尝试了这两个选项 - 第二个适合我!
祝好运
以上是关于log4j2配置不会加载自定义模式转换器的主要内容,如果未能解决你的问题,请参考以下文章