Files
shaguabijia-app-server/docs/api/other/applog-batch.md
T
2026-07-19 10:01:54 +08:00

4.9 KiB
Raw Blame History

POST /api/v1/applog/batch — 批量上报客户端运行日志

所属:客户端日志组(前缀 /api/v1/applog | 鉴权:无(不强制登录,user_id 可选带上) | ← 返回 API 索引

批量接收客户端 App 运行日志(自动化步骤 / 网络 / 崩溃 / 调试等),逐条封装成单行 JSON 写入独立滚动文件 logs/app-client.log(与服务日志 app-server.log 分开),由阿里云 Logtail 采进独立 SLS logstore不落库。服务端补 client_ipX-Forwarded-For)与 time(接收时间,SLS 主时间)。trace_id 提到输出行顶层,便于在 SLS 里跨「客户端 / 服务端」两个 logstore 按 trace 拼出端到端链路。fire-and-forget:写失败也返回 2xx,不 500。

入参

批级公共字段发一次;logs 里每条只带日志本身。每条只有 client_ts/level/trace_id/tag/msg 会提到输出顶层,其余自定义字段一律并入输出的 data(防 SLS 索引列爆炸)。

字段 类型 必填 说明
device_id string (≤64 设备 ID(限流 / 分组键)
user_id int | null 登录用户 ID(未登录可空)
app_ver string | null (≤32 App 版本
platform string | null (≤16 平台(android / ios / harmony
sent_at int | null 批次发送时间(epoch ms
logs list[object] 1-500 条) 日志数组(每条为对象,内部字段不强类型
logs[].client_ts int 端侧日志时间(epoch ms
logs[].level string 级别(服务端归一化大写,截断 ≤16
logs[].trace_id string | null 关联服务端比价链路的 trace(有服务端交互的日志带上,截断 ≤256)
logs[].tag string | null 模块 / 分类(截断 ≤128
logs[].msg string 消息主体(超 8KB 字节截断,加 msg_truncated 标记)
logs[].* any 其余任意自定义字段 → 一律并入输出的 data(客户端自带的 data 对象会被合并进来)

Mock 入参:

{
  "device_id": "android_abc123def456",
  "user_id": 42,
  "app_ver": "0.1.5",
  "platform": "android",
  "sent_at": 1719993700000,
  "logs": [
    {
      "client_ts": 1719993600000,
      "level": "info",
      "tag": "automation",
      "msg": "compare flow start",
      "trace_id": "t_ab12cd34"
    },
    {
      "client_ts": 1719993615000,
      "level": "error",
      "tag": "network",
      "msg": "timeout calling /price/step",
      "trace_id": "t_ab12cd34",
      "http_status": 504,
      "retry": 2
    }
  ]
}

上例第二条的 http_status / retry 不在白名单 → 会被并入落盘行的 data:{"http_status":504,"retry":2}

出参

响应 200:AppLogIngestOut

字段 类型 说明
ok bool 固定 true
received int 成功写入文件的条数
dropped int 跳过的条数(服务端处理 / 序列化失败;正常为 0

Mock 出参:

{
  "ok": true,
  "received": 2,
  "dropped": 0
}

错误码

  • 413 请求体超过上限(默认 2MB;服务端查 Content-Length,在 body 校验前拦截。缺该头时由 nginx client_max_body_size 兜底)
  • 422 logs 为空或超过 500 条 / device_id 缺失 / 字段类型不符
  • 429 触发限流(同 IP 每分钟 > 120 次)

说明

  • 落盘 → SLS:逐条写独立文件 logs/app-client.log(单行 JSONpropagate=False 不污染 app-server.log),由 Logtail JSON 模式采进独立 logstore;不进数据库。落盘行除白名单字段外,服务端另补 time(接收时间)、source="client"serviceclient_ip 及批级 device_id/user_id/app_ver/platform/sent_at
  • trace_id 跨层检索:字段名与服务端日志一致。客户端应给有服务端交互的日志带上当初 API 返回的 trace_id(如 /api/v1/price/step 等透传族返回的 trace),即可在 SLS 里 trace_id: "xxx" 一查拼出「客户端视角 + 服务端比价链路」;纯客户端日志不带即可。
  • 白名单 + data 兜底:只有 client_ts/level/trace_id/tag/msg 上顶层,其余键并入 data,把 SLS 索引列钉死在固定集合,防客户端任意 key 撑爆索引。索引字段另有长度上限(level≤16 / trace_id≤256 / tag≤128 / msg≤8KB)。
  • fire-and-forget:写文件失败也返回 2xx(避免客户端重试风暴);网络重试可能在 SLS 造成重复条目,可接受。
  • 量级建议:客户端做等级过滤 / 采样,攒到一定量再批量上报;单批 ≤500 条、body ≤2MB。
  • client_ts 是端侧时间(客户端时钟不可信),time 由服务端补(可靠时间轴)。
  • user_id 不靠 JWT:未登录态也要采日志;带上便于按用户排查。