简体   繁体   English

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

[英]log4j2 configuration will not load custom pattern converter

I am trying to create a custom pattern converter for log4j 2.0, but am having issues getting my log4j configuration to recognize the pattern. 我正在尝试为log4j 2.0创建一个自定义模式转换器,但是在让我的log4j配置识别模式时遇到了问题。 Here is the custom converter: 这是自定义转换器:

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());
        }
    }
}

And here is my log4j configuration file: 这是我的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>

Note that I have included the package which contains the custom converter in my configuration, the lack of which seems to be a common cause of issues when using custom plugins. 请注意,我在我的配置中包含了包含自定义转换器的软件包,在使用自定义插件时,缺少该软件包似乎是导致问题的常见原因。

When test code is executed, the configuration status output does not indicate that the plugin is loaded or found, and log4j treats the %markername as if it is the "%marker" conversion pattern followed by "name". 执行测试代码时,配置状态输出不表示插件已加载或找到,而log4j将%markername视为“%marker”转换模式,后跟“name”。 For example, 例如,

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

produces the following output: 产生以下输出:

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

I tried changing the conversion key a value that did not start with a standard conversion pattern, eg "fmarker", and when executed log4j produces the following error: 我尝试将转换键更改为不以标准转换模式开头的值,例如“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

Documentation indicates that plugins are gathered at build time rather than runtime, but I haven't found anything that indicates that I need to do something specific to get my custom converter to be found other than to: 文档表明插件是在构建时而不是运行时收集的,但我没有找到任何表明我需要做一些特定的事情来获取我的自定义转换器而不是:

  1. Annotate it with @Plugin and @ConverterKeys 用@Plugin和@ConverterKeys注释它
  2. Specify the plugin's category to be a "Converter" 将插件的类别指定为“转换器”
  3. Include a static "newInstance(String[])" method 包含静态“newInstance(String [])”方法
  4. Implement the "format" method 实现“格式”方法
  5. Specify the plugin package with the configuration's "packages" parameter. 使用配置的“packages”参数指定插件包。

There was documentation for a Maven plugin, but my simple test is just a basic Java project developed in Eclipse. 有一个Maven插件的文档,但我的简单测试只是在Eclipse中开发的基本Java项目。

Any ideas on what I am doing wrong? 关于我做错了什么的任何想法?

To make a long story short, since version 2.0-rc2, the packages attribute does not work any more. 简而言之,从版本2.0-rc2开始,packages属性不再起作用。 Instead, there is an annotation processor in log4j-core that will (should?) run during the build and will generate a metadata file for your custom plugins in your jar file. 相反,log4j-core中有一个注释处理器,它将(应该?)在构建期间运行,并将为您的jar文件中的自定义插件生成元数据文件。 When log4j2 starts it will look for the metadata file in all jar files and quickly discover all available plugins. 当log4j2启动时,它将在所有jar文件中查找元数据文件,并快速发现所有可用的插件。

The annotation processor works when compiling with Maven or with plain javac, but it may not work well when compiling in Eclipse. 注释处理器在使用Maven或普通javac进行编译时可以正常工作,但在Eclipse中进行编译时可能效果不佳。 You need to enable annotation processing with right-click on a project > Properties > Java Compiler > Annotation Processing. 您需要通过右键单击项目> Properties> Java Compiler> Annotation Processing来启用注释处理。

Still, I am not 100% sure this will work from Eclipse. 尽管如此,我并不是100%确定这可以从Eclipse中运行。 For now, one alternative is to build your custom plugin with Maven. 目前,另一种方法是使用Maven构建自定义插件。

I will try to make the packages attribute work again in an upcoming release. 我将尝试在即将发布的版本中再次使packages属性工作。

This issue is tracked here: https://issues.apache.org/jira/browse/LOG4J2-741 此问题在此处进行了跟踪: https//issues.apache.org/jira/browse/LOG4J2-741

UPDATE (7/28) This is fixed in trunk and will be included in the 2.0.1 release. 更新(7/28)这在trunk中修复,将包含在2.0.1版本中。

I spent a couple of hours struggling with this one as well... 我花了几个小时努力与这个...

Apparently, it's all about class loading! 显然,这都是关于课堂加载的!

Use this trick: 使用这个技巧:

Run your app using -verbose:class (it will print all the classes loaded by the JVM by their order) 使用-verbose:class运行您的应用程序(它将打印JVM按其顺序加载的所有类)

eg 例如

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

Search for the log4j2 converter class; 搜索log4j2转换器类; in your case, it should look like this: 在你的情况下,它应该是这样的:

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

You'll probably note that the converter class is loaded relatively late (I assume after the log4j2 plugins are supposed to get loaded). 您可能会注意到转换器类的加载时间相对较晚(我假设在log4j2插件应该加载之后)。

To fix this, you can try one of the following: 要解决此问题,您可以尝试以下方法之一:

  1. Load the converter class explicitly, ie Class.forName(...) 显式加载转换器类,即Class.forName(...)
  2. Change the converter class location: put it next to your main class or underneath it (in terms of package hierarchy) 更改转换器类位置:将其放在主类旁边或其下方(就包层次结构而言)

I tried both of these options - the second one worked for me! 我尝试了这两个选项 - 第二个适合我!

Goodluck 祝好运

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM