# http-trace-demo **Repository Path**: git4chen/http-trace-demo ## Basic Information - **Project Name**: http-trace-demo - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-09 - **Last Updated**: 2026-08-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # HTTP 链路追踪示例工程 基于 **JDK11 + Spring Boot 2.7 + SLF4J MDC** 的 HTTP 链路追踪前后端示例项目。演示 traceId 如何经 MDC 贯穿同步与异步线程,并以后端 **JSON 结构化日志**输出,满足 ELK 等日志平台的后期分析需求。 ## 功能特性 - **链路追踪(W3C traceparent 标准)**:前端生成/持久化 traceId(localStorage)并携带 `traceparent` 请求头,后端透传 trace-id、兜底生成、非法重生成,响应头回写 `traceparent`;兼容读取旧版 `X-Trace-Id` - **父子 span 结构**:入口请求为根 span(spanId 16 位 hex,W3C 标准),异步子任务自动生成子 span(spanId + parentSpanId),日志可还原调用树 - **异步链路贯穿**:`TaskDecorator` 在任务提交时复制 MDC、执行后清理,`@Async` 子线程日志延续同一链路,杜绝线程复用串号 - **结构化日志**:`logstash-logback-encoder` 每行一个 JSON 对象,字段可直接被日志平台解析索引 - **Access 日志分离**:独立 `ACCESS_LOG` 通道记录每个请求的 method/uri/status/duration_ms/clientIp - **慢请求告警**:耗时超过阈值(默认 1000ms)输出 `SLOW_REQUEST` WARN 日志 - **前端实时日志回显**:SSE 推送后端日志到页面(快照 + 增量),WARN/ERROR 高亮,单屏布局 - **单屏演示页**:当前链路管理 + 请求按钮 + 请求结果 + 实时日志,全部一屏展示、面板内独立滚动 ## 技术栈 | 领域 | 选型 | |---|---| | JDK | 11 | | 框架 | Spring Boot 2.7.x | | 构建 | Maven | | 日志 | logstash-logback-encoder(JSON 结构化) | | 异步 | ThreadPoolTaskExecutor + TaskDecorator | | 前端 | 原生 HTML + JS(零构建依赖) | ## 快速开始 ```bash # 1. 构建并运行测试 mvn test # 2. 启动服务 mvn spring-boot:run # 3. 打开演示页 # http://localhost:8080/ ``` ## 链路追踪设计 ### 传播规则 ``` 前端(localStorage 持久化 traceId,每次请求新生成 spanId) │ 请求头: traceparent: 00---01 ▼ TraceFilter(OncePerRequestFilter) 1. 解析 traceparent:透传 trace-id、以上游 span-id 为父 span └─ 无/非法 → 兼容 X-Trace-Id → 兜底生成 traceId 2. 生成本服务根 spanId(16 位 hex),注入 MDC 3. 执行业务(业务日志自动携带追踪字段) 4. 写 ACCESS_LOG(method/uri/status/duration_ms/clientIp) 5. 慢请求(>1000ms) → SLOW_REQUEST WARN 6. finally 清理 MDC;响应头回写 traceparent ▼ 前端(展示响应 traceparent + 耗时) ``` ### 异步链路 `@Async` 任务通过统一 `ThreadPoolTaskExecutor` bean(`traceExecutor`)执行,`TraceTaskDecorator` 在提交时快照 MDC、执行时恢复、`finally` 清理;子任务内调用 `enterChildSpan()` 生成子 span(新 spanId + parentSpanId 指向父)。由此子线程日志与主线程共享同一 traceId,且能还原父子层级。 ## 日志结构(核心交付物) ### 业务日志(`logs/app.log`,单行 JSON) ```json {"@timestamp":"2026-08-09T11:18:03.826+08:00","level":"INFO", "logger_name":"com.example.trace.web.TraceController","thread_name":"trace-async-1", "traceId":"abcd...","spanId":"30ba...","parentSpanId":"fc80...", "serviceName":"http-trace-demo","message":"async-work-start"} ``` ### Access 日志(`logs/app-access.log`) ```json {"message":"GET /api/sync status=200 duration_ms=6 clientIp=127.0.0.1", "traceId":"feed...","spanId":"db8d...","parentSpanId":"","serviceName":"http-trace-demo"} ``` ### 滚动策略 - 按天 + 单文件 ≤50MB 滚动,保留 7 天 - `logs/app.log`(业务)、`logs/app-access.log`(Access) - 控制台输出人类可读文本,仅本地排障用 ### 日志分析提示 - **按 traceId 排障**:`grep logs/app.log`,一次请求的全部日志(含异步子线程)归属同一链路 - **按接口统计性能**:查询 `ACCESS_LOG` 的 `duration_ms`/`status` 聚合 - **慢请求告警**:过滤 `message=SLOW_REQUEST` - **还原调用树**:由 `spanId` + `parentSpanId` 组装父子层级 ## 接口说明 | 接口 | 说明 | |---|---| | `GET /api/sync` | 同步业务,输出业务日志 | | `GET /api/async` | 触发 `@Async` 子任务(子 span),立即返回 | | `GET /api/biz-error` | 业务异常:WARN 无堆栈,400 业务码 | | `GET /api/error` | 系统异常(NPE):ERROR 带堆栈,500 统一结构 | | `GET /api/logs/recent?limit=N` | 实时日志历史快照(JSON) | | `GET /api/logs/stream` | 实时日志 SSE 流(先推快照,后推增量) | ## 测试 `mvn test` 运行 10 个 MockMvc 集成测试,覆盖: - `traceparent` 三种决策:缺失生成 / 合法透传(响应回写新 span) / 非法重生成 - 旧版 `X-Trace-Id` 兼容透传 - 系统异常返回 500 且 ERROR 日志携带 traceId - 业务异常返回 400 且 WARN 无堆栈 - 异步接口日志包含子 span(spanId 16 位 hex,parentSpanId 指向根 span) - Access 日志记录每个请求 - 实时日志快照接口返回链路日志 ## 工程结构 ``` com.example.trace ├── TraceApplication.java ├── filter/TraceFilter.java # 链路入口:traceId 决策/根 span/Access 日志/回写 ├── async/ │ ├── AsyncConfig.java # ThreadPoolTaskExecutor(traceExecutor) │ ├── TraceTaskDecorator.java # MDC 复制/恢复/清理 │ └── AsyncTraceService.java # @Async 子任务(子 span) ├── web/TraceController.java # 演示接口 ├── exception/ # BizException + 全局异常处理 ├── live/ # 实时日志通道(appender/buffer/SSE) └── util/TraceContext.java # ID 生成/校验/MDC 键 ``` ## 文档索引 - `CONTEXT.md` — 领域词汇表 - `docs/DESIGN.md` — 设计概览 - `docs/adr/0001-0004` — 架构决策记录(结构化日志 / traceId+spanId / Access 分离 / TaskDecorator) - `docs/specs/0001-http-trace-demo.md` — 实现规范