springboot-log4j2过滤器总介绍
为log4j2配置全局过滤器
源码分析
以输出一条dubug日志为例
log.debug("this is a debug log.");
程序将调用org.apache.logging.log4j.spi.AbstractLogger#debug(java.lang.String)方法, 该方法会顺序调用以下方法
@Override
public void debug(final String message, final Object... params) {
logIfEnabled(FQCN, Level.DEBUG, null, message, params);
}
@Override
public void logIfEnabled(final String fqcn, final Level level, final Marker marker, final String message,
final Object... params) {
if (isEnabled(level, marker, message, params)) {
logMessage(fqcn, level, marker, message, params);
}
}
@Override
public boolean isEnabled(final Level level, final Marker marker, final String message, final Object... params) {
return privateConfig.filter(level, marker, message, params);
}
boolean filter(final Level level, final Marker marker, final String msg, final Object... p1) {
final Filter filter = config.getFilter(); //全局过滤器
if (filter != null) { //在不设置全局过滤器的情况下,filter = null
final Filter.Result r = filter.filter(logger, level, marker, msg, p1);
if (r != Filter.Result.NEUTRAL) {
return r == Filter.Result.ACCEPT;
}
}
//在不设置全局过滤器情况下,仅仅比对日志级别大小,速度极快
return level != null && intLevel >= level.intLevel();
}
全局过滤器配置
配置文件配置
这种配置方式是启动即生效
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<!--此处配置一个ThresholdFilter全局过滤器 org.apache.logging.log4j.core.filter.ThresholdFilter -->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<Loggers>
<!--该例配置中, 因为设置ThresholdFilter全局过滤器,首先进行全局过滤,因此最终打印级别为info-->
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
在application.properties中添加
logging.config=classpath:log4j2.xml
通过代码进行注入
这种方式只有当代码执行完globalFilter方法后过滤器才会生效
获取configuration
@Bean("log4j-configuration")
public Configuration configuration(LoggingServer loggingServer) {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration configuration = ctx.getConfiguration();
return configuration;
}
添加全局过滤器
@Bean("global-filter")
public Filter globalFilter(@Qualifier("log4j-configuration") Configuration configuration) {
Filter global = ThresholdFilter.createFilter(Level.INFO, Filter.Result.ACCEPT, Filter.Result.DENY);
configuration.addFilter(global);
return global;
}
总结
需要定制过滤条件时,尽量使用全局过滤器,不管在同步日志还是异步日志时,使用全局过滤器都可以最大限度提高日志效率,减少日志事件生成。但因为全局过滤器会在每条日志中调用(不管debug还是trace,不管是否明确规定只打印info级别,都会调用全局过滤器),因此自定义的全局过滤器过滤逻辑应尽可能简单,处理尽可能快,否则将影响主业务处理速度
版权声明:本文为u014777076原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。