日志组件之debug动态开关

本文介绍如何在Logback中实现动态开启或关闭DEBUG级别日志的方法。通过自定义TurboFilter,结合动态配置组件DebugLevelConfig,可以在不影响系统性能的前提下灵活调整日志级别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

日志组件之debug动态开关

一、应用场景

二、logback简介

三、logback应用debug动态开关

 


一、应用场景

生产环境,系统日志记录级别一般高于或等于INFO,不会开启DEBUG级别的日志打印。

但如果生产环境系统出现问题,需要在一段时间内启用debug日志,以便调查分析问题,那怎么办呢?

本文将提供一种可行方案。

 

二、logback简介

Logback是由log4j创始人设计的又一个开源日志组件。

logback当前分成三个模块:logback-core,logback-classic和logback-access。logback-core是其它两个模块的基础模块。

logback-classic是log4j的一个 改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日志系统如log4j或JDK14Logging。

logback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能。

       

三、logback应用debug动态开关

       在logback中有一个过滤器TurboFilter,有以下特点:

       1.TurboFilter会试图记录上下文环境。因此他们会在每次logging请求产生的时候调用,而不是一个指定的appender使用时才出现。

       2.更重要的是,TurboFilter会在日志事件对象创建前调用。因此它具有更高性能的过滤日志事件,即使在事件被创建之前

      

       相关代码与配置:

       DebugLevelTurboFilter 基于TurboFilter。代码如下:

       

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
          
import ch.qos.logback.classic.Level ;
import ch.qos.logback.classic.Logger ;
import ch.qos.logback.classic.turbo.TurboFilter ;
import ch.qos.logback.core.spi.FilterReply ;
import java.util.List ;
import org.slf4j.Marker ;
public class DebugLevelTurboFilter extends TurboFilter
{
protected static DebugLevelConfig debugLevelConfig = DebugLevelConfig . getInstance ();
public FilterReply decide ( Marker marker , Logger logger , Level level , String format , Object [] params , Throwable t )
{
boolean acceptDebug = acceptDebug ( logger , level , debugLevelConfig );
if ( acceptDebug ) {
return FilterReply . ACCEPT ;
}
return FilterReply . NEUTRAL ;
}
protected boolean acceptDebug ( Logger logger , Level level , DebugLevelConfig logLevelDynConfig ) {
if (( null == logger ) || ( null == level ) || (! level . isGreaterOrEqual ( Level . DEBUG )) || ( null == logLevelDynConfig ) || (! logLevelDynConfig . isEnabled ()))
{
return false ;
}
if ( logLevelDynConfig . isAcceptAll ())
return true ;
String name ;
if (( null != logLevelDynConfig . getMatchList ()) && (! logLevelDynConfig . getMatchList (). isEmpty ())) {
name = logger . getName ();
for ( String className : logLevelDynConfig . getMatchList ()) {
if (( name . equals ( className )) || ( name . startsWith ( className )))
{
return true ;
}
}
}
return false ;
}
public void start ()
{
super . start ();
}
}
 来自CODE的代码片
DebugLevelTurboFilter.java

      

       DebugLevelTurboFilter 依赖于一个动态配置组件 DebugLevelConfig(依赖于 diamond )

       

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
          
import ch.qos.logback.classic.Level ;
import java.util.List ;
public class DebugLevelConfig extends AbstractDynamicConfig
{
private boolean enabled ;
private boolean acceptAll ;
private List < String > matchList ;
private static DebugLevelConfig instance = new DebugLevelConfig ();
public boolean isEnabled ()
{
return this . enabled ;
}
public void setEnabled ( boolean enabled ) {
this . enabled = enabled ;
}
public Level getLevel () {
return Level . DEBUG ;
}
public List < String > getMatchList () {
return this . matchList ;
}
public void setMatchList ( List < String > matchList ) {
this . matchList = matchList ;
}
public boolean isAcceptAll () {
return this . acceptAll ;
}
public void setAcceptAll ( boolean acceptAll ) {
this . acceptAll = acceptAll ;
}
public static DebugLevelConfig getInstance ()
{
return instance ;
}
static
{
try
{
instance . init ();
instance . setRemoteConfigManagerListener ( DiamondRemoteConfigManagerListener . getInstance ());
} catch ( Exception e ) {
e . printStackTrace ();
}
}
}
 来自CODE的代码片
DebugLevelConfig.java

      

       logback.xml中添加一行配置:

       <turboFilterclass="org.oschina.log.logback.filter.DebugLevelTurboFilter" />

       

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
          
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- //TODO: 日志文件目录(以应用名来命名) -->
<property name= "LOG_HOME" value= "../logs/captcha-web" />
<!-- //TODO: 日志文件名(以应用名来命名,如 [captcha-web]) -->
<property name= "LOG_FIEL_NAME" value= "captcha" />
<!-- debug级别日志打印过滤器 -->
<turboFilter class= "org.oschina.log.logback.filter.DebugLevelTurboFilter" />
<!-- 控制台日志打印(生产环境不允许开启) -->
<appender name= "STDOUT" class= "ch.qos.logback.core.ConsoleAppender" >
<encoder>
<pattern>[%date %t %-5p]-%c [%file:%line] %m%n </pattern>
</encoder>
</appender>
<!-- 所有日志(记录debug,info,warn,error等别级的日志) -->
<appender name= "log-all" class= "ch.qos.logback.core.rolling.RollingFileAppender" >
<file>${LOG_HOME}/${LOG_FIEL_NAME}-all.log </file>
<rollingPolicy class= "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >
<FileNamePattern>${LOG_HOME}/${LOG_FIEL_NAME}-all-%d{yyyy-MM-dd}.log </FileNamePattern>
</rollingPolicy>
<encoder>
<pattern>[%date [%thread] %-5p]-%c [%file:%line] %m%n </pattern>
</encoder>
<append>true </append>
<prudent>false </prudent>
<!--
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
-->
</appender>
<!-- error日志(只记录error级别的日志) -->
<appender name= "log-error" class= "ch.qos.logback.core.rolling.RollingFileAppender" >
<file>${LOG_HOME}/${LOG_FIEL_NAME}-error.log </file>
<rollingPolicy class= "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >
<FileNamePattern>${LOG_HOME}/${LOG_FIEL_NAME}-error-%d{yyyy-MM-dd}.log </FileNamePattern>
</rollingPolicy>
<encoder>
<pattern>[%date [%thread] %-5p]-%c [%file:%line] %m%n </pattern>
</encoder>
<append>true </append>
<prudent>false </prudent>
<filter class= "ch.qos.logback.classic.filter.ThresholdFilter" >
<level>ERROR </level>
</filter>
</appender>
<!-- //TODO: 特殊loger(包或类)日志别级设置
<logger name="com.alibaba.dubbo" level="WARN"/>
-->
<!-- 根loger ,生产环境必须配置为INFO及以上级别 -->
<root level= "info" >
<!--<appender-ref ref="STDOUT" />-->
<appender-ref ref= "log-all" />
<appender-ref ref= "log-error" />
</root>
</configuration>
 来自CODE的代码片
logback.xml

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值