# 📋 客户端 IP 地址日志指南 ## ✅ 已完成的功能 现在 Flask 应用已经配置为在日志中记录客户端的真实 IP 地址。 ## 🔍 日志格式 ### Flask 应用日志 ``` [2025-10-16 18:58:23] INFO in app: [203.0.113.1] GET /api/health | UA: Mozilla/5.0 (Windows NT 10.0) ^^^^^^^^^^^^ 客户端真实 IP ``` **日志包含:** - 时间戳 - 日志级别 - 客户端 IP 地址 - HTTP 方法和路径 - User-Agent(浏览器信息) ### Gunicorn 访问日志 ``` [16/Oct/2025:18:58:23 +0000] Client: 203.0.113.1 (Remote: 172.17.0.1) GET /api/health Status: 200 Size: 123 bytes Time: 5234 μs UA: "Mozilla/5.0..." ^^^^^^^^^^^^ 真实客户端 IP ``` **日志包含:** - 时间戳 - 客户端真实 IP(从 X-Forwarded-For 获取) - 远程地址(可能是代理服务器) - 请求信息 - 响应状态码和大小 - 处理时间 - User-Agent ## 🎯 IP 获取逻辑 应用会按以下优先级检查 HTTP 头部来获取真实 IP: 1. **X-Forwarded-For** - 最常见的代理头部 2. **X-Real-IP** - Nginx 等使用 3. **CF-Connecting-IP** - Cloudflare 使用 4. **True-Client-IP** - 某些 CDN 使用 5. **X-Client-IP** - 其他代理使用 6. **request.remote_addr** - 直连时的 IP ### 代码实现 ```python def get_client_ip(): """获取客户端真实 IP 地址""" headers_to_check = [ 'X-Forwarded-For', 'X-Real-IP', 'CF-Connecting-IP', 'True-Client-IP', 'X-Client-IP', ] for header in headers_to_check: ip = request.headers.get(header) if ip: # X-Forwarded-For 可能包含多个 IP,取第一个 return ip.split(',')[0].strip() return request.remote_addr or 'Unknown' ``` ## 📁 日志文件位置 ### 本地开发环境 - **控制台输出**: 实时显示 - **文件日志**: `logs/app.log`(自动滚动,保留10个备份) ### Hugging Face Spaces - **控制台输出**: Space 页面的 "Logs" 标签 - **文件日志**: 不持久化(容器重启后丢失) ## 🔍 查看日志 ### 查看实时日志(本地) ```bash # 启动应用(控制台输出) python3.12 app.py # 或使用 Gunicorn gunicorn -c gunicorn_config.py app:app # 实时监控日志文件 tail -f logs/app.log ``` ### 查看历史日志 ```bash # 查看最近 100 条日志 tail -n 100 logs/app.log # 搜索特定 IP 的访问记录 grep "203.0.113.1" logs/app.log # 统计各 IP 的访问次数 grep -oP '\[\K[0-9.]+(?=\])' logs/app.log | sort | uniq -c | sort -rn ``` ### Hugging Face Spaces 1. 进入你的 Space 页面 2. 点击 "Logs" 标签 3. 查看实时日志输出 4. 可以搜索特定 IP 或时间段 ## 📊 日志分析示例 ### 统计最活跃的 IP 地址 ```bash # 提取所有 IP 并统计 grep -oP '\[\K[0-9.]+(?=\])' logs/app.log | sort | uniq -c | sort -rn | head -10 ``` 输出示例: ``` 245 203.0.113.1 156 198.51.100.1 89 192.0.2.1 45 203.0.113.50 ``` ### 查看特定 IP 的访问历史 ```bash grep "\[203.0.113.1\]" logs/app.log ``` 输出示例: ``` [2025-10-16 18:58:23] INFO in app: [203.0.113.1] GET /api/health | UA: Mozilla/5.0 [2025-10-16 18:58:24] INFO in app: [203.0.113.1] GET /api/book/info | UA: Mozilla/5.0 [2025-10-16 18:58:25] INFO in app: [203.0.113.1] POST /api/search | UA: Mozilla/5.0 ``` ### 分析访问时间分布 ```bash # 按小时统计访问量 grep -oP '\[.*?\s+\K\d{2}' logs/app.log | sort | uniq -c ``` ### 统计不同浏览器的使用情况 ```bash grep "UA:" logs/app.log | grep -oP 'UA: \K[^/]+' | sort | uniq -c | sort -rn ``` ## 🧪 测试 IP 记录 ### 运行测试脚本 ```bash # 确保应用正在运行 python3.12 app.py # 在另一个终端运行测试 python3.12 test_ip_logging.py ``` ### 手动测试 ```bash # 普通请求 curl http://localhost:7860/api/health # 模拟代理请求(带 X-Forwarded-For) curl -H "X-Forwarded-For: 203.0.113.1" http://localhost:7860/api/health # 查看日志中记录的 IP tail logs/app.log ``` ## 🔒 隐私和安全 ### IP 地址处理 - IP 地址仅用于日志记录和调试 - 不会永久存储在数据库中 - 日志文件会自动滚动(最多保留10个备份) ### 隐私保护建议 如果需要遵守 GDPR 等隐私法规: 1. **匿名化 IP**: 可以只记录 IP 的前缀 ```python # 例如:203.0.113.1 -> 203.0.113.0 ip_parts = ip.split('.') anonymized_ip = '.'.join(ip_parts[:3]) + '.0' ``` 2. **定期清理日志**: 设置日志保留期限 ```python # 在 gunicorn_config.py 中 max_log_age_days = 30 # 保留30天 ``` 3. **限制日志访问**: 确保只有授权人员可以访问日志 ## 📈 日志性能影响 ### 性能考虑 - IP 获取:几乎无性能影响(只是读取 HTTP 头部) - 日志写入:异步处理,不影响请求响应时间 - 文件大小:每个日志文件最大 10MB,自动滚动 ### 优化建议 如果日志量很大: 1. **减少日志级别**(只记录重要信息) ```python app.logger.setLevel(logging.WARNING) # 只记录警告和错误 ``` 2. **只记录 API 请求**(跳过静态资源) ```python # 已在 before_request 中实现 if request.path.startswith('/api/'): app.logger.info(...) ``` 3. **使用日志聚合服务**(如 ELK、Datadog) ## 🛠️ 自定义日志格式 ### 修改 Flask 日志格式 编辑 `app.py` 中的 `setup_logging()` 函数: ```python file_handler.setFormatter(logging.Formatter( '[%(asctime)s] [%(levelname)s] [IP:%(client_ip)s] %(message)s' )) ``` ### 修改 Gunicorn 日志格式 编辑 `gunicorn_config.py` 中的 `access_log_format`: ```python access_log_format = ( '%(h)s - %({X-Forwarded-For}i)s ' '[%(t)s] "%(r)s" %(s)s %(b)s ' '"%(f)s" "%(a)s"' ) ``` ## 📚 相关文档 - [Flask 日志文档](https://flask.palletsprojects.com/en/latest/logging/) - [Gunicorn 配置文档](https://docs.gunicorn.org/en/stable/settings.html) - [HTTP 头部参考](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) ## 🎉 总结 现在您的 Flask 应用已经可以: ✅ 记录客户端真实 IP 地址 ✅ 支持多种代理环境(Hugging Face Spaces、Cloudflare 等) ✅ 提供详细的访问日志 ✅ 支持日志分析和统计 查看日志的快速命令: ```bash # 实时监控 tail -f logs/app.log # 搜索特定 IP grep "203.0.113.1" logs/app.log # 统计访问量 grep -c "GET /api/" logs/app.log ``` --- **最后更新**: 2025-10-16 **相关文件**: `app.py`, `gunicorn_config.py`, `test_ip_logging.py`