• Logback 过滤特定字符串的日志

    有一个第三方的包,在运行时会打出大量我觉得没有用的日志,假设它都以abcdef开头,要怎么办呢?一般的 log 过滤,都是按等级来设置的,例如不记录 debug、info 级别的 log。如果涉及到字符串的匹配,要怎么做?

    做法是在logback.xml<appender>里面,加上<filter>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>%d{yy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{32} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    
        <filter class="com.xxxxxxx.MyThresholdFilter"/>  <!-- 加在这里 -->
    </appender>

    然后另外再创建这个MyThresholdFilter.java

    public class MyThresholdFilter extends ThresholdFilter {
        @Override
        public FilterReply decide(ILoggingEvent event) {
            if (event.getMessage().startsWith("abcdef")) {
                return FilterReply.DENY;
            }
            return FilterReply.NEUTRAL;
        }
    }
  • Spring Boot 3.x swagger 迁移 SpringFox 到 SpringDoc

    背景

    有一个项目升级到 Spring Boot 3.0,同事踩坑填坑花了点时间。遇到最大的一个坑就是 swagger 了,我顺便记录一下。

    SpringFox

    可以去它的官网看,SpringFox 已经有两三年没有更新了,属于被遗忘的项目。我去年也遇到 SpringFox 的问题,当时我用 Spring Boot 2.6,已经出现了不兼容报错的情况,所以退回了 2.5。今年是 Spring Boot 3.0,SpringFox 直接就别用了。

    SpringDoc

    SpringDoc 可以自动化生成 API 文档,它支持:(注意,本文所指均是 SpringDoc v2 版本)

    • OpenAPI 3
    • Spring Boot v3 (Java 17 & Jakarta EE 9)
    • JSR-303, specifically for @NotNull, @Min, @Max, and @Size.
    • Swagger-ui
    • OAuth 2
    • GraalVM native images

    从 SpringFox 迁移

    引入依赖

    把原来的io.springfoxswagger 2相关的依赖都删除,然后添加 SpringDoc 的依赖:

    <dependency>
       <groupId>org.springdoc</groupId>
       <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
       <version>2.1.0</version>
    </dependency>

    替换注解

    把原来 swagger 2 的注解替换成 swagger 3 的,springdoc-openapi-starter-webmvc-ui中已经包含了 swagger 3 的依赖。

    • @Api → @Tag
    • @ApiIgnore → @Parameter(hidden = true) 或 @Operation(hidden = true) 或 @Hidden
    • @ApiImplicitParam → @Parameter
    • @ApiImplicitParams → @Parameters
    • @ApiModel → @Schema
    • @ApiModelProperty(hidden = true) → @Schema(accessMode = READ_ONLY)
    • @ApiModelProperty → @Schema
    • @ApiOperation(value = "foo", notes = "bar") → @Operation(summary = "foo", description = "bar")
    • @ApiParam → @Parameter
    • @ApiResponse(code = 404, message = "foo") → @ApiResponse(responseCode = "404", description = "foo")

    之后 swagger 就可以在 http://server:port/context-path/swagger-ui.html 访问了。

    简单例子

    创建一个 controller:

    @RestController
    @RequestMapping("/test")
    public class TestController {
    
        @GetMapping("/greet")
        @CrossOrigin
        @Operation(summary = "say hello", description = "这里写描述")
        public String greet(@RequestParam(required = false) String name) {
            return "hello " + name;
        }
    }

    访问 swagger 大概是这样:

    具体的接口:

    结语

    上面只展示了最简单的使用,高级的用法和具体的配置在这里先不展开,需要时自己看官网文档。

    参考链接

  • Spring Boot 动态修改日志级别

    背景

    服务在生产环境跑,出了点问题,需要 debug 级别的日志;但是平时生产环境谁用 debug,都是用 info 级别。

    按一般的流程,改日志级别需要修改文件、重新打包发版,重启是免不了了,但重启可能导致问题不能复现。

    现在才知道,日志级别是可以在运行过程中动态修改的。记录下来。

    依赖

    这个功能有赖于 Spring Boot Actuator。诶,又是你,之前项目中已经有引入的,用来做服务的监控。

    如果没有引入,需要在pom.xml中添加

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    配置

    然后找一下配置项management.endpoints.web.exposure.include是否存在,如果没有就添加

    management.endpoints.web.exposure.include=info,health,loggers

    如果有的话,就在原有值里加上loggers即可。

    接口

    开启了 loggers endpoint,应用启动后就可以访问以下3个接口:

    • GET /actuator/loggers 返回当前应用全部的日志级别信息
    • GET /actuator/loggers/{name} 查看{name}的日志级别
    • POST /actuator/loggers/{name} 修改{name}的日志级别

    首先访问第一个接口(http://localhost:8080/actuator/loggers)看一看:

    找到loggers部分,我这里返回的是

    "loggers": {
        "ROOT": {
            "configuredLevel": "INFO",
            "effectiveLevel": "INFO"
        }
    }

    表示根节点的日志级别是INFO。(访问http://localhost:8080/actuator/loggers/ROOT也可以看到)

    那么要怎么修改呢,调用对应的POST接口即可:

    curl -X POST http://localhost:8080/actuator/loggers/ROOT  -H "Content-Type: application/json"  -d "{\"configuredLevel\":\"DEBUG\",\"effectiveLevel\":\"DEBUG\"}"

    再次查看GET接口,可以看到已经变为DEBUG级别。

    有关原理和其他细节,可以查看以下的参考。

    相关参考

    1. Spring Boot 系列(4):日志动态配置详解 – 掘金 (juejin.cn)