利用log42框架自定义日志过滤

文章介绍了如何在车联网业务中处理TSP网关的日志问题,由于每小时有大量日志,选择了Log4j2作为日志框架进行优化。通过加载数据库中的tbox白名单到内存缓存,并使用Redis的发布订阅机制实现分布式节点的同步更新。自定义了Log4j2的日志过滤拦截器,只允许包含特定关键字的日志打印,以此减少日志量,提高效率。
摘要由CSDN通过智能技术生成

任务背景:

车联网业务TSP网关打印的日志接入es数据量过大,每小时基本有上亿条日志,快扛不住了。
本着降本增效的原则,需要实现tbox白名单日志打印功能。

框架选择

  • logback
  • log4j2

日志框架的选择网上已经有很多文章,我是参考了如下几篇文章,加上程序中原有框架也是log4j2,所以想着继续延用并在其基础上优化吧。

纠结哇!日志框架选型,Logback 还是 Log4j2? 转载

Logback与Log4j2日志框架性能对比与调优

Logback 对比 Log4j2

功能设计

  1. 程序启动时候加载数据库tbox白名单数据到程序内缓存,
  2. tbox白名单CRUD,数据库使用mysql,
  3. 每天凌晨定时刷新程序内白名单缓存,
  4. 对数据库tbox白名单做CRUD的时候,实时更新各分布式节点程序的缓存,
  5. 自定义日志过滤拦截器,

前面两点没啥好说的。
第三点是通过redis发布订阅实现的。每次对tbox白名单进行crud的时候向redis的channel “tbox_white_info” 发送一条指令数据,{“refresh”:“true”},代表需要刷新缓存了。网关程序订阅这个channel,有收到数据就进行刷新缓存的操作。这样就可以同步更新多个分布式订阅节点的数据了。

自定义日志拦截

接下来就是重点了,如何实现自定义log42的日志拦截器。有如下几个步骤
1、继承AbstractFilter
2、使用工厂模式创建你的Filter对象
3、重写filter方法,实现你的业务逻辑
4、定义注解,可以在log4j2.xml中使用

@Plugin(name = "TboxLogFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
@Slf4j
public class TboxLogFilter extends AbstractFilter {

	private Result onMatch;
	private Result onMisMatch;

	//是否启用白名单日志打印功能
	private Boolean enable = false;

	public TboxLogFilter(boolean enable, Result onMatch, Result onMismatch) {
		super();
		this.enable = enable;
		if(!enable){
			log.info("白名单日志打印功能未启用。");
		}else {
			log.info("白名单日志打印功能开始启用。");
		}
		this.onMatch = onMatch;
		this.onMisMatch = onMismatch;
	}

	//业务
	@Override
	public Result filter(LogEvent event) {
		if(!enable){
			//未开启功能
			return this.onMatch;
		}
		String log = event.getMessage().toString();
		if(!StringUtils.containsIgnoreCase(log,"tbox")
				&& !StringUtils.containsIgnoreCase(log,"tboxsn")
				&& !StringUtils.containsIgnoreCase(log,"sn")){
			//不包含tbox,sn,tboxsn关键字
			return this.onMatch;
		}
		if(GlobalSessionChannel.enableLog(log)){
			return this.onMatch;
		}
		return this.onMisMatch;
	}

	@PluginFactory
	public static TboxLogFilter createFilter(@PluginAttribute("enable") String enable,
	                                        @PluginAttribute("onMatch") final Result match,
	                                        @PluginAttribute("onMismatch") final Result mismatch) {
		assert StringUtils.isNotBlank(enable);
		final Result onMatch = match == null ? Result.NEUTRAL : match;
		final Result onMismatch = mismatch == null ? Result.DENY : mismatch;
		Boolean bo = Boolean.valueOf(enable);
		return new TboxLogFilter(bo , onMatch, onMismatch);
	}

	@Override
	public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
		return super.filter(logger, level, marker, msg, t);
	}
}

我这里对这个tbox白名单日志打印过滤功能留了个总开关,方便全局开启和关闭。
同时在过滤逻辑上做了优化,只有当日志中包含关键字“tbox”、“sn”,“tboxsn”(忽略大小写)的时候才会进入是否过滤的判定环节。

接下来是xml的配置了,有需要的同学可以直接使用。

<?xml version="1.0" encoding="UTF-8"?>
<!--设置log4j2的自身log级别为warn-->
<configuration status="warn">
    <Properties>
        <!--<property name="LOG_DIR" value="/opt/log/gateway" />-->
        <property name="LOG_DIR" value="${sys:user.dir}/logs" />
        <property name="PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%p] -%t -%c:%L - %m%n" />
        <property name="ROLLING_LOG_SIZE" value="50 MB" />
        <property name="ROLLING_LOG_MAX_NUM" value="10" />
        <property name="ROLLING_LOG_AGE" value="7D" />
    </Properties>

    <appenders>
        <console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${PATTERN}" charset="UTF-8"/>
        </console>

		<RollingFile name="RollingFileDebug" fileName="${LOG_DIR}/debug.log"
                     filePattern="${LOG_DIR}/debug-%d{yyyy-MM-dd}-%i.log">
            <Filters>
                <ThresholdFilter level="DEBUG"/>
                <ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>

            </Filters>
            <PatternLayout pattern="${PATTERN}" charset="UTF-8"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${ROLLING_LOG_SIZE}"/>
            </Policies>
            <!--归档文件设置-->
            <DefaultRolloverStrategy max="${ROLLING_LOG_MAX_NUM}">
                <Delete basePath="${LOG_DIR}" maxDepth="1">
                    <IfFileName glob="debug.*.log"/>
                    <IfLastModified age="${ROLLING_LOG_AGE}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <RollingFile name="RollingFileInfo" fileName="${LOG_DIR}/info.log"
                     filePattern="${LOG_DIR}/info-%d{yyyy-MM-dd}-%i.log">
            <Filters>
                <ThresholdFilter level="INFO"/>
                <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <PatternLayout pattern="${PATTERN}" charset="UTF-8"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${ROLLING_LOG_SIZE}"/>
            </Policies>
            <!--归档文件设置-->
            <DefaultRolloverStrategy max="${ROLLING_LOG_MAX_NUM}">
                <Delete basePath="${LOG_DIR}" maxDepth="1">
                    <IfFileName glob="info.*.log"/>
                    <IfLastModified age="${ROLLING_LOG_AGE}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <RollingFile name="RollingFileWarn" fileName="${LOG_DIR}/warn.log"
                     filePattern="${LOG_DIR}/warn-%d{yyyy-MM-dd}-%i.log">
            <Filters>
                <ThresholdFilter level="WARN"/>
                <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <PatternLayout pattern="${PATTERN}" charset="UTF-8"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${ROLLING_LOG_SIZE}"/>
            </Policies>
            <!--归档文件设置-->
            <DefaultRolloverStrategy max="${ROLLING_LOG_MAX_NUM}">
                <Delete basePath="${LOG_DIR}" maxDepth="1">
                    <IfFileName glob="warn.*.log"/>
                    <IfLastModified age="${ROLLING_LOG_AGE}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <RollingFile name="RollingFileError" fileName="${LOG_DIR}/error.log"
                     filePattern="${LOG_DIR}/error-%d{yyyy-MM-dd}-%i.log">
            <Filters>
                <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${PATTERN}" charset="UTF-8"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${ROLLING_LOG_SIZE}"/>
            </Policies>
            <!--归档文件设置-->
            <DefaultRolloverStrategy max="${ROLLING_LOG_MAX_NUM}">
                <Delete basePath="${LOG_DIR}" maxDepth="1">
                    <IfFileName glob="error.*.log"/>
                    <IfLastModified age="${ROLLING_LOG_AGE}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

    </appenders>

    <loggers>
        <!--过滤掉spring和hibernate的一些无用的debug信息-->
        <logger name="org.springframework" level="INFO" includeLocation="true" additivity="false"/>
        <logger name="org.hibernate" level="INFO" includeLocation="true" additivity="false"/>
        <logger name="com.netflix" level="WARN" includeLocation="true" additivity="false"/>
        <logger name="io.netty" level="INFO" includeLocation="true" additivity="false"/>
        <logger name="io.lettuce" level="WARN" includeLocation="true" additivity="false"/>
        <logger name="org.apache" level="INFO" includeLocation="true" additivity="false"/>
        <logger name="org.apache.kafka.clients.consumer" level="WARN" includeLocation="true" additivity="false"/>
        <logger name="org.springframework.kafka.listener" level="WARN" includeLocation="true" additivity="false"/>
        <logger name="cn.com.jit.assp.css.client.communication.RequestClient" level="WARN" includeLocation="true" additivity="false"/>
        <root level="info" includeLocation="true" additivity="false">
            <appender-ref ref="Console"/>
            <!-- tbox过滤 -->
            <TboxLogFilter enable="true" onMatch="NEUTRAL" onMismatch="DENY"/>
            <appender-ref ref="RollingFileDebug"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
        </root>
    </loggers>
</configuration>

关键是下面一行的使用,enable=true的时候功能功能,onMatch的时候放行,onMismatch则直接丢弃这条日志。

<TboxLogFilter enable="true" onMatch="NEUTRAL" onMismatch="DENY"/>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>