网络请求本地日志设计

1. 目标与状态

2. Compact Use Case

3. 参考实现与当前基础

CusumptionMachine 在 RequetInterceptor 中组装请求 URL、POST 参数、响应和耗时,然后调用:

LocalFileRecorder.writeLog(
        ResourcesUtils.getStringRes(R.string.local_recorder_net_work_title),
        builder.toString());

其日志文件名前缀为 网络请求_。

AIDishRecognition 已具备以下基础:

  1. CptApplication 已为全局 OkHttp 客户端注册 RequetInterceptor。
  2. RequetInterceptor 已记录 URL、Form 参数、Multipart 参数、响应体和耗时。
  3. LocalFileRecorder 已使用单线程执行器异步写入 应用外部文件目录/Log/;外部目录不可用时回退到内部文件目录。
  4. 扫码支付专用客户端由全局客户端 newBuilder() 创建,会继承相同拦截器。

因此无需新建日志组件,也无需修改网络客户端,只需把拦截器现有记录接入本地写入工具。

4. 设计方案

4.1 文件位置与命名

继续使用当前项目 LocalFileRecorder 的目录规则:

<应用外部文件目录>/Log/网络请求_<日期>.txt

外部文件目录不可用时,保持现有逻辑回退到应用内部文件目录。新增字符串资源:

<string name="local_recorder_net_work_title">网络请求_</string>

文件名前缀通过资源读取,不在拦截器内散落硬编码。

4.2 成功请求

沿用当前日志内容与 peekBody 方式:

请求url: ...
请求方式: POST
请求参数: ...
请求结果: ...
本次请求耗时: ...毫秒

响应读取完成后调用 LocalFileRecorder.writeLog()。文件写入继续在后台单线程执行,不阻塞网络线程。

4.3 网络异常

用 try/catch 包裹 chain.proceed(request) 及响应日志组装。捕获 IOException 后追加:

请求失败: <异常类型>: <异常消息>
本次请求耗时: ...毫秒

写入本地日志后重新抛出同一个异常。该设计只增强可观测性,不改变现有错误类型、回调和界面提示。

4.4 数据边界

5. 影响范围

计划修改业务仓库:

明确不修改:

6. 验收与验证

6.1 自动验证

./gradlew :app:testDebugUnitTest
./gradlew :app:assembleDebug
git diff --check

6.2 人工验收

  1. 在真机发起一个成功的 HTTP 请求。
  2. 检查当前项目日志目录生成 网络请求_<日期>.txt。
  3. 确认日志包含 URL、已有参数、响应和耗时。
  4. 模拟断网、连接失败或超时,再次检查同一日志文件。
  5. 确认失败记录包含异常类型、异常消息和耗时,应用仍走原有失败回调。

7. 追踪矩阵

UC / 步骤实现验收标准验证
UC-OBS-001/M1 成功请求落盘RequetInterceptor + 网络日志文件名资源当天文件包含成功请求完整记录单测、构建、真机日志检查
UC-OBS-001/E1 网络异常落盘RequetInterceptor 异常分支当天文件包含异常类型、消息与耗时单测、构建、断网或超时检查
UC-OBS-001/BR-001 不改变网络行为原响应返回、原异常重抛业务成功/失败回调保持不变现有测试、代码审查

8. 实施边界

本文档只冻结本次实现范围。书面设计经用户复核后,生成详细实施计划,再修改业务代码并补充同 basename 的 Markdown 与 HTML 变更记录。