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("=== 我輸出了 === \n "); 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("\n 僅僅移除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