当前位置: 首页 > 后端技术 > Java

【小知识】log4j2动态修改日志级别(轻量级)

时间:2023-04-01 19:21:31 Java

部分日志在后台代码中添加,只需要在排错&进程跟踪时打印出来,其他时候不需要打印出来。解决办法是写一个通用的Logger类和一个“日志级别”配置项。打印日志时,会调用logger.log方法。该方法内部通过判断日志级别调用log.debug、log.info等方法。打印日志的方法不变(业务代码直接调用log.debug、log.info等方法),通过配置动态修改指定业务类中日志对象的日志级别。上述方案一:一般的Logger类需要覆盖日志的所有方法(log.debug、log.info等),需要写很多方法,太麻烦了。方案二:可以实现精细化管理,无需修改原有代码。那么如果不想管理的那么精细,只想使用通用的Logger类进行简单管理怎么办?实现方案一借鉴了上面方案二的核心代码:@Slf4j@ComponentpublicclassDynamicLogger{/***@paramdynamicLevel*@author*@date2022/12/615:09*/@Value("${log.dynamic.level:WARN}")//通过配置系统配置修改,也可以使用其他方法,但核心代码是一样的publicvoidsetDynamicLevel(StringdynamicLevel){log.info("[DynamicLog]收到日志级别配置[{}]",dynamicLevel);尝试{StringlogType=StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr();如果("org.apache.logging.slf4j.Log4jLoggerFactory".equals(logType)){LoggerContext.getContext(false)。getLogger(DynamicLogger.class.getName()).setLevel(Level.toLevel(dynamicLevel));}if(xxx){//logback和其他日志组件}else{log.error([动态日志]日志框架类别[{}]无法识别:类型{}",logType);}}catch(Exceptione){log.error("[动态日志]日志级别配置[{}]解析异常!",dynamicLevel,e);}}/***@returnorg.slf4j.Logger*@author*@date2022/12/615:35*/publicstaticLoggergetLogger(){返回日志;}}使用时,由原来的log.info改为DynamicLogger.getLogger.info,编写一个通用的Logger类和一个“日志级别”配置项。打印日志时,从Logger类中获取实际执行调用logger.log方法,通过方法内部判断日志级别动态修改当前日志对象的打印级别。对于方案2及以上,需要判断底层使用的是哪个日志组件。如果使用Springboot框架,Springboot提供了更高层次的抽象:@AutowiredprivateLoggingSystemloggingSystem;publicvoidsetDynamicLevel(StringdynamicLevel,StringloggerName){log.info("[动态日志]收到日志级别配置[{}]",dynamicLevel);尝试{LoggerConfigurationloggerConfiguration=loggingSystem.getLoggerConfiguration(loggerName);if(loggerConfiguration==null){log.error("[动态日志]没有获取[{}]日志配置",loggerName);返回;}ListsupportLevels=loggingSystem.getSupportedLogLevels().stream().map(Enum::name).collect(Collectors.toList());if(!supportLevels.contains(dynamicLevel)){log.error("[动态日志]不支持配置的[{}]日志级别",dynamicLevel);返回;}if(!loggerConfiguration.getEffectiveLevel().name().equals(dynamicLevel)){loggingSystem.setLogLevel(loggerName,LogLevel.valueOf(dynamicLevel));}别的{log.info("[动态日志]当前配置为[{}]日志级别",dynamicLevel);}}catch(Exceptione){log.error("[动态日志]日志级别配置[{}]解析异常!",dynamicLevel,e);}}但是这种方案也有局限性,就是只能修改配置好的Logger(比如xml文件中配置的Logger列表),比如不能单独修改某个类下的Logger对象(比如DynamicLogger类下日志对象的打印级别修改如方案1),只能修改配置Loggers中的Logger级别,例如:如果项目使用如下log4j2.xml文件,那么loggerName只能是com.xxx或ROOT。......对比以上两种方案,调整的对象是相互反向的。方案一:调整日志级别。如果级别调整到XML配置级别以下,则不会有日志;如果级别调整到配置级别以上,就会有日志。解决方案2:调整XML配置的级别。如果级别调整到日志类的打印级别以下,就会有日志;如果调整到日志类的打印级别之上,则不会有日志。参考:Java日志:动态调整日志级别https://juejin.cn/post/7140939233518649357别再随便敲日志了,教你动态修改日志级别!