Log4j2 - 查找插件 (StrLookup) 用于解析 ThreadName 以通过线程路由 RollingLogFile

2023-11-29

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

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



|-/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据我了解,packages的属性Configuration应该读入ThreadLookup.java并根据注释创建一个新的threadLookup让我打电话的前缀lookup(String key)无论我想要什么值——在这种情况下,我没有使用特定值,因为此类只会执行 threadName 查找):

<?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.

如何使用 log4j2 注册插件(我使用的是版本2.2,我也尝试过2.3)?请注意,我正在使用spring-framework 4.1.7项目,如果有帮助的话;我用maven对于该项目也是如此,但我仅使用它来解决依赖关系,我通过构建项目ant script.

UPDATE

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

$ 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>

Thanks


我最终发现问题在于我的Plugin name不能采用驼峰式命名。

我正在调试通过PluginManager.java (Log4j2 - 2.3), on line 169 in private static void mergeByName(final Map<String, PluginType<?>> newPlugins, final List<PluginType<?>> plugins),我发现我有以下属性可以进入newPlugins.put(key, pluginType);

  • key: 线程查找,
  • pluginType: 插件类型 [pluginClass=class log4j2.plugins.ThreadLookup, key=线程查找,elementName=threadLookup,isObjectPrintable=false,isDeferChildren==false,category=Lookup]

看到之后我修改了我的Routing附加器在我的log4j2.xml配置为以下内容(无需更改我的注释Plugin实现的类StrLookup)并且它起作用了:

    <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.

Thanks!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Log4j2 - 查找插件 (StrLookup) 用于解析 ThreadName 以通过线程路由 RollingLogFile 的相关文章

随机推荐