From dc240f39f05fbe68cbaa7d15fa7742ffc1ba4744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roog=20=28=E9=A1=BE=E6=96=B0=E5=9F=B9=29?= Date: Mon, 2 Feb 2026 19:24:38 +0800 Subject: [PATCH] =?UTF-8?q?main:=E6=96=B0=E5=A2=9E=20CLAUDE.md=20=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E8=84=9A=E6=9C=AC=E5=8F=8A=E6=97=A5=E5=BF=97=E6=94=B6?= =?UTF-8?q?=E9=9B=86=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 变更内容: - 编写 `verify_claude_md.sh` 脚本,用于验证 CLAUDE.md 文档完整性及相关配置文件。 - 增加 Loki 日志收集系统的详细文档说明,包括架构、收集模式及查询方法。 - 更新 CLAUDE.md,完善日志追踪功能及 Loki 集成相关细节。 - 提升项目文档的完备度,方便日志分析与运维操作。 --- CLAUDE.md | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 236 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 27ca491..abd1984 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -65,9 +65,10 @@ src/functional_scaffold/ 3. **配置管理**:使用 `pydantic-settings` 从环境变量或 `.env` 文件加载配置,支持类型验证。 4. **可观测性**: - - 日志:结构化 JSON 日志(pythonjsonlogger) + - 日志:结构化 JSON 日志(pythonjsonlogger),自动包含 request_id - 指标:Prometheus 格式(request_counter, request_latency, algorithm_counter) - 追踪:request_id 关联所有日志和指标 + - 日志收集:Loki + Promtail 自动收集和查询日志 ## 开发命令 @@ -150,11 +151,12 @@ docker build -f deployment/Dockerfile -t functional-scaffold:latest . # 运行容器 docker run -p 8000:8000 functional-scaffold:latest -# 使用 docker-compose(包含 Prometheus + Grafana) +# 使用 docker-compose(包含 Prometheus + Grafana + Loki) cd deployment docker-compose up # Grafana: http://localhost:3000 (admin/admin) # Prometheus: http://localhost:9090 +# Loki: http://localhost:3100 ``` ### 文档 @@ -273,10 +275,52 @@ from functional_scaffold.core.logging import setup_logging # 设置日志 logger = setup_logging(level="INFO", format_type="json") -# 记录日志 +# 记录日志(自动包含 request_id) logger.info("处理请求", extra={"user_id": "123"}) ``` +**日志特性:** +- 结构化 JSON 格式 +- 自动包含 request_id(从 ContextVar 中提取) +- 支持文件日志(可选,通过环境变量启用) +- 日志轮转(100MB,保留 5 个备份) + +### 日志收集(Loki) + +项目集成了 Grafana Loki 日志收集系统,支持两种收集模式: + +**模式 1: Docker stdio 收集(默认,推荐)** +- 自动收集容器标准输出/错误 +- 无需修改应用代码 +- 性能影响极小 + +**模式 2: 文件收集(备用)** +- 日志持久化到文件 +- 支持日志轮转 +- 需要设置 `LOG_FILE_ENABLED=true` + +**查询日志:** + +```bash +# 使用 Loki API +curl -G -s "http://localhost:3100/loki/api/v1/query_range" \ + --data-urlencode 'query={job="functional-scaffold-app"}' + +# 按 request_id 过滤 +curl -G -s "http://localhost:3100/loki/api/v1/query_range" \ + --data-urlencode 'query={job="functional-scaffold-app"} |= "request-id-here"' +``` + +**Grafana 仪表板:** +- 访问 http://localhost:3000 +- 进入 "日志监控" 仪表板 +- 使用 Request ID 输入框过滤特定请求的日志 + +**相关文档:** +- 完整文档:`docs/loki-integration.md` +- 使用说明:`docs/grafana-dashboard-usage.md` +- 快速参考:`docs/loki-quick-reference.md` + ### 指标 使用 `core/metrics.py` 的装饰器: @@ -298,7 +342,7 @@ def my_function(): ### 追踪 -Request ID 自动注入到所有请求: +Request ID 自动注入到所有请求和日志: ```python from functional_scaffold.core.tracing import get_request_id @@ -307,6 +351,13 @@ from functional_scaffold.core.tracing import get_request_id request_id = get_request_id() ``` +**Request ID 特性:** +- 自动生成或从请求头 `X-Request-ID` 获取 +- 通过 ContextVar 在异步上下文中传递 +- 自动添加到所有日志记录中 +- 可用于追踪单个请求的完整生命周期 +- 在 Grafana 仪表板中可按 request_id 过滤日志 + ## 部署 ### Kubernetes @@ -355,7 +406,8 @@ sam deploy --template-file deployment/serverless/aws-lambda.yaml - ✅ 参数校验(Pydantic + utils/validators.py) - ✅ 错误包装和标准化(core/errors.py) - ✅ 埋点(core/metrics.py - 延迟、失败率) -- ✅ 分布式追踪的关联 ID(core/tracing.py) +- ✅ 分布式追踪的关联 ID(core/tracing.py + RequestIdFilter) +- ✅ 日志收集和查询(Loki + Promtail) - ⏳ Worker 运行时(重试、超时、DLQ - 待实现) ### 3. 脚手架生成器 @@ -365,8 +417,9 @@ sam deploy --template-file deployment/serverless/aws-lambda.yaml - ✅ Dockerfile(deployment/Dockerfile) - ✅ CI/CD 流水线配置(.github/workflows/) - ✅ Serverless 平台部署 YAML(deployment/serverless/) -- ✅ Grafana 仪表板模板(monitoring/grafana/dashboard.json) +- ✅ Grafana 仪表板模板(monitoring/grafana/dashboards/) - ✅ 告警规则配置(monitoring/alerts/rules.yaml) +- ✅ Loki 日志收集配置(monitoring/loki.yaml, monitoring/promtail.yaml) ## 开发理念 @@ -397,3 +450,180 @@ sam deploy --template-file deployment/serverless/aws-lambda.yaml 4. **Docker 构建**:Dockerfile 使用非 root 用户(appuser),包含健康检查。 5. **配置优先级**:环境变量 > .env 文件 > 默认值。 + +6. **Promtail 版本**:使用 Promtail 3.0.0 或更高版本,以支持较新的 Docker API(1.44+)。如果遇到 "client version too old" 错误,需要升级 Promtail 版本。 + +## 日志收集系统(Loki) + +项目集成了 Grafana Loki 日志收集系统,提供强大的日志查询和分析能力。 + +### 架构 + +``` +应用容器 (stdout/stderr) + ↓ +Docker Engine + ↓ +Promtail (日志采集器) + ↓ +Loki (日志存储) + ↓ +Grafana (可视化) +``` + +### 服务组件 + +**docker-compose 包含以下服务:** +- **app**: 应用服务(端口 8111) +- **loki**: 日志存储服务(端口 3100) +- **promtail**: 日志采集服务(端口 9080) +- **grafana**: 可视化服务(端口 3000) +- **prometheus**: 指标收集服务(端口 9090) +- **redis**: 缓存服务(端口 6380) + +### 日志收集模式 + +#### 模式 1: Docker stdio 收集(默认) + +**特点:** +- ✅ 无需修改应用代码 +- ✅ 自动收集容器标准输出/错误 +- ✅ 性能影响极小 +- ✅ 推荐用于生产环境 + +**配置:** +应用容器需要添加标签(已配置): +```yaml +labels: + logging: "promtail" + logging_jobname: "functional-scaffold-app" +``` + +#### 模式 2: 文件收集(备用) + +**特点:** +- ✅ 日志持久化到文件 +- ✅ 支持日志轮转(100MB,5个备份) +- ✅ 适合需要本地日志文件的场景 + +**启用方式:** +```yaml +# docker-compose.yml +environment: + - LOG_FILE_ENABLED=true + - LOG_FILE_PATH=/var/log/app/app.log +``` + +### 日志格式 + +所有日志使用 JSON 格式,自动包含以下字段: +- `asctime`: 时间戳 +- `name`: 日志器名称 +- `levelname`: 日志级别(INFO, WARNING, ERROR) +- `message`: 日志消息 +- `request_id`: 请求 ID(自动添加) +- `timestamp`: ISO 格式时间戳 + +### 查询日志 + +#### 使用 Loki API + +```bash +# 查询所有日志 +curl -G -s "http://localhost:3100/loki/api/v1/query_range" \ + --data-urlencode 'query={job="functional-scaffold-app"}' + +# 按 request_id 过滤 +curl -G -s "http://localhost:3100/loki/api/v1/query_range" \ + --data-urlencode 'query={job="functional-scaffold-app"} |= "request-id-here"' + +# 查询错误日志 +curl -G -s "http://localhost:3100/loki/api/v1/query_range" \ + --data-urlencode 'query={job="functional-scaffold-app", level="ERROR"}' +``` + +#### 使用 Grafana 仪表板 + +1. 访问 http://localhost:3000(admin/admin) +2. 进入 "日志监控" 仪表板 +3. 使用 Request ID 输入框过滤特定请求的日志 + +**仪表板面板:** +- **日志流(实时)**: 实时日志流 +- **日志量趋势**: 按时间和级别统计 +- **日志级别分布**: INFO/WARNING/ERROR 分布 +- **错误日志**: 只显示 ERROR 级别 + +#### 使用 Grafana Explore + +1. 访问 http://localhost:3000/explore +2. 选择 Loki 数据源 +3. 使用 LogQL 查询语言 + +**常用查询:** +```logql +# 查询所有日志 +{job="functional-scaffold-app"} + +# 查询错误日志 +{job="functional-scaffold-app", level="ERROR"} + +# 按 request_id 过滤 +{job="functional-scaffold-app"} |= "request-id-here" + +# 使用 JSON 解析 +{job="functional-scaffold-app"} | json | request_id="request-id-here" + +# 统计日志量 +sum by (level) (count_over_time({job="functional-scaffold-app"}[5m])) +``` + +### 验证和测试 + +```bash +# 验证 Loki 集成 +./scripts/verify_loki.sh + +# 测试 Request ID 过滤 +./scripts/test_request_id_filter.sh +``` + +### 配置文件 + +- **Loki 配置**: `monitoring/loki.yaml` + - 日志保留期: 7 天 + - 摄入速率限制: 10MB/s + - 自动压缩和清理 + +- **Promtail 配置**: `monitoring/promtail.yaml` + - Docker stdio 收集配置 + - 文件收集配置 + - JSON 日志解析规则 + +- **Grafana Provisioning**: `monitoring/grafana/` + - 数据源自动配置(datasources/) + - 仪表板自动加载(dashboards/) + +### 故障排查 + +**看不到日志:** +1. 检查服务状态: `docker-compose ps` +2. 查看 Promtail 日志: `docker-compose logs promtail` +3. 验证容器标签: `docker inspect | grep Labels` + +**Docker socket 权限问题:** +```bash +sudo chmod 666 /var/run/docker.sock +``` + +**日志延迟:** +- Promtail 每 5 秒刷新一次 +- 建议等待 5-10 秒后再查询 + +### 相关文档 + +- **完整文档**: `docs/loki-integration.md` - 包含查询示例、故障排查、性能优化 +- **快速参考**: `docs/loki-quick-reference.md` - 常用命令和 LogQL 查询 +- **仪表板使用**: `docs/grafana-dashboard-usage.md` - Grafana 仪表板使用说明 +- **实施总结**: `docs/loki-implementation-summary.md` - 架构和实施细节 +- **监控目录**: `monitoring/README.md` - 配置文件说明