我们有一个 log4j2 模式布局,如下所示:
<PatternLayout>
<pattern>%d{ISO8601} %5p - [%t] - %m%n</pattern>
</PatternLayout>
每行打印线程名称。我们现在需要按线程名称过滤日志。我们已经尝试了正则表达式过滤器,但它似乎只适用于该行的消息部分(%m)。
是否有一种方法可以使用另一个提供的过滤器直接过滤线程名称或将线程名称放入消息部分,而无需编辑所有日志记录语句?然后我们可以使用正则表达式过滤器。
谢谢您的帮助!
我们尝试过正则表达式过滤器,例如:
<RegexFilter regex=".*db-thread.*" onMatch="ACCEPT" onMismatch="DENY"/>
正则表达式似乎不对该行的线程名称部分生效,而仅对消息部分生效。
没有专门的过滤器来匹配线程名称。不过,您有两种解决方案:
ScriptFilter
和脚本引擎。编写本机脚本过滤器很容易:
@Plugin(name = "ThreadNameFilter", category = Node.CATEGORY)
public final class ThreadNameFilter extends AbstractFilter {
public static final class Builder extends AbstractFilter.AbstractFilterBuilder<Builder>
implements org.apache.logging.log4j.core.util.Builder<ThreadNameFilter> {
@PluginBuilderAttribute
@Required
private Pattern regex;
@Override
public ThreadNameFilter build() {
return new ThreadNameFilter(getOnMatch(), getOnMismatch(), regex);
}
}
@PluginBuilderFactory
public static Builder newBuilder() {
return new Builder();
}
private final Pattern regex;
public ThreadNameFilter(final Result onMatch, final Result onMismatch, final Pattern regex) {
super(onMatch, onMismatch);
this.regex = regex;
}
@Override
public Result filter(final LogEvent event) {
return regex.matcher(event.getThreadName()).matches() ? getOnMatch() : getOnMismatch();
}
}
在启用注释处理的情况下编译它,你可以像这样使用它:
<ThreadNameFilter onMatch="ACCEPT" onMismatch="DENY" regex="db-thread.*"/>
您也可以使用
ScriptFilter
。为此,您需要:
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>15.4</version>
</dependency>
log4j2.scriptEnableLanguages
变量中。这可以例如完成通过增加:
log4j2.scriptEnableLanguages = javascript
到类路径中的 log4j2.component.properties
文件。安装并启用脚本引擎后,您可以像这样使用
ScriptFilter
:
<ScriptFilter onMatch="ACCEPT" onMismatch="DENY">
<Script language="javascript">logEvent.getThreadName().matches("db-thread.*");</Script>
</ScriptFilter>
备注:如果您想将这些过滤器用作全局过滤器(即作为
<Configuration>
的直接子级),则需要进行一些调整。