https://github.com/null-object-0000/http-log-snap
一个轻量级的 Java HTTP 请求/响应日志记录库,快照式捕获完整的 HTTP 交互。同时支持客户端(如 OkHttp)和服务端(如 Spring MVC)场景。
https://github.com/null-object-0000/http-log-snap
Last synced: 7 months ago
JSON representation
一个轻量级的 Java HTTP 请求/响应日志记录库,快照式捕获完整的 HTTP 交互。同时支持客户端(如 OkHttp)和服务端(如 Spring MVC)场景。
- Host: GitHub
- URL: https://github.com/null-object-0000/http-log-snap
- Owner: null-object-0000
- License: mit
- Created: 2025-12-01T05:05:28.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-12-04T07:18:38.000Z (8 months ago)
- Last Synced: 2025-12-06T03:01:40.845Z (8 months ago)
- Language: Java
- Size: 138 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# HTTP Log Snap 📸
一个轻量级的 Java HTTP 请求/响应日志记录库,**快照式**捕获完整的 HTTP 交互。
同时支持 **客户端**(OkHttp)和 **服务端**(Spring MVC)场景。
## ✨ 为什么选择 HTTP Log Snap?
- 🔄 **双向支持** - 客户端发起请求、服务端处理请求,一套 API 全搞定
- ⏱️ **详细耗时** - DNS、连接、TTFB、下载...每个阶段耗时一目了然
- 📊 **多种格式** - 文本格式便于调试,JSON 格式便于分析
- 🛡️ **脱敏支持** - Authorization、Cookie 等敏感头自动脱敏
- 🎯 **零侵入** - 不改业务代码,Filter/EventListener 即插即用
- 🔧 **可扩展** - 格式化器、输出目标、适配器全部可定制
## 📦 安装
```xml
io.github.null-object-0000
http-log-snap
0.0.1
```
## 🚀 30 秒上手
### 客户端(OkHttp)
```java
// 1. 创建 OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
.eventListenerFactory(OkHttpLoggingEventListener.FACTORY)
.build();
// 2. 创建 Logger
HttpRequestLogger logger = HttpRequestLogger.forClient(HttpLogContext.of("创建订单"));
logger.putExtra("orderId", "ORD123");
// 3. 发起请求
String body = "{\"name\":\"test\"}";
logger.start(body);
Request request = new Request.Builder()
.url("https://api.example.com/orders")
.tag(HttpRequestLogger.class, logger)
.post(RequestBody.create(body, MediaType.parse("application/json")))
.build();
try (Response response = client.newCall(request).execute()) {
logger.end(response.body().string());
}
// 4. 输出日志
logger.log();
```
### 服务端(Spring Boot)
```yaml
# application.yml
mc:
http:
logging:
enabled: true
```
```java
// 方式1:实现 HttpLogCustomizer 统一定制(推荐)
@Component
public class MyHttpLogCustomizer implements HttpLogCustomizer {
@Override
public void customize(HttpRequestLogger logger, HttpServletRequest request) {
// 添加 traceId
logger.putExtra("traceId", request.getHeader("X-Trace-Id"));
// 根据路径设置接口名称
if (request.getRequestURI().startsWith("/api/users")) {
logger.setInterfaceName("用户服务");
}
}
}
// 方式2:在 Controller 中按需设置
HttpRequestLogger logger = HttpRequestLoggerHolder.get();
if (logger != null) {
logger.putExtra("orderId", "ORD123");
}
// 方式3:在全局异常处理器中记录异常(如果有 GlobalExceptionHandler)
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public BaseResponse> errorHandler(Exception e) {
HttpLoggingExceptionHandler.record(e); // 添加这一行
// ... 原有逻辑
return BaseResponse.error();
}
}
```
**搞定!** 服务端自动记录所有 HTTP 请求/响应。
## 📝 日志输出效果
### 客户端日志
```
15:42:31.123 --- LOG EXTRAS -------------------------------------------------------
{"userId":10086,"source":"app"}
15:42:31.123 --- START [NONE] 获取用户信息 (total: 245ms)
15:42:31.180 --> DNS LOOKUP (50ms)
15:42:31.210 --> CONNECTING (30ms) [192.168.1.100:54321 -> 203.0.113.50:443]
15:42:31.215 --> REQUEST START --------------------------------------------------->
GET https://api.example.com/users/123 HTTP/2
Authorization: ██
15:42:31.350 <-- RESPONSE START <--------------------------------------------------
HTTP/2 200 OK (130ms)
Content-Type: application/json
{"id":123,"name":"张三","email":"zhangsan@example.com"}
15:42:31.368 <-- END RESPONSE (18ms, 256-byte body)
```
### 服务端日志
```
15:42:31.100 --- LOG EXTRAS -------------------------------------------------------
{"orderId":"ORD123","channel":"web"}
15:42:31.100 --- START [SERVER] 用户登录 -> UserController.login (total: 156ms) [client: 192.168.1.50:52341]
15:42:31.102 --> REQUEST START --------------------------------------------------->
POST http://localhost:8080/api/login HTTP/1.1
Content-Type: application/json
{"username":"zhangsan","password":"****"}
15:42:31.245 <-- RESPONSE START <--------------------------------------------------
200 OK (handler: 135ms)
{"code":0,"message":"success","data":{"token":"eyJ..."}}
15:42:31.256 <-- END RESPONSE (11ms, 128-byte body)
```
### JSON 格式(便于 ELK 分析)
```json
{
"type": "HTTP_CLIENT",
"duration_ms": 245,
"network": {
"local_address": "192.168.1.100:54321",
"remote_address": "203.0.113.50:443"
},
"request": {
"method": "GET",
"url": "https://api.example.com/users/123"
},
"response": {
"code": 200,
"body": "{\"id\":123,\"name\":\"张三\"}"
},
"timing": {
"dns_lookup_ms": 50,
"connection_ms": 30,
"server_processing_ms": 130
}
}
```
## ⏱️ 性能指标
| 客户端指标 | 服务端指标 |
|-----------|-----------|
| DNS 解析时间 | 请求体读取时间 |
| TCP/TLS 连接时间 | Handler 执行时间 |
| 请求发送时间 | 响应构建时间 |
| TTFB(首字节时间)| 响应发送时间 |
| 内容下载时间 | 框架开销时间 |
## ⚙️ 默认配置
| 配置项 | 默认值 | 说明 |
|--------|------------------------|--------------------|
| 格式化器 | `JsonHttpLogFormatter` | JSON 格式 |
| 输出目标 | `Slf4jLogOutput` | 输出到 SLF4J(INFO 级别) |
| 请求体/响应体最大长度 | `无限制` | 默认不限制,可通过配置设置限制(超过限制会被截断) |
**⚠️ 重要提示:** 请求体和响应体的最大记录长度默认**无限制**(`-1`)。如果设置了限制值,超过此长度的内容会被截断,并在日志中显示 `... [truncated N bytes]` 提示。建议根据实际日志系统的限制(如单条日志限制为 512KB 的系统)来设置合适的限制值。可通过配置修改 `maxPayloadLength`、`maxRequestBodyLength` 或 `maxResponseBodyLength`。
**切换格式化器:**
```java
// 使用 JSON 格式
HttpRequestLogger.setDefaultFormatter(new JsonHttpLogFormatter());
// 使用美化的 JSON 格式
HttpRequestLogger.setDefaultFormatter(new JsonHttpLogFormatter(true));
// 使用 JSON 格式 + 记录完整事件序列(用于分析调用链路)
HttpRequestLogger.setDefaultFormatter(new JsonHttpLogFormatter()
.setPrettyPrint(true)
.setIncludeEvents(true));
```
**切换输出目标:**
```java
// 输出到控制台
HttpRequestLogger.setDefaultOutput(new ConsoleLogOutput());
// 输出到 SLF4J DEBUG 级别
HttpRequestLogger.setDefaultOutput(new Slf4jLogOutput(Slf4jLogOutput.LogLevel.DEBUG));
// 同时输出到多个目标
HttpRequestLogger.setDefaultOutput(CompositeLogOutput.of(
new Slf4jLogOutput(),
new ConsoleLogOutput()
));
```
**配置请求体/响应体最大长度:**
```java
// 服务端:通过 HttpLoggingFilter 配置
HttpLoggingFilter filter = new HttpLoggingFilter();
filter.setMaxPayloadLength(512 * 1024); // 设置为 512KB
// 格式化器:通过 AbstractHttpLogFormatter 配置
JsonHttpLogFormatter formatter = new JsonHttpLogFormatter();
formatter.setMaxRequestBodyLength(512 * 1024); // 请求体最大长度
formatter.setMaxResponseBodyLength(512 * 1024); // 响应体最大长度
// Spring Boot 自动配置(application.yml)
mc:
http:
logging:
max-payload-length: 512000 # 512KB(单位:字节,-1 表示无限制)
```
## 📚 文档
- [📖 使用指南](docs/guide.md) - 完整的使用教程
- [🔧 高级用法](docs/advanced.md) - 自定义格式化器、输出目标、适配器
- 💡 接入示例 - 在 IDE 中直接运行:
- OkHttp 客户端: `src/test/java/.../demo/OkHttpClientDemo.java`
- Spring Boot 服务端: `src/test/java/.../demo/SpringBootServerDemo.java`
## 🤝 贡献
欢迎提交 Issue 和 Pull Request!
## 📄 许可证
MIT License