Logback 使用TurboFilter实现日志级别等内容的动态修改操作

目录
  • Logback TurboFilter实现日志级别等内容的动态修改
    • 为什么要通过TurboFilter去动态的修改日志级别
  • logback动态设置某个类的日志级别
    • 假设一下,现在有这么个情况
    • 于是就有了下面的方案

Logback TurboFilter实现日志级别等内容的动态修改

可能看到这个标题,读者会问:要修改日志的级别,不是直接修改log.xxx就好了吗?为何要搞那么复杂呢?所以,先说一下场景

为什么要通过TurboFilter去动态的修改日志级别

我们在使用Java开发各种项目的时候必然的会引入很多框架,这些框架通过堆叠的方式完成所要提供的业务服务(一个服务请求在进入后会在这些框架中兜一圈,然后返回结果),当一个比较底层的框架在处理过程中抛出了异常之后,这个异常会不断的向上传递。

这个时候,有的框架直接throw,继续向上抛,而有的在throw之前还会自己打印一下error日志,这就导致了当出现异常的时候,往往会出现一连串类似的错误日志记录。如果对接了错误日志告警,就会出现重复告警的现象。为了解决类似这样的问题,修改源码重新编译最直接,但是不可取。

所以希望可以有更好的手段去控制这些已经被编码固化的日志打印信息。当我们使用Logback的时候,TurboFilter就是解决该问题的工具之一。

TurboFIlter不同于之前在[《Logback中如何自定义灵活的日志过滤规则》]一文中介绍的那些通过ch.qos.logback.core.filter.Filter接口实现的过滤器。ch.qos.logback.core.filter.Filter实现的过滤器是与Appender绑定的,而TurboFIlter是与日志上下文绑定的,它会过滤所有的日志请求,并且TurboFIlter的方法中提供了丰富的可访问信息用来进行控制和改写。

比如下面的实现,通过继承ch.qos.logback.classic.turbo.TurboFilter类,并重写decide方法,将org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter类中原本要打印的ERROR日志DENY掉(过滤掉),同时以WARN级别打印一封相同的内容,这样就实现了对已定义日志的动态修改。

public class ForceWarnFilter extends TurboFilter {
    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable throwable) {
        if (level == Level.ERROR && logger.getName().equals("org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter")) {
            logger.warn(marker, format, params);
            return FilterReply.DENY;
        }
        return FilterReply.NEUTRAL;
    }
}

为了让上面定义的过滤器生效,需要在logback的配置xml中增加如下配置:

<configuration>
    <turboFilter class="com.didispace.log.filter.ForceWarnFilter" />
    ......
</configuration>

或者也可以在应用主类中增加:

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
lc.addTurboFilter(new MyTurboFilter());

更多关于Logback过滤器的内容可参考官方文档

logback动态设置某个类的日志级别

假设一下,现在有这么个情况

你调别人的接口出问题了,但是怎么排查都定位不了原因。只能借助更详细的日志信息,这个时候,又不想把全局的日志级别调低,毕竟调低对并发量大的应用来说,瞬间会涌出很多很多日志信息。

最好的情况就是,只调整出问题的那个类的日志级别。那怎么办呢?

于是就有了下面的方案

定向修改某个class的logger日志级别。

 public void testLog(String key, String level, String level2){
        LoggerContext loggerContext= (LoggerContext) LoggerFactory.getILoggerFactory();
        //设置全局日志级别
        ch.qos.logback.classic.Logger logger=loggerContext.getLogger("root");
        logger.setLevel(Level.toLevel(level));

        if (!StringUtils.isBlank(level2)) {
            //设置某个类日志级别-可以实现定向日志级别调整
            ch.qos.logback.classic.Logger vLogger = loggerContext.getLogger(key);
            if (vLogger!=null)
                vLogger.setLevel(Level.toLevel(level2));
        }

        List<ch.qos.logback.classic.Logger> loggerList = loggerContext.getLoggerList();
        for (ch.qos.logback.classic.Logger logger1 : loggerList){
            log.info(logger1.getName());
        }
    }

比如:

     level = ERROR
     level2 = INFO
     key = "com.duy.soo.web.controller.TestController"

表示把全局日志级别设置为ERROR级别,单独把com.duy.soo.web.controller.TestController类的日志设置为INFO级别。

/**
 * @Author changle
 * @Time 17/6/30.
 * @Desc to do
 */
@Slf4j
@Controller
@RequestMapping(value = "/api/test")
public class TestController {
    @RequestMapping("/testDebug")
    @ResponseBody
    public Response<String> testLog(String key){
        //打印日志级别
        String rtn = "this is a INFO";
        log.info(rtn);
        rtn = "this is a ERROR";
        log.error(rtn);
        rtn = "this is a DEBUG";
        log.debug(rtn);
        Response<String> response = Response.ok(rtn);
        return response;
    }
}

如此一来,除了com.duy.soo.web.controller.TestController类以外的其他类,都只输出ERROR日志,而TestController类能输出INFO日志信息。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 使用Logback设置日志级别

    Logback设置日志级别 使用Logback设置日志的设置方式现在已经有很多文章说明,本文重点说明不同设置方式的区别和用途.首先列举常用的三种方式,接下来说明其区别. appender中的LevelFilter: 级别过滤器,根据日志级别进行过滤.如果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志 <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppende

  • 利用logback 设置不同包下的日志级别

    1.实现效果:项目的整体的日志打印级别为ERROR,但在某个包下或某个类想打印INFO级别的日志. 2.配置: FILE是ERROR级别日志打印: SPECIAL 是INFO级别日志打印: FILE与SPECIAL唯一不同是日志保存路径不同,其它策略相同: 通过 logger标签指定包路径或类路径并引用SPECIAL: <?xml version="1.0" encoding="UTF-8"?> <configuration> <con

  • spring boot使用logback日志级别打印控制操作

    因为公司业务需要,需要把性能日志和业务日志分开打印,用elk收集处理,所以需要对不同的业务的日志,打印到不同文件. 使用的是spring boot自带的logback. 首先在yml文件配置logback.xml文件,默认会从resources下找logback.xml文件,找不到会从yml文件中找logging.config下的指定文件. logging: level: DEBUG config: classpath:logback.xml logback.xml是logback的配置文件,可

  • logback使用filter过滤日志操作

    笔者语录: 我发现我喜欢捣鼓一些小玩意儿,虽然官网(见文末)写得很明白了,但是咱们对感兴趣的部分来敲一遍代码好吧. 过滤器简介: 简介 logback具有过滤器支持.logbcak允许给日志记录器appender配置一个或多个Filter(或者给整体配置一个或多个TurboFilter),来控制:当满足过滤器指定的条件时,才记录日志(或不满足条件时,拒绝记录日志).logback支持自定义过滤器,当然logback也自带了一些常用的过滤器,在绝大多数时候,自带的过滤器其实就够用了,一般是不需要自

  • 使用logback实现日志打印过滤

    logback日志打印过滤 1.只打印sql语句以及参数 <?xml version="1.0" encoding="UTF-8" ?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- 设置 logger context 名称,一旦设置不可改变,默认为default --> &l

  • Logback 使用TurboFilter实现日志级别等内容的动态修改操作

    目录 Logback TurboFilter实现日志级别等内容的动态修改 为什么要通过TurboFilter去动态的修改日志级别 logback动态设置某个类的日志级别 假设一下,现在有这么个情况 于是就有了下面的方案 Logback TurboFilter实现日志级别等内容的动态修改 可能看到这个标题,读者会问:要修改日志的级别,不是直接修改log.xxx就好了吗?为何要搞那么复杂呢?所以,先说一下场景 为什么要通过TurboFilter去动态的修改日志级别 我们在使用Java开发各种项目的时

  • springboot logback调整mybatis日志级别无效的解决

    现象 在日志配置文件 logback-spring.xml 中,无论怎么修改级别,mybatis 的 sql 日志都会打印出来. 原因 在 application.yml 中配置了 mybatis 的自定义日志类,如下: mybatis: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 点进去查看源码,发现 debug 日志级别始终为 true,所以怎么配置都不生效 public boolean isDeb

  • Logback动态修改日志级别的方法

    问题提出: 一般在生产环境上,日志的级别是INFO以上,但有时候程序出现问题(如SQL报错),少量日志不能尽快定位问题,这时候可以动态修改日志级别到DEBUG,打印更多日志后可以快速定位到问题. 解决方法: 定义动态修改日志级别的接口:这种方法的好处是不用修改配置文件,排错后再次调用接口把日志级别修改回去:坏处是需要在代码中写死指定哪些包要修改日志级别.示例代码如下: @RestController public class LogController { private static Logg

  • Java ASM使用logback日志级别动态切换方案展示

    目录 背景 logback简介 解决方案 方案一:logback自动扫描更新 方案二:ASM动态修改字节码 延伸扩展 背景 一切皆有因果,所有事情,都有事件驱动.本方案的日志级别切换是由这样的背景下产生的: 单个生产环境上,有几百近千个微服务 日志级别切换不重启服务,要求即时生效果 由业务开发人员去修改代码或增加相关依赖配置等涉及面广,推动进度慢 后期动态实时过滤垃圾日志,减少io和磁盘空间成本 logback简介 在跟敌人发起战争之前,只有先发解敌方的情况,才能做到百战百胜.要想对logbac

  • Java中 log4j日志级别配置详解

    1.1 前言 说出来真是丢脸,最近被公司派到客户公司面试外包开发岗位,本来准备了什么redis.rabbitMQ.SSM框架的相关面试题以及自己做过的一些项目回顾,信心满满地去面试,结果别人一上来就问到了最近项目使用的日志系统是什么?日志级别是怎么配置的?当时我都蒙X了,平时都是项目经理搭的,我自己也是随便上网一搜往配置文件一黏贴就OK了.我就这么说完后面试官深深定了我一眼,当时我的内心羞愧到...... 1.2 闲话少说,讲讲日志的发展故事(如果已经了解的可以跳过,直接看1.3日志配置) 要想

  • Spring Boot整合logback一个简单的日志集成架构

    一.业务需求 在项目开发和运维过程中需要通过日志来分析问题,解决问题以保证项目的正常运行.通过SpringBoot自带的日志管理相对比较简单,已无法满足日常的运维需求,需要对日志文件进行分时分类管理,刚好通过学习接触到了logback日志系统.因此便决定将其加入到项目框架之中. 二.logback简介 至于简介,可自行网上查阅相关文档文献,这里不做详细描述,毕竟不是本文主要目的.只需理解它很好的实现了slf4j,是log4j的再发展即可. 三.具体实施方案(仅供参考) 1.引入依赖包 其实不需要

随机推荐