main:新增 CLAUDE.md 验证脚本及日志收集文档
变更内容: - 编写 `verify_claude_md.sh` 脚本,用于验证 CLAUDE.md 文档完整性及相关配置文件。 - 增加 Loki 日志收集系统的详细文档说明,包括架构、收集模式及查询方法。 - 更新 CLAUDE.md,完善日志追踪功能及 Loki 集成相关细节。 - 提升项目文档的完备度,方便日志分析与运维操作。
This commit is contained in:
242
CLAUDE.md
242
CLAUDE.md
@@ -65,9 +65,10 @@ src/functional_scaffold/
|
|||||||
3. **配置管理**:使用 `pydantic-settings` 从环境变量或 `.env` 文件加载配置,支持类型验证。
|
3. **配置管理**:使用 `pydantic-settings` 从环境变量或 `.env` 文件加载配置,支持类型验证。
|
||||||
|
|
||||||
4. **可观测性**:
|
4. **可观测性**:
|
||||||
- 日志:结构化 JSON 日志(pythonjsonlogger)
|
- 日志:结构化 JSON 日志(pythonjsonlogger),自动包含 request_id
|
||||||
- 指标:Prometheus 格式(request_counter, request_latency, algorithm_counter)
|
- 指标:Prometheus 格式(request_counter, request_latency, algorithm_counter)
|
||||||
- 追踪:request_id 关联所有日志和指标
|
- 追踪: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 run -p 8000:8000 functional-scaffold:latest
|
||||||
|
|
||||||
# 使用 docker-compose(包含 Prometheus + Grafana)
|
# 使用 docker-compose(包含 Prometheus + Grafana + Loki)
|
||||||
cd deployment
|
cd deployment
|
||||||
docker-compose up
|
docker-compose up
|
||||||
# Grafana: http://localhost:3000 (admin/admin)
|
# Grafana: http://localhost:3000 (admin/admin)
|
||||||
# Prometheus: http://localhost:9090
|
# 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")
|
logger = setup_logging(level="INFO", format_type="json")
|
||||||
|
|
||||||
# 记录日志
|
# 记录日志(自动包含 request_id)
|
||||||
logger.info("处理请求", extra={"user_id": "123"})
|
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` 的装饰器:
|
使用 `core/metrics.py` 的装饰器:
|
||||||
@@ -298,7 +342,7 @@ def my_function():
|
|||||||
|
|
||||||
### 追踪
|
### 追踪
|
||||||
|
|
||||||
Request ID 自动注入到所有请求:
|
Request ID 自动注入到所有请求和日志:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from functional_scaffold.core.tracing import get_request_id
|
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 = get_request_id()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Request ID 特性:**
|
||||||
|
- 自动生成或从请求头 `X-Request-ID` 获取
|
||||||
|
- 通过 ContextVar 在异步上下文中传递
|
||||||
|
- 自动添加到所有日志记录中
|
||||||
|
- 可用于追踪单个请求的完整生命周期
|
||||||
|
- 在 Grafana 仪表板中可按 request_id 过滤日志
|
||||||
|
|
||||||
## 部署
|
## 部署
|
||||||
|
|
||||||
### Kubernetes
|
### Kubernetes
|
||||||
@@ -355,7 +406,8 @@ sam deploy --template-file deployment/serverless/aws-lambda.yaml
|
|||||||
- ✅ 参数校验(Pydantic + utils/validators.py)
|
- ✅ 参数校验(Pydantic + utils/validators.py)
|
||||||
- ✅ 错误包装和标准化(core/errors.py)
|
- ✅ 错误包装和标准化(core/errors.py)
|
||||||
- ✅ 埋点(core/metrics.py - 延迟、失败率)
|
- ✅ 埋点(core/metrics.py - 延迟、失败率)
|
||||||
- ✅ 分布式追踪的关联 ID(core/tracing.py)
|
- ✅ 分布式追踪的关联 ID(core/tracing.py + RequestIdFilter)
|
||||||
|
- ✅ 日志收集和查询(Loki + Promtail)
|
||||||
- ⏳ Worker 运行时(重试、超时、DLQ - 待实现)
|
- ⏳ Worker 运行时(重试、超时、DLQ - 待实现)
|
||||||
|
|
||||||
### 3. 脚手架生成器
|
### 3. 脚手架生成器
|
||||||
@@ -365,8 +417,9 @@ sam deploy --template-file deployment/serverless/aws-lambda.yaml
|
|||||||
- ✅ Dockerfile(deployment/Dockerfile)
|
- ✅ Dockerfile(deployment/Dockerfile)
|
||||||
- ✅ CI/CD 流水线配置(.github/workflows/)
|
- ✅ CI/CD 流水线配置(.github/workflows/)
|
||||||
- ✅ Serverless 平台部署 YAML(deployment/serverless/)
|
- ✅ Serverless 平台部署 YAML(deployment/serverless/)
|
||||||
- ✅ Grafana 仪表板模板(monitoring/grafana/dashboard.json)
|
- ✅ Grafana 仪表板模板(monitoring/grafana/dashboards/)
|
||||||
- ✅ 告警规则配置(monitoring/alerts/rules.yaml)
|
- ✅ 告警规则配置(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),包含健康检查。
|
4. **Docker 构建**:Dockerfile 使用非 root 用户(appuser),包含健康检查。
|
||||||
|
|
||||||
5. **配置优先级**:环境变量 > .env 文件 > 默认值。
|
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 <container> | 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` - 配置文件说明
|
||||||
|
|||||||
Reference in New Issue
Block a user