zoukankan      html  css  js  c++  java
  • logback java动态配置【动态修改日志级别,动态修改appender】(转)

    logback 动态配置


    写在前面
    在做java日志之前,强烈建议大家读一下这篇java日志的前世今生,对理清java日志框架很有帮助!
    1
    奉上地址: 一个著名的日志系统是怎么设计出来的

    然后说一下,为啥要使用动态日志配置。对于业务系统来讲,有些日志并非必须日志,但是对于调试是很重要的,当我们需要监控一个时段的日志,而过去这个时段,我们便不需要这些日志了,我们就可以通过命令,或者请求,动态开启日志输出,不想要日志时,动态关闭日志即可。
    对于试运行阶段的项目,我们需要收集比较详细的日志,当我们认为系统稳定了,没有问题了,就可以动态关闭日志。

    再者,有需求,我们的日志输出源发生改变,比如ELK变为了kafka ,我们在不停止服务的情况下,就可以动态操作,修改掉输出对象。

    简述java日志框架


    spring boot 默认的日志框架为 slf4j+logback 。这里也强烈建议写日志时面向 slf4j(面向接口),几乎目前主流的日志框架(指java日志框架)都实现了slf4j,因此面向slf4j写日志,日志框架非常容易迁移。
    例如将log4j2 迁移为 logback ,只需要修改部分配置文件即可。

    logback的执行步骤 :

    logback的主要对象

    对象 简述
    LoggerContext logback的核心对象,加载配置文件,存储loggerList……是log back的核心容器
    Logger 这个Logger为logback的logger 它实现了slf4j的Logger对象,除了实现了所有的logger方法外,我们动态配置日志输出源,也需要里面的 addAppender(),detachAppender()方法
    Appender 日志输出的最终实现, doAppend(E e)方法,最终实现了日志的输出,如果自定义appender 需要最终实现该接口

    注:以上对象并非logback全部核心对象,对于今天的日志动态输出,仅仅涉及到以上核心对象。

    实现logback 动态改变日志级别


    实现流程如下 :


    下面附上测试源代码:

     1 package com.kgo.logger.logback;
     2 
     3 import ch.qos.logback.classic.Level;
     4 import ch.qos.logback.classic.LoggerContext;
     5 import com.kgo.logger.appender.DemoAppender;
     6 import org.slf4j.Logger;
     7 import org.slf4j.LoggerFactory;
     8 
     9 public class ContextTest {
    10     public static final String demoApName = "demo";
    11     public static void main(String[] args) {
    12         // 定义日志输出
    13         Logger logger = LoggerFactory.getLogger(ContextTest.class);
    14         logger.debug("=== 我输出了 === ");
    15         // 第一步:获取日志上下文
    16         LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
    17         // 第二步:获取日志对象 (日志是有继承关系的,关闭上层,下层如果没有特殊说明也会关闭)
    18         ch.qos.logback.classic.Logger logbackLogger = lc.getLogger("com.kgo.logger.logback");
    19         ch.qos.logback.classic.Logger rootLogger = lc.getLogger("root");
    20         // 第三步:修改日志级别
    21         logbackLogger.setLevel(Level.INFO);
    22         logger.debug("===== 我是 debug  =====");
    23         logger.info("===== 我是 info  =====");
    24         logger.error("===== 我是 ERROR  =====");
    25     }
    26 }

    输出结果如下:

     

    可以看到 日志级别修改为INFO之后,日志 “===== 我是 debug =====” 没有输出
    logback 基本选择规则如下 :

     

    动态添加删除 appender


    实现步骤和 修改日志级别基本一致,流程如下:

     

    附上测试代码:

     1 package com.kgo.logger.logback;
     2 
     3 import ch.qos.logback.classic.LoggerContext;
     4 import org.slf4j.Logger;
     5 import org.slf4j.LoggerFactory;
     6 
     7 public class ChangeAppender {
     8     public static final String demoApName = "demo";
     9     public static void main(String[] args) {
    10         // 定义日志输出
    11         Logger logger = LoggerFactory.getLogger(ContextTest.class);
    12         logger.debug("=== 我输出了 === 
     ");
    13         // 第一步:获取日志上下文
    14         LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
    15         // 第二步:获取日志对象 (日志是有继承关系的,关闭上层,下层如果没有特殊说明也会关闭)
    16         ch.qos.logback.classic.Logger logbackLogger = lc.getLogger("com.kgo.logger.logback");
    17         ch.qos.logback.classic.Logger rootLogger = lc.getLogger("root");
    18         // 第三步:移除 appender
    19         logbackLogger.detachAppender("STDOUT");
    20         logger.debug("仅仅移除 com.kgo.logger.logback 的 appender");
    21         logger.debug("===== 我是 debug  =====");
    22         logger.info("===== 我是 info  =====");
    23         logger.error("===== 我是 ERROR  =====");
    24         rootLogger.detachAppender("STDOUT");
    25         logger.debug("
     仅仅移除root 的 appender");
    26         logger.debug("===== 我是 debug  =====");
    27         logger.info("===== 我是 info  =====");
    28         logger.error("===== 我是 ERROR  =====");
    29 
    30     }
    31 }

    在执行这段代码的时候我在本地已经配置的 logback-test.xml ,其中 “STDOUT” 便是在该文件中做的配置,配置如下:

     1 <configuration>
     2     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     3         <encoder>
     4             <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
     5         </encoder>
     6     </appender>
     7 
     8     <root level="debug">
     9         <appender-ref ref="STDOUT" />
    10     </root>
    11  <logger name="com.kgo.logger.logback" level="DEBUG" >
    12         <appender-ref ref="STDOUT" />
    13     </logger>
    14 </configuration>

    输出结果如下:

     

    • 在配置文件里配置了两个 Logger ,都输出给 STDOUT appender ,因此 “ === 我输出了 === ” 被打印了两次,
    • 当我移除掉了名字为 “ com.kgo.logger.logback” Logger的Appender , 下面的 日志仅输出了一次 (Root 的输出),
    • 当将root的appender 也移除掉后,日志不在输出(没有了输出对象)。

      就先分享到这里,接下里会写一篇 自定义appender ,并且动态添加append的 博客 ,本系列的博客目标 为 实现 日志的 全自动化
    包括:收集,上传,分类 ,自定义字段,实时更新,elk 等。

    如果感觉有用,点个赞再走吧,大佬

    ------------------------------------------------------- 这就是我的底线了 --------------------------------------------------------------
    ————————————————
    版权声明:本文为CSDN博主「keep-go-on」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_26462567/article/details/103065029

  • 相关阅读:
    kafka常见命令
    hive创建分区表
    java正则表达式过滤html标签
    Jquery 获取地址位置
    时间插件之My97DatePickerBeta
    Idea根据表自动生成实体
    验证码图片(个性化+)
    QQ第三方登录
    生成二维码
    Ehcache 的简单实用 及配置
  • 原文地址:https://www.cnblogs.com/wxdlut/p/15064945.html
Copyright © 2011-2022 走看看