# JSON格式日志输出示例 ## 优化后的 `log_callback_request` 方法 - JSON格式日志 ### 1. site_id 日志输出 ```json 📝 site_id: "test-site-123" ``` ### 2. 请求头日志输出(JSON格式) ```json 📋 请求头: { "content-type": "application/json", "authorization": "***REDACTED***", "x-api-key": "***REDACTED***", "user-agent": "python-httpx/0.25.2", "accept": "application/json", "content-length": "1024", "host": "localhost:8000" } ``` ### 3. 请求体日志输出(JSON格式) ```json 📄 请求体: { "count": 2, "data": [ { "bill": 100, "duration": 60, "callid": "test-call-123", "calldate": "2024-01-01 12:00:00", "number": "13800138000", "numberid": "number-123", "customer_id": "customer-123", "status": 0, "status_str": "失败", "user_id": "user-123", "type": 1, "number_data": { "number": "13800138000", "province": "广东", "city": "深圳", "operator": "移动" }, "group": { "id": 1, "name": "测试组" }, "task": { "id": "task-123", "name": "测试任务" }, "user": { "id": "user-123", "name": "测试用户" }, "customer_data": { "name": "测试客户", "email": "test@example.com", "company": "测试公司", "extra": "额外信息" } } ] } ``` ### 4. server_ip 日志输出(JSON格式) ```json 🏠 server_ip: { "ip": "0.0.0.0", "port": 8000 } ``` ### 5. client_ip 日志输出(JSON格式) ```json 🖥️ client_ip: { "ip": "127.0.0.1", "port": 52345 } ``` ### 6. callback_data 日志输出(JSON格式) ```json 📦 callback_data: { "count": 2, "data_count": 1, "data_sample": { "bill": 100, "duration": 60, "callid": "test-call-123", "calldate": "2024-01-01 12:00:00", "number": "13800138000", "numberid": "number-123", "customer_id": "customer-123", "status": 0, "status_str": "失败", "user_id": "user-123", "type": 1, "number_data": { "number": "13800138000", "province": "广东", "city": "深圳", "operator": "移动" }, "group": { "id": 1, "name": "测试组" }, "task": { "id": "task-123", "name": "测试任务" }, "user": { "id": "user-123", "name": "测试用户" }, "customer_data": { "name": "测试客户", "email": "test@example.com", "company": "测试公司", "extra": "额外信息" } } } ``` ## 完整的请求处理日志流程 ### 单次请求的完整日志输出 ``` 2024-12-02 16:30:15 - routes - INFO - 🔥 收到AI Talk回调请求: siteId=test-site-123, count=2, data_count=1 2024-12-02 16:30:15 - routes - INFO - 📝 site_id: "test-site-123" 2024-12-02 16:30:15 - routes - INFO - 📋 请求头: { "content-type": "application/json", "authorization": "***REDACTED***", "user-agent": "python-httpx/0.25.2", "accept": "application/json", "content-length": "1024", "host": "localhost:8000" } 2024-12-02 16:30:15 - routes - INFO - 📄 请求体: { "count": 2, "data": [ { "bill": 100, "duration": 60, "callid": "test-call-123", "calldate": "2024-01-01 12:00:00", "number": "13800138000", "numberid": "number-123", "customer_id": "customer-123", "status": 0, "status_str": "失败", "user_id": "user-123", "type": 1, "number_data": { "number": "13800138000", "province": "广东", "city": "深圳", "operator": "移动" }, "group": { "id": 1, "name": "测试组" }, "task": { "id": "task-123", "name": "测试任务" }, "user": { "id": "user-123", "name": "测试用户" }, "customer_data": { "name": "测试客户", "email": "test@example.com", "company": "测试公司", "extra": "额外信息" } } ] } 2024-12-02 16:30:15 - routes - INFO - 🏠 server_ip: { "ip": "0.0.0.0", "port": 8000 } 2024-12-02 16:30:15 - routes - INFO - 🖥️ client_ip: { "ip": "127.0.0.1", "port": 52345 } 2024-12-02 16:30:15 - routes - INFO - 📦 callback_data: { "count": 2, "data_count": 1, "data_sample": { "bill": 100, "duration": 60, "callid": "test-call-123", "calldate": "2024-01-01 12:00:00", "number": "13800138000", "numberid": "number-123", "customer_id": "customer-123", "status": 0, "status_str": "失败", "user_id": "user-123", "type": 1, "number_data": { "number": "13800138000", "province": "广东", "city": "深圳", "operator": "移动" }, "group": { "id": 1, "name": "测试组" }, "task": { "id": "task-123", "name": "测试任务" }, "user": { "id": "user-123", "name": "测试用户" }, "customer_data": { "name": "测试客户", "email": "test@example.com", "company": "测试公司", "extra": "额外信息" } } } 2024-12-02 16:30:15 - routes - INFO - ✅ 回调请求记录成功保存到数据库,ID: 123 2024-12-02 16:30:15 - routes - INFO - 📞 count=2 < 3,调用外部API 2024-12-02 16:30:15 - routes - DEBUG - 🔒 获取Redis锁成功: external_api_call_test-site-123_2 ``` ## JSON格式日志的优势 ### 1. 结构化数据 - 每个字段都以标准JSON格式输出 - 便于程序解析和处理 - 支持复杂的嵌套数据结构 ### 2. 可读性强 - JSON格式具有良好的层次结构 - 缩进格式便于人工阅读 - 支持中文字符(`ensure_ascii=False`) ### 3. 便于分析 - 可以直接使用JSON工具解析 - 支持日志分析工具(如ELK、Fluentd等) - 便于数据提取和统计 ### 4. 安全性 - 敏感信息自动过滤为 `***REDACTED***` - 保持数据结构完整性 - 避免敏感信息泄露 ## 日志分析示例 ### 使用jq工具分析JSON日志 ```bash # 提取所有site_id grep "📝 site_id:" logs/app.log | jq -r '.📝 site_id' # 提取所有client_ip信息 grep "🖥️ client_ip:" logs/app.log | jq -r '.🖥️ client_ip.ip' # 统计不同count值的请求 grep "📦 callback_data:" logs/app.log | jq -r '.📦 callback_data.count' | sort | uniq -c # 提取包含特定号码的请求 grep "📄 请求体:" logs/app.log | jq 'select(.📄 请求_body.data[].number == "13800138000")' ``` ### 使用Python分析JSON日志 ```python import json import re # 解析日志中的JSON数据 def parse_json_logs(log_file): site_ids = [] client_ips = [] with open(log_file, 'r', encoding='utf-8') as f: for line in f: if '📝 site_id:' in line: # 提取JSON部分 json_str = line.split('📝 site_id: ')[1].strip() site_id = json.loads(json_str) site_ids.append(site_id) elif '🖥️ client_ip:' in line: json_str = line.split('🖥️ client_ip: ')[1].strip() client_info = json.loads(json_str) client_ips.append(client_info['ip']) return site_ids, client_ips ``` ## 性能考虑 ### 1. JSON序列化开销 - 使用标准库`json.dumps()` - `ensure_ascii=False` 支持中文但略慢 - 对于高频调用,可考虑关闭详细日志 ### 2. 日志文件大小 - JSON格式比纯文本占用更多空间 - 建议合理设置日志轮转大小 - 生产环境可考虑使用压缩存储 ### 3. 内存使用 - 大型请求体会占用较多内存 - `callback_data` 只记录摘要信息,避免完整数据 ## 配置建议 ### 开发环境 ```bash LOG_LEVEL=INFO # 显示所有JSON日志 ``` ### 生产环境 ```bash LOG_LEVEL=WARNING # 只显示重要信息,减少JSON日志量 ``` ### 调试特定问题 ```bash # 临时开启详细日志 LOG_LEVEL=DEBUG # 问题解决后恢复 LOG_LEVEL=INFO ``` 现在 `log_callback_request` 方法以JSON格式输出所有关键信息,便于日志分析和系统监控!