# 客户端错误上报接口文档 ## 接口概览 - 路径:`POST /v1/common/log/message/report` - 说明:APP/PC/Web 客户端错误与异常信息上报,服务端入库 `log_message` 表,并提供管理端查询。 - 认证:无需登录;若走设备安全通道需使用 `Login-Type: device` 与 AES 加密。 - 中间件:`DeviceMiddleware`(当请求头 `Login-Type=device` 时启用加解密)。 ## 请求 - Headers: - `Content-Type: application/json` - 可选:`Login-Type: device`(启用设备加密通道) - Body(JSON): - `platform` string 必填,客户端平台,如 `android`/`ios`/`windows`/`mac`/`web` - `appVersion` string 可选,应用版本,如 `2.4.1` - `osName` string 可选,系统名称,如 `Android`/`iOS`/`Windows`/`macOS` - `osVersion` string 可选,系统版本,如 `14` - `deviceId` string 可选,设备唯一标识 - `sessionId` string 可选,会话标识 - `level` uint8 可选,日志等级:`1=fatal`、`2=error`、`3=warn`、`4=info`(默认 `3`) - `errorCode` string 可选,业务或系统错误码 - `message` string 必填,错误简述(服务器将超过约 64KB 的内容截断) - `stack` string 可选,堆栈信息(服务器将超过约 1MB 的内容截断) - `context` object 可选,扩展上下文(如接口路径、参数、网络状态等) - `occurredAt` int64 可选,客户端发生时间,毫秒时间戳 - 服务器侧自动填充: - `client_ip`、`user_agent`、`locale` 由请求解析 - `user_id` 仅在鉴权后由服务端注入(本接口默认匿名) ## 加密通道(设备) - 当使用设备安全通道时(`Login-Type: device`),请求体需要将原始 JSON 加密为: - `data` string:AES 加密后的密文 - `time` string:IV/nonce(与密文配套) - 服务端会自动解密为明文 JSON,再进行字段校验与入库。 ## 响应 - 成功: ``` { "code": 0, "msg": "OK", "data": { "id": 123 } } ``` - 常见错误: - `{"code":401,"msg":"TooManyRequests"}` 触发速率限制(设备ID或IP维度) - `{"code":400,"msg":"InvalidParams"}` 参数校验失败(缺少必填或类型不符) - `{"code":10001,"msg":"DatabaseQueryError"}` 数据库操作异常 ## 速率限制 - 默认按 `deviceId` 或 `client_ip` 每分钟最多约 `120` 条,超限即返回 `TooManyRequests`。 ## 去重策略 - 服务端计算 `digest = sha256(message|stack|errorCode|appVersion|platform)` 并尝试唯一入库,重复日志可能返回已存在记录的 `id`。 ## 示例 - 明文上报(推荐测试使用): ``` curl -X POST http://localhost:8080/v1/common/log/message/report \ -H 'Content-Type: application/json' \ -d '{ "platform": "android", "appVersion": "2.4.1", "osName": "Android", "osVersion": "14", "deviceId": "and-9a7f3e2c-01", "sessionId": "sess-73f8a2a4", "level": 2, "errorCode": "ORDER_RENEWAL_TIMEOUT", "message": "订单续费接口超时:/v1/public/order/renewal", "stack": "TimeoutException: request exceeded 8000ms\\n at HttpClient.post(HttpClient.kt:214)\\n at RenewalRepository.submit(RenewalRepository.kt:87)", "context": { "api": "/v1/public/order/renewal", "method": "POST", "endpoint": "https://api.example.com/v1/public/order/renewal", "httpStatus": 504, "responseTimeMs": 8123, "retryCount": 2, "network": { "type": "cellular", "carrier": "China Mobile" } }, "occurredAt": 1733200005123 }' ``` - 设备加密上报(示意): ``` # 将原始JSON通过AES加密得到密文data与随机IV time curl -X POST http://localhost:8080/v1/common/log/message/report \ -H 'Content-Type: application/json' \ -H 'Login-Type: device' \ -d '{"data":"","time":""}' ``` ## 管理端查询(用于联调验证) - 列表:`GET /v1/admin/log/message/error/list`(需 `Authorization`) - 详情:`GET /v1/admin/log/message/error/detail?id=...` ## 备注 - 字段尽量避免携带敏感信息(密码、密钥、完整令牌等);如需调试请截断或脱敏后上报。 - 建议在 APP/PC 端统一封装上报模块,包含:字段收集、级别过滤、采样策略、离线缓存与重试、速率限制配合。