需求背景
SpringBoot用法:动态修改日志输出级别
问题痛点
SpringBoot在 spring-boot-starter-actuator 模块中提供了日志相关的EndPoint,通过该EndPoint可以在项目运行时不需要重启服务就可以修改日志的打印级别,解决了以前修改日志打印级别必须要重启服务的烦恼。
技术点
1. 集成actuator依赖组件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2. 配置EndPoint
# log
management:
endpoints:
web:
exposure:
include: loggers
代码演示
1. 项目目录结构
2. pom.xml依赖组件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.md</groupId>
<artifactId>spring-boot2-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>spring-boot2-log-level</artifactId>
<packaging>jar</packaging>
<name>spring-boot2-log-level</name>
<description>Spring Boot, MVC, Rest API for App</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 构建成可运行的Web项目 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib-ext-spring</artifactId>
</dependency>
<!-- swagger集成 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<!-- 默认swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!-- 更易用第三方swagger-ui组件 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. application.yml配置
server:
port: 9090
# log
management:
endpoints:
web:
exposure:
include: loggers
4. LogController设置类
我把接口做成了通过接口代码访问。当然,你也可以通过直接请求接口
LogController:
package com.md.demo.rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.md.demo.util.HttpRequestUtil;
import com.md.demo.util.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
/**
* @author Minbo
*/
@RestController
@RequestMapping("/log")
@Api(tags = { "接口-演示" })
@Slf4j
public class LogController {
@Autowired
private Environment environment;
/**
* http://localhost:9090/testLog
*
* @return
*/
@GetMapping("/testLog")
public String testLog() {
log.debug("this is debug log");
log.info("this is info log");
return "Hello greetings from spring-boot2-log-level";
}
/**
* http://localhost:9090/getLogger
*
* @return
*/
@ApiOperation(value = "获得当前项目:日志输出级别", httpMethod = "GET")
@GetMapping("/getLogger")
public JsonResult getLogger() {
String port = this.environment.getProperty("local.server.port");
String url = "http://localhost:" + port + "/actuator/loggers/com.md";
String result = HttpRequestUtil.sendGet(url);
log.info("当前项目:日志输出级别,url={},result={}", url, result);
return JsonResult.ok(result);
}
/**
* http://localhost:9090/setLogger
*
* @return
*/
@ApiOperation(value = "设置当前项目:日志输出级别(INFO/DEBUG)", httpMethod = "POST")
@PostMapping("/setLogger")
public JsonResult setLogger(@RequestHeader String logLevel) {
String port = this.environment.getProperty("local.server.port");
String url = "http://localhost:" + port + "/actuator/loggers/com.md";
String param = "{\"configuredLevel\":\"" + logLevel + "\"}";
String result = HttpRequestUtil.sendJsonPost(url, param);
log.info("设置当前项目:日志输出级别,url={},param={},result={}", url, param, result);
return JsonResult.ok();
}
}
5. 启动类
Application:
package com.md.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
/**
* 程序主入口
*
* @author Minbo
*
*/
@SpringBootApplication
@EnableSwaggerBootstrapUI
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
/**
* 开启过滤器功能
*
* @return
*/
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
/**
* 跨域过滤器
*
* @return
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
接口测试
1. 启动后,访问地址:http://localhost:9090/doc.html (已集成了swagger2框架,Swagger集成用法教程)
2. 获得当前项目:日志输出级别
3. 设置当前项目:日志输出级别(INFO/DEBUG)
设置成INFO级别:
查看最新日志级别:
4. 接口日志输出测试
@GetMapping("/testLog")
public String testLog() {
log.debug("this is debug log");
log.info("this is info log");
return "Hello greetings from spring-boot2-log-level";
}
控制台输出:
只输出了info级别日志,证明已生效
完整源码下载
下一章教程
SpringBoot从入门到精通教程(二十九)- 微信企业支付集成(五分钟集成)
该系列教程
我的专栏
至此,全部介绍就结束了
-------------------------------
-------------------------------
关于我(个人域名)
期望和大家一起学习,一起成长,共勉,O(∩_∩)O谢谢
欢迎交流问题,可加个人QQ 469580884,
或者,加我的群号 751925591,一起探讨交流问题
不讲虚的,只做实干家
Talk is cheap,show me the code