Springboot log4j2全局过滤器配置

  • Post author:
  • Post category:其他





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 版权协议,转载请附上原文出处链接和本声明。