当前位置: 首页 > 知识库问答 >
问题:

log4j2-lookup插件(StrLookup)解析通过线程路由RollingLogFile的线程名

傅旺
2023-03-14

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

|-/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(我的理解是,configurationpackages属性应该读取threadlookup.java中的内容,并根据注释创建一个新的threadlookup前缀,使我可以使用我想要的任何值调用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中的任何断点。

如何在log4j2注册插件(我使用的是2.2,我也尝试了2.3)?注意,我使用的是Spring-Framework4.1.7项目(如果有帮助的话);我也将maven用于项目,但我仅使用它来解决依赖关系,我通过Ant脚本构建项目。

更新

当我通过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>

共有1个答案

洪通
2023-03-14

最后我发现问题是我的插件名称不能被camelcased。

我通过pluginmanager.java(log4j2-2.3)在私有静态void mergeByName(final map >newPlugins,final list >plugins) 中的第169行进行调试,我看到有以下属性可以进入newPlugins.put(key,pluginType)

  • 键:ThreadLookup,
  • PluginType:PluginType[pluginclass=class log4j2.plugins.threadlookup,key=threadlookup,elementname=threadlookup,isobjectprintable=false,isdeferchildren==false,category=lookup]

在看到这些之后,我将log4j2.xml配置中的routing附加符修改为以下内容(而不需要更改实现strlookupplugin类中的注释),并且它工作了:

    <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复习的文档或问题中没有找到这一点。

谢谢!

 类似资料:
  • 本文向大家介绍图解Eclipse在线安装ADT插件过程,包括了图解Eclipse在线安装ADT插件过程的使用技巧和注意事项,需要的朋友参考一下   要想使用Eclipse开发Android应用,首先要安装一个ADT插件,在此记录一下在Eclipse中采用在线安装的方式ADT插件,我使用的Eclipse版本是:eclipse-jee-luna-SR2-win32-x86_64,操作步骤如下:Help

  • String postProcessor=“file: from(processFiles).threads(10).routeid(“someid”) .to(“bean:someBean”); 从(postProcessor).routeid(“PostProcress”).到(“bean:PostProcessorBean”); 解决方案已经到位。但目前需要更多的时间。因此,我们尝试在cam

  • 本文向大家介绍Python线程协作threading.Condition实现过程解析,包括了Python线程协作threading.Condition实现过程解析的使用技巧和注意事项,需要的朋友参考一下 领会下面这个示例吧,其实跟java中wait/nofity是一样一样的道理 Condition的底层实现了__enter__和 __exit__协议.所以可以使用with上下文管理器 由Condi

  • 本文向大家介绍java 多线程-线程通信实例讲解,包括了java 多线程-线程通信实例讲解的使用技巧和注意事项,需要的朋友参考一下 线程通信的目标是使线程间能够互相发送信号。另一方面,线程通信使线程能够等待其他线程的信号。 通过共享对象通信 忙等待 wait(),notify()和 notifyAll() 丢失的信号 假唤醒 多线程等待相同信号 不要对常量字符串或全局对象调用 wait() 通过共

  • 我有下面的场景。 我有一台带无线上网的笔记本电脑。我通过以太网电缆将我的笔记本电脑连接到网件路由器。我想让笔记本电脑无线上网与那些连接到路由器的人共享。有没有可能。

  • 本文向大家介绍Spring Boot定时+多线程执行过程解析,包括了Spring Boot定时+多线程执行过程解析的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Spring Boot定时+多线程执行过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Spring Boot 定时任务有多种实现方式,我在一个微型项目中通过注解方式执