# api-logging-spring-boot-starter
**Repository Path**: mrbox/api-logging-spring-boot-starter
## Basic Information
- **Project Name**: api-logging-spring-boot-starter
- **Description**: API-logging is a Spring AOP-based component that automatically logs HTTP requests and responses in Spring Web applications.api-logging 是一个基于 Spring AOP 的 API 日志记录组件,用于自动记录 Spring Web 应用中的 HTTP 请求和响应信息。
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-01-28
- **Last Updated**: 2026-01-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: API日志, 请求日志, 响应日志, 日志组件, traceid
## README
# api-logging 组件使用文档

[](https://github.com/mr-box/api-logging-spring-boot-starter/releases)
[](https://www.apache.org/licenses/LICENSE-2.0.html)
[](https://jitpack.io/#mr-box/api-logging-spring-boot-starter)
## 简介
api-logging 是一个基于 Spring AOP 的 API 日志记录组件,用于自动记录 Spring Web 应用中的 HTTP 请求和响应信息。该组件通过切面技术拦截 Controller 方法的调用,记录请求参数、响应结果、处理时间等信息,默认记录精简的日志信息,并支持多种触发条件来决定何时记录详细日志。
## 核心依赖
该模块依赖以下组件:
- `spring-boot-starter-web`: Spring Web MVC 基础。
- `spring-boot-starter-aop`: Spring AOP,用于实现切面功能。
## 功能特性
- 支持启用、禁用组件
- 自动记录请求和响应信息
- 支持精简和详细两种日志模式
- 多种触发器决定何时记录详细日志
- 支持自定义记录详细日志的触发器
- 支持指定URI强制记录详细日志
- 敏感参数脱敏
- 异常信息和堆栈跟踪记录
- 默认基于 SLF4J 的 JSON 格式日志输出
- 支持自定义日志格式
- 支持过滤器配置,自定义不打印日志的场景
## 快速开始
组件所有配置均有默认值,添加依赖后启用该组件即可使用。
### 1. 添加依赖
本组件通过 JitPack 发布。
**第一步**:在项目根目录的 `pom.xml` 中添加 JitPack 仓库源:
```xml
jitpack.io
https://jitpack.io
```
**第二步**:添加组件依赖:
```xml
com.github.mr-box
api-logging-spring-boot-starter
1.0.0
```
### 2. 启用组件
在 `application.yml` 或 `application.properties` 中启用组件:
```yaml
mr-box:
api-logging:
enabled: true
```
## 配置说明
下面列举的配置项,除特殊说明外,示例值均为组件默认值。
### 基础配置
```yaml
mr-box:
api-logging:
# 是否启用日志记录
enabled: false
# 日志模式:SIMPLE(精简)或 DETAILED(详细)
logMode: SIMPLE
# 参数或返回值序列化的最大长度
maxPayloadLength: 1024
```
### 敏感信息配置
```yaml
mr-box:
api-logging:
sensitive:
# 需要脱敏的参数名称列表,区分大小写
argNames:
- password
# 需要脱敏的请求头名称列表,不区分大小写
requestHeaders:
- Authorization
- Token
# 脱敏替换字符
mask: "****"
```
### 异常堆栈配置
```yaml
mr-box:
api-logging:
exceptionStack:
# 是否启用异常堆栈记录
enabled: false
# 堆栈跟踪最大行数
maxLines: 20
# 项目包名前缀
# 如果不为空,只打印到含有该前缀的异常堆栈信息以及后面2行
# 默认为空字符串
packagePrefix: "" # 示例: com.example
```
### 详细日志触发配置
```yaml
mr-box:
api-logging:
# 启用的详细日志触发器
# - header: 通过请求头触发详细日志
# - exception: 通过异常触发详细日志
# - statusCode: 通过HTTP状态码触发详细日志
triggers:
# 默认启用以下两个
- exception
- statusCode
# 请求头触发配置
headerTrigger:
# 触发详细日志的请求头名称
headerName: X-Log-Mode
# 触发详细日志的请求头值
detailedValue: DETAILED
# 触发详细日志的 HTTP 状态码
detailedLogOnStatusCodes: 400,401,403,404,405,500,501,502,503,504
# 强制使用详细日志的 URI 模式(默认为空)
forceDetailedLogPatterns:
- "/api/admin/**"
- "/debug/**"
```
### 特殊Content-Type配置
```yaml
mr-box:
api-logging:
# 不记录日志的请求Content-Type集合。 不区分大小写、前缀匹配。
excluded-argument-on-content-types:
- application/octet-stream
- multipart/form-data
```
## 使用示例
### 1. 精简模式日志输出示例
```json
{
"logMode": "SIMPLE",
"requestTimestamp": 1747707931829,
"uri": "/api/users/list",
"controllerHandler": "UserController#listUsers",
"processingTimeMs": 286
}
```
### 2. 详细模式日志输出示例
```json
{
"logMode": "DETAILED",
"requestTimestamp": 1747708132583,
"uri": "/api/users/list",
"controllerHandler": "UserController#listUsers",
"processingTimeMs": 239,
"statusCode": 200,
"requestHeader": {
"content-length": "276",
"host": "localhost:8080",
"content-type": "application/json",
"user-agent": "PostmanRuntime/7.43.0"
},
"requestParams": "{\"username\":\"guest\",\"page\":1}",
"responseData": "{\"code\":0,\"data\":[...]}"
}
```
### 3. 异常情况日志输出示例
```json
{
"logMode": "DETAILED",
"requestTimestamp": 1747708262354,
"uri": "/api/users/list",
"controllerHandler": "UserController#listUsers",
"processingTimeMs": 3,
"statusCode": 500,
"errorIndicator": "ERROR:NullPointerException",
"requestHeader": {
"content-length": "276",
"host": "localhost:8080",
"content-type": "application/json"
},
"requestParams": "{\"username\":\"guest\"}",
"exceptionStacktrace": "java.lang.NullPointerException: null\n\tat com.example.demo.controller.UserController.listUsers(UserController.java:25)\n..."
}
```
## 功能扩展
api-logging 组件提供了多个扩展点,允许自定义日志记录行为。
### 过滤器功能
组件支持过滤器功能,允许依赖方自定义哪些接口需要记录日志。过滤器分为两类:
#### 前置过滤器(PreFilter)
在Controller方法执行前进行快速失败判断,可以基于请求信息(URI、参数、请求头等)决定是否跳过日志记录。
#### 后置过滤器(PostFilter)
在Controller方法执行后进行判断,可以基于响应结果、异常信息、执行时间等决定是否跳过日志记录。
#### 过滤器配置
如果内置过滤器满足要求,只需要将过滤器实现注册为Spring Bean即可自动生效。
使用内置过滤器,只需要注册Bean,无需额外配置
```java
@Bean
public UriPatternPreFilter uriPatternPreFilter() {
Set excludePatterns = Sets.newHashSet("/health", "/actuator/**");
return new UriPatternPreFilter(excludePatterns);
}
```
可条件化启用过滤器或制定环境启用
```java
@Bean
@ConditionalOnProperty(name = "app.logging.xxxx.enabled", havingValue = "true")
@Profile("prod")
public UriPatternPreFilter uriPatternPreFilter() {
return new UriPatternPreFilter(Sets.newHashSet("/health", "/actuator/**"));
}
```
#### 自定义前置过滤器示例
实现 `PreFilter` 接口,并将其注册为 Spring Bean:
```java
@Component
public class CustomPreFilter implements PreFilter {
@Override
public boolean shouldSkipLogging(ProceedingJoinPoint joinPoint, HttpServletRequest request) {
// 自定义逻辑,返回true表示跳过日志记录
if (request != null && "/health".equals(request.getRequestURI())) {
return true; // 跳过健康检查接口的日志
}
return false;
}
@Override
public int getOrder() {
return -100; // 执行顺序,数值越小优先级越高
}
}
```
#### 内置过滤器示例
**UriPatternPreFilter** - 基于URI模式过滤:
```java
@Bean
public UriPatternPreFilter uriPatternPreFilter() {
Set excludePatterns = Sets.newHashSet(
"/health",
"/actuator/**",
"/static/**"
);
return new UriPatternPreFilter(excludePatterns);
}
```
**RequestHeaderPreFilter** - 基于请求头过滤:
```java
@Bean
public RequestHeaderPreFilter requestHeaderPreFilter() {
Map excludeHeaders = new HashMap<>();
excludeHeaders.put("X-Client", "IOS");
excludeHeaders.put("X-Monitor", "true");
return new RequestHeaderPreFilter(excludeHeaders);
}
```
**MethodNamePreFilter** - 基于控制器或方法名过滤:
```java
@Bean
public MethodNamePreFilter methodNamePreFilter() {
Set excludeClasses = Sets.newHashSet("HealthController", "MonitorController");
Set excludeMethods = Sets.newHashSet("health", "ping", "status");
return new MethodNamePreFilter(excludeClasses, excludeMethods);
}
```
**ProcessingTimePostFilter** - 基于处理时间过滤:
```java
@Bean
public ProcessingTimePostFilter processingTimePostFilter() {
// 只记录超过500ms的慢请求
return new ProcessingTimePostFilter(500);
}
```
### 自定义详细日志触发器
实现 `DetailedLogTrigger` 接口,并将其注册为 Spring Bean:
```java
@Component
public class CustomDetailedLogTrigger implements DetailedLogTrigger {
@Override
public String name() {
return "custom";
}
@Override
public boolean shouldLogDetailed(HttpServletRequest request,
HttpServletResponse response,
Throwable exception,
ApiLoggingDataContext logDataContext,
ApiLoggingProperties properties) {
// 自定义逻辑,决定是否触发详细日志
return true;
}
}
```
然后在配置中启用该触发器:
```yaml
mr-box:
api-logging:
triggers: custom,...
```
> 触发器名称可以重名,例如自定义的触发器也叫`response`,那么默认触发器和自定义触发器都会生效
### 自定义日志内容格式化器
实现 `LogContentFormatter` 接口,并将其注册为 Spring Bean
```java
@Component
@Primary
public class CustomLogContentFormatter implements LogContentFormatter {
// 实现接口中的方法
}
```
## 注意事项
1. 默认情况下组件是禁用的,需要显式配置 `mr-box.api-logging.enabled=true` 来启用
2. 组件禁用状态下启动应用,不支持运行中启用组件。启用状态下启动应用,支持运行中实时禁用或启用组件。
3. 对于文件上传等特殊请求,会自动排除参数记录
4. 敏感信息会自动进行脱敏处理
5. 可以通过请求头 `X-Log-Mode: DETAILED` 临时启用详细日志
> enabled 需要为启用状态
> triggers 配置列表需要包含`header`
6. 异常情况下会自动记录堆栈信息
> 需开启异常堆栈记录
> 默认关闭时只记录一行异常类型+异常信息
7. 通常情况细触发器的优先级大于过滤器,但下面情况除外:
> 触发器依赖接口执行结果,但使用了前置过滤器,且符合过滤条件
> 这种情况应该使用后置过滤器,后置过滤器的优先级永远低于触发器
## 最佳实践
1. 建议在开发环境使用详细模式,生产环境使用精简模式
2. 合理配置 `maxPayloadLength` 避免日志过大
3. 及时更新敏感信息配置,确保信息安全
4. 使用 `forceDetailedLogPatterns` 为重要接口配置详细日志
## 常见问题
1. Q: 为什么某些请求没有记录参数?
A:
- 检查请求的 Content-Type 是否在 `excludedArgumentOnContentTypes` 中
- 确认 Controller 类上是否有 @Controller 或 @RestController 注解
- 检查是否启用了 Spring AOP
2. Q:日志内容过长
A:调整 max-payload-length 参数限制日志内容长度
3. Q:日志中的异常堆栈信息不足
A:启用异常堆栈记录,并设置合适的记录行数
```java
mr-box:
api-logging:
enabled: on
exception-stack:
enabled: true # 默认false,只打印一行异常类型+异常信息
package-prefix: "" # 默认空,可配置项目包名前缀,如com.example
max-lines: 20 # 默认20
```
4. Q: 如何临时查看某个请求的详细日志?
A: 方法一:在请求头中添加 `X-Log-Mode: DETAILED`
方法二:将接口地址配置`forceDetailedLogPatterns`中
5. Q: 如何自定义日志格式?
A: 实现 `LogContentFormatter` 接口并注册为 Spring Bean
6. Q: 如何添加自定义的详细日志触发条件?
A: 实现 `DetailedLogTrigger` 接口并注册为 Spring Bean
7. Q: 触发器没生效?
A: 检查是否被前置过滤器过滤掉了,依赖接口响应的触发器,需要实现`PostFilter`,不能使用`PreFilter`
8. Q: 如何自定义过滤器来控制哪些接口记录日志?
A: 实现 `PreFilter`(前置过滤)或 `PostFilter`(后置过滤)接口并注册为 Spring Bean即可自动生效
9. Q: 过滤器不生效怎么办?
A: 检查以下几点:
- 确认过滤器已正确注册为 Spring Bean
- 确认过滤器的 `shouldSkipLogging` 方法逻辑正确
- 检查是否有其他过滤器先返回了跳过日志的结果
10. Q: 如何调试过滤器执行情况?
A: 启用DEBUG日志级别:`logging.level.com.github.mrbox.apilogging=DEBUG`