龙空技术网

动态设置 log4j2 日志的级别不能落

BUG弄潮儿 49

前言:

如今兄弟们对“log4j monitorinterval”都比较注意,咱们都想要学习一些“log4j monitorinterval”的相关文章。那么小编同时在网络上搜集了一些有关“log4j monitorinterval””的相关知识,希望咱们能喜欢,兄弟们快快来了解一下吧!

上篇[ SpringBoot 动态设置 logback 日志的级别 ] 说了 logback 动态设置日志级别。这篇来说下 log4j2 日志框架结合 SpringBoot 动态设置日志级别。因为 log4j2 日志框架也有非常多的公司采用,毕竟 logback 和 log4j2 是现在用的最多的两个日志框架。都不能落对吧。

0x01:pom.xml 引入依赖

<project xmlns="; xmlns:xsi=";    xsi:schemaLocation=";;>    <modelVersion>4.0.0</modelVersion>    <groupId>com.olive</groupId>    <artifactId>valid-log4j2</artifactId>    <version>0.0.1-SNAPSHOT</version>    <packaging>jar</packaging>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>2.1.8.RELEASE</version>        <relativePath />     </parent>    <name>valid-demo</name>    <url>;/url>    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    </properties>    <dependencies>        <dependency>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-web</artifactId>              <exclusions><!-- 去掉springboot默认配置 -->                  <exclusion>                      <groupId>org.springframework.boot</groupId>                      <artifactId>spring-boot-starter-logging</artifactId>                  </exclusion>              </exclusions>          </dependency>         <dependency> <!-- 引入log4j2依赖 -->              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-log4j2</artifactId>          </dependency>     </dependencies></project>

因为 SpringBoot 默认使用 logback 记录日志。所以要排查 logback 日志框架 spring-boot-starter-logging,在引入 log4j2 日志框架 spring-boot-starter-log4j2。

0x02:Controller 控制器编写

Controller 基本框架

package com.olive.controller;import java.util.HashMap;import java.util.Map;import org.apache.logging.log4j.Level;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.core.LoggerContext;import org.apache.logging.log4j.core.config.Configuration;import org.apache.logging.log4j.core.config.LoggerConfig;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.slf4j.impl.StaticLoggerBinder;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class LoggerController {    private final static  Logger logger = LoggerFactory.getLogger(LoggerController.class);    // TODO }
打印各级别日志
@RequestMapping("/logger/print")public Map loggerPrint(){    Map result = new HashMap();    result.put("code", 200);    result.put("msg", "success");    logger.debug("loggerPrint debug>>>>");    logger.info("loggerPrint info>>>>");    logger.warn("loggerPrint warn>>>>");    logger.error("loggerPrint error>>>>");    return result;}
打印所有日志对象
@RequestMapping("/logger/printAllLogger")public Map printAllLogger(){    Map result = new HashMap();    result.put("code", 200);    result.put("msg", "success");    LoggerContext ctx = (LoggerContext) LogManager.getContext(false);    Configuration config = ctx.getConfiguration();    Map<String, LoggerConfig> loggerConfigs = config.getLoggers();    System.out.println("printAllLogger begin>>>>>>>>");    loggerConfigs.forEach((name, loggerConfig) -> {        System.out.println("name = " + name);       System.out.println("loggerConfig = " + loggerConfig);    });    System.out.println("printAllLogger end>>>>>>>>");    return result;}
动态设置日志对象的日志级别
@RequestMapping("/logger/level")public Map loggerLevelChange(String level){    Map result = new HashMap();    result.put("code", 200);    result.put("msg", "success");    String loggerFactoryClassStr = StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr();    System.out.println("loggerFactoryClassStr>>>>" + loggerFactoryClassStr);        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);    Configuration config = ctx.getConfiguration();    LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);    switch (level) {    case "debug":        loggerConfig.setLevel(Level.DEBUG);        break;    case "info":        loggerConfig.setLevel(Level.INFO);        break;    case "warn":        loggerConfig.setLevel(Level.WARN);        break;    case "error":        loggerConfig.setLevel(Level.ERROR);        break;    default:        break;    }    ctx.updateLoggers();    return result;}

0x04:log4j2-spring.xml 配置

<?xml version="1.0" encoding="UTF-8"?><!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出--><!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--><configuration monitorInterval="5">  <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->  <!--变量配置-->  <Properties>    <!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->    <!-- %logger{36} 表示 Logger 名字最长36个字符 -->    <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />  </Properties>  <appenders>    <console name="ConsoleOut" target="SYSTEM_OUT">      <!--输出日志的格式-->      <PatternLayout pattern="${LOG_PATTERN}"/>      <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->   <!--    <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> -->    </console>  </appenders>  <loggers>    <root level="debug">      <appender-ref ref="ConsoleOut"/>    </root>  </loggers></configuration>

这里只配置了打印到控制台的 ROOT logger。

0x05:编写引导类

@SpringBootApplicationpublic class Application {    public static void main( String[] args )    {        SpringApplication.run(Application.class, args);    }}

启动服务

打印各级别日志

因为 log4j2-spring.xml 配置的级别是 debug,所以可以在控制台看到如下打印

21:08:52.298 [http-nio-8080-exec-1] DEBUG com.olive.controller.LoggerController - loggerPrint debug>>>>21:08:52.298 [http-nio-8080-exec-1] INFO  com.olive.controller.LoggerController - loggerPrint info>>>>21:08:52.298 [http-nio-8080-exec-1] WARN  com.olive.controller.LoggerController - loggerPrint warn>>>>21:08:52.298 [http-nio-8080-exec-1] ERROR com.olive.controller.LoggerController - loggerPrint error>>>>
打印所有日志对象

在控制台只看见打印了 ROOT logger 对象。

printAllLogger begin>>>>>>>>name = loggerConfig = rootprintAllLogger end>>>>>>>>
动态修改日志的级别

再次调用 接口打印日志,在控制台看到不在打印 debug 级别日志

21:19:25.756 [http-nio-8080-exec-6] INFO  com.olive.controller.LoggerController - loggerPrint info>>>>21:19:25.756 [http-nio-8080-exec-6] WARN  com.olive.controller.LoggerController - loggerPrint warn>>>>21:19:25.756 [http-nio-8080-exec-6] ERROR com.olive.controller.LoggerController - loggerPrint error>>>>
修改 log4j2-spring.xml 配置
  <loggers>    <root level="debug">      <appender-ref ref="Console"/>    </root>     <logger name="org.springframework" level="info" additivity="true">     </logger>     <logger name="org.hibernate" level="warn" additivity="true">     </logger>  </loggers>

重启服务,再次调用 接口打印日志对象

printAllLogger begin>>>>>>>>name = loggerConfig = rootname = org.springframeworkloggerConfig = org.springframeworkname = org.hibernateloggerConfig = org.hibernateprintAllLogger end>>>>>>>>

标签: #log4j monitorinterval