本文介绍了Log4j2-查找插件(StrLookup)可以解析ThreadName以便通过线程路由RollingLogFile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试配置log4j2配置,以通过线程名将消息路由到多线程程序的不同日志文件.

I am trying to configure a log4j2 config to route messages to different logfiles for a multithreaded program via threadname.

到目前为止,这就是我所拥有的(与log4j2配置有关):

Here is what I have, so far (relevant to log4j2 config):


|-/src/main/java/log4j2/plugins
|-- ThreadLookup.java
|-/src/main/resources
|-- log4j2.xml

ThreadLookup.java :

package log4j2.plugins;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.lookup.StrLookup;

@Plugin(name="threadLookup", category=StrLookup.CATEGORY)
public class ThreadLookup implements StrLookup {

    @Override
    public String lookup(String key) {
        return Thread.currentThread().getName();
    }

    @Override
    public  String lookup(LogEvent event, String key) {
        // Check event first:
        if (event.getThreadName() != null) {
            return event.getThreadName();
        }
        // Fallback to key if event doesn't define a threadName:
        return this.lookup(key);
    }

}

Log4j2.xml (据我了解,应在ThreadLookup.java中读取Configurationpackages属性,并根据注释创建一个新的threadLookup前缀,以让我用我想要的任何值调用lookup(String key) -在这种情况下,我没有使用特定的值,因为此类只会执行threadName查找():

Log4j2.xml (It is my understanding that the packages attribute of Configuration should read in ThreadLookup.java and based on the annotation create a new threadLookup prefix to let me call lookup(String key) with whatever value I want to -- in this case I am not using a specific value because this class will only do a threadName lookup):

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" strict="true" schema="Log4J-V2.0.xsd"
               packages="log4j2.plugins">
    <Properties>
        <Property name="logMsgPattern">%date{yyyy/MM/dd HH:mm:ss.SSS} %-5level ${sys:pid}[%thread] %class %method:%line - %message%n</Property>
    </Properties>

    <Appenders>

        <Console name="console" target="SYSTEM_OUT" >
            <PatternLayout pattern="${logMsgPattern}" />
        </Console>

        <Routing name="routing">
            <Routes pattern="$${threadLookup:threadName}">
                <Route>
                    <RollingFile name="RollingFile-${threadLookup:threadName}"
                                 fileName="${sys:log4j.dir}/thread-${threadLookup:threadName}.log"
                                 filePattern="${sys:log4j.dir}/thread-${threadLookup:threadName}-%i.log.gz">
                            <PatternLayout pattern="${logMsgPattern}"/>
                            <Policies>
                                <SizeBasedTriggeringPolicy size="100 MB" />
                            </Policies>
                    </RollingFile>
                </Route>
            </Routes>
        </Routing>

        <!-- Config for other appenders snipped -->

    </Appenders>

    <Loggers>
        <!-- Config for other loggers snipped -->
        <Root level="${sys:log4j.console.threshold}">
            <AppenderRef ref="rootOut" level="trace" />
            <AppenderRef ref="rootErr" level="error" />
            <AppenderRef ref="console" level="${sys:log4j.console.threshold}" />
            <AppenderRef ref="routing" level="trace" />
        </Root>
    </Loggers>

</Configuration>

但是,当我启动我的应用程序时,它只是在我的日志目录中创建了一个名为thread-${threadLookup(无扩展名)的附加文件.它也永远不会达到ThreadLookup.java中的任何断点.

However, when I launch my app, it just creates an additional file called thread-${threadLookup (no extension) in my log directory. It also never hits any breakpoints in ThreadLookup.java.

如何在log4j2中注册插件(我使用的是版本 2.2 ,我也尝试过 2.3 )?注意,如果有帮助的话,我正在使用spring-framework 4.1.7项目.我也为项目使用了maven,但是我只是用它来解决依赖关系,而是通过ant脚本来构建项目.

How can I register the plugin with log4j2 (I was using version 2.2, I also tried 2.3)? Note, I am using a spring-framework 4.1.7 project, if that helps at all; I use maven for the project as well, but I am only using it to resolve dependencies, I build the project via ant script.

更新

当我通过ant构建脚本时,实际上确实得到了显示在我的类路径(-cp resources:bin)中的Log4j2Plugins.dat,但它似乎并没有影响服务器上生成的日志的结果. :

When I build the script via ant, I do actually get a Log4j2Plugins.dat that shows up in my classpath (-cp resources:bin), but it doesn't seem to effect the outcome of the logs that are generated on the server:

$ find bin/META-INF/ -type f
bin/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat

$ cat bin/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat
lookup
      threadlookupog4j2.plugins.ThreadLookup
                                            threadLookup

$ vi bin/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat
^A^Flookup^A^Lthreadlookup^[log4j2.plugins.ThreadLookup^LthreadLookup

$ find logs -type f -name "thread-*"
logs/thread-${threadLookup:threadName}.log
logs/thread-${threadLookup:threadName}-1.log.gz</pre>

谢谢

推荐答案

我最终发现问题是我的Plugin name无法被驼装.

I ended up finding out that the issue was that my Plugin name cannot be camelCased.

我正在通过private static void mergeByName(final Map<String, PluginType<?>> newPlugins, final List<PluginType<?>> plugins)line 169上的PluginManager.java(Log4j2-2.3)进行调试,我发现要在newPlugins.put(key, pluginType)中使用以下属性;

I was debugging through PluginManager.java (Log4j2 - 2.3), on line 169 in private static void mergeByName(final Map<String, PluginType<?>> newPlugins, final List<PluginType<?>> plugins), and I saw that I had the following properties to go into newPlugins.put(key, pluginType);

  • 键: threadlookup
  • pluginType:PluginType [pluginClass = class log4j2.plugins.ThreadLookup,键= 线程查找,elementName = threadLookup,isObjectPrintable = false,isDeferChildren == false,category = Lookup]
  • key: threadlookup,
  • pluginType: PluginType [pluginClass=class log4j2.plugins.ThreadLookup, key=threadlookup, elementName=threadLookup, isObjectPrintable=false, isDeferChildren==false, category=Lookup]

看到之后,我将log4j2.xml配置中的Routing附加程序修改为以下内容(无需在实现StrLookup的我的Plugin类中更改批注),并且可以正常工作:

After seeing that, I modified my Routing appender in my log4j2.xml config to the following (without needing to change the annotation in my Plugin class that implemented StrLookup) and it worked:

    <Routing name="routing">
        <Routes pattern="$${threadlookup:threadName}">
            <Route>
                <RollingFile name="RollingFile-${threadlookup:threadName}"
                             fileName="${sys:log4j.dir}/thread-${threadlookup:threadName}.log"
                             filePattern="${sys:log4j.dir}/thread-${threadlookup:threadName}-%i.log.gz">
                        <PatternLayout pattern="${logMsgPattern}"/>
                        <Policies>
                            <SizeBasedTriggeringPolicy size="100 MB" />
                        </Policies>
                </RollingFile>
            </Route>
        </Routes>
    </Routing>

希望这可以对其他人有所帮助,因为我不得不花几天的时间来弄清楚这一点,并且在我查看的Log4j2的任何文档或问题中都没有找到它.

Hopefully this can help others out, as I had to spend a few days to figure this out and I didn't find this in any of the documentation or questions I was reviewing for Log4j2.

谢谢!

这篇关于Log4j2-查找插件(StrLookup)可以解析ThreadName以便通过线程路由RollingLogFile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 04:31