我正在尝试配置log4j2
配置,通过threadname将消息路由到多线程程序的不同日志文件。
到目前为止,我所拥有的(与log4j2配置相关):
<>之前| -/src/main/java/log4j2/插件|——ThreadLookup.java| -/src/main/资源|——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 (这是我的理解,Configuration
的packages
属性应该在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
脚本构建项目。
更新
当我通过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>
谢谢
我最终发现问题是我的Plugin
name
不能camelcase。
我正在调试PluginManager.java
(Log4j2
- 2.3
), private static void mergeByName(final Map<String, PluginType<?>> newPlugins, final List<PluginType<?>> plugins)
中的line 169
,我看到我有以下属性进入newPlugins.put(key, pluginType)
;
- key: threadlookup,
- pluginType: pluginType [plugclass =class log4js .plugins. class]ThreadLookup, key= ThreadLookup , elementName= ThreadLookup, isObjectPrintable=false, isDeferChildren==false, category=Lookup]
看到这一点后,我修改了log4j2.xml
配置中的Routing
appender如下(不需要更改实现StrLookup
的Plugin
类中的注释),它起作用了:
<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
。
谢谢!