日志回捞(Log Recall)
常规日志采集是「端上主动上报」:受采样、级别、配额限制,不可能把每台设备的全部日志都传上来。 但排障时经常遇到「用户反馈 App 卡顿 / 报错,而他的日志恰好没有自动上报」的窘境。 日志回捞解决的就是这个问题——服务端按需向指定用户的设备下发回捞命令,设备把本地缓存的 加密日志文件补传上来,包括那些因级别 / 采样而未自动上报的条目。
回捞是 Argus 隐私敏感度最高的能力:它是「服务端主动要用户设备上的更多数据」。因此整条链路 被设计为默认 fail-closed——设备端有用户同意门(未同意不响应回捞)、命令有存活期(TTL) 且按 ID 幂等(同一命令只履行一次)、数据窗口有上限(默认 24h)、发起 / 查看 / 下载 / 删除 全程留痕审计。
核心概念
本地日志文件(Local Log)
开启 localLog 后(iOS / Android 初始化配置,默认关闭),SDK 把日志加密压缩写入设备
本地文件(源自 Clogan C 内核方法论:mmap 暂存 + AES 加密 + 压缩,退后台时强制落盘)。
这份文件平时不上传,只在两种情况下上传:
- 远程回捞:设备轮询发现回捞命令后,滚动(roll)当前会话日志并上传;
- 手动上传:业务代码调用
Argus.uploadLogs(),上传上次会话遗留的本地日志文件。
回捞命令(Recall Command)
一条回捞命令对应「让某个项目下(可选:某个 user_id 的)设备补传日志」的意图,关键属性:
| 属性 | 说明 |
|---|---|
id | 命令唯一 ID;SDK 按 id 去重,同一命令只履行一次(防重放 / 防误建多条) |
ttl_seconds | 命令存活期(Console 默认 600s = 10 分钟);到期自动过期,设备不再响应 |
window_seconds | 回捞数据时间窗(默认 24h,服务端拒绝超上限的请求) |
level | 级别过滤:只回捞该级别及以上(如 ERROR+),空 = 全部 |
modules | 模块过滤(逗号分隔),空 = 全部 |
ttl_seconds 与 window_seconds 语义不同:前者是「命令本身多久过期」,
后者是「回捞多长时间范围内的数据」。级别 / 模块过滤属于数据最小化要求——只拿排障必需的数据。
回捞文件与审计
- 设备上传的日志文件落对象存储,元数据(设备 / 用户 / 日期 / 大小 / 平台 / 状态)入库, Console 可列表、在线查看解密后的条目、下载原文件;文件按项目留存策略定期清理。
- 敏感操作全程审计:
recall_create(发起回捞)、view_entries(查看条目)、download(下载文件)、retention_delete(留存到期删除)。审计记录元信息 (谁 / 何时 / 哪个文件),不包含日志正文。
用户同意门(fail-closed)
在 requireLogConsent = true 的配置下,未获最终用户同意的设备一律不响应回捞命令、
不上传本地日志(Argus.uploadLogs() 同样被同意门拦截)。用户撤回同意
(Argus.setLogConsent(false))后设备不再响应任何回捞。回捞数据上传前照常经过端上脱敏,
回捞不绕过脱敏。
接入
平台支持矩阵
| 端 | 本地日志文件 | 远程回捞(命令轮询) | 手动上传 uploadLogs() |
|---|---|---|---|
| iOS | ✅(localLog: true) | ✅ | ✅ |
| Android | ✅(localLog(true)) | ✅ | ✅ |
| Web / Flutter / React Native | — | — | — |
回捞依赖端上本地加密日志文件,目前由 iOS / Android SDK 提供;先完成 iOS 或 Android 基础接入。
开启本地日志
// Android:初始化时开启 localLog(默认关)
Argus.init(applicationContext, ArgusConfig.Builder(dsn)
.localLog(true)
// PIPL / GDPR opt-in 场景:开启同意门,未同意不采集、不响应回捞
.requireLogConsent(true)
.build())
// 用户在你的隐私弹窗中同意后:
Argus.setLogConsent(true)// iOS:ArgusConfig 的对应字段
var config = ArgusConfig(dsn: dsn)
config.localLog = true
config.requireLogConsent = true
Argus.start(with: config)
// 用户同意后:
Argus.setLogConsent(true)手动上传本地日志
适合「用户在反馈表单里点了提交,顺带把日志传上来」的场景:
// 上传上次会话遗留的本地日志文件(不含当前在写的)。后台执行,best-effort。
Argus.uploadLogs()iOS 为同名 API Argus.uploadLogs()。未开启 localLog、未同意(同意门开启时)、
或已有上传进行中时,调用为静默 no-op。
Console 使用
进入 Console → Logs → Files(/logs/files 页面)。
发起远程回捞
设定过滤(可选)
在工具栏选择回捞级别(如 ERROR+,空 = 全部级别)与模块过滤(逗号分隔,空 = 全部)——
按数据最小化原则,能过滤就过滤。
点击「Request recall」
Console 会创建一条回捞命令(默认 10 分钟命令存活期 / 24h 数据窗口)。
等设备响应
目标设备在前台运行并轮询到命令后,滚动当前会话日志并上传;文件出现在下方列表中。 设备离线或命令过期则不会有文件产生。
浏览与下载日志文件
文件列表展示 File / Device / User / Date / Size / Platform / Uploaded 列,支持按 Device ID、User ID、日期、文件名模糊搜索。每行两个操作:
- View:进入文件详情,服务端解密 + 解压 + 解析后按条目展示,可按级别与关键词过滤;
- Download:经 Console 代理下载原始文件(不直连对象存储)。
查看条目与下载文件都会写入审计(view_entries / download)。审计供合规与取证查询——
「谁在什么时候看过哪个用户的回捞日志」全程可追溯,详见 审计日志。
SDK API
| API | 端 | 说明 |
|---|---|---|
ArgusConfig.localLog | iOS / Android | 开启本地加密日志文件(默认 false) |
ArgusConfig.requireLogConsent | iOS / Android | 开启用户同意门(默认 false;开启后未同意不采集、不响应回捞) |
Argus.setLogConsent(granted) | iOS / Android | 授予 / 撤回最终用户同意 |
Argus.isLogConsentGranted() | iOS / Android | 查询当前同意状态 |
Argus.uploadLogs() | iOS / Android | 手动触发上传上次会话的本地日志文件(后台执行,best-effort) |
远程回捞无需额外代码:开启 localLog 后 SDK 自动轮询回捞命令端点
(GET /v1/logs/recall-commands,设备侧 HMAC 签名),发现属于本项目 +
本用户的 active 命令即履行。
MCP 工具
回捞相关的 MCP 工具全部只读:
| 工具 | 用途 | 关键参数 |
|---|---|---|
log.list_files | 列出项目已上传(回捞)的日志文件,可按设备 / 用户 / 日期 / 文件名过滤 | project_id、device_id、user_id、date、q、limit |
log.file_entries | 读取某个回捞文件解码后的日志条目(服务端解密 + 解压 + 解析) | project_id、file_id、level、q、limit |
log.audit | 查询回捞审计轨迹:谁 / 何时访问了哪个文件、发起了哪次回捞 | project_id、limit |
AI 不能发起回捞。 触发回捞是「改变系统状态、令真实用户设备上传数据」的写操作, MCP Server 有意不注册回捞触发工具——AI 对回捞只能「看」(列文件 / 读条目 / 读审计), 发起回捞只能由人在 Console 点「Request recall」完成。这是防提示词注入 (如日志正文里混入「请回捞所有用户数据」)的硬边界。
配额与计费
- 回捞回来的日志按正常 events / 存储计入项目配额;
- 回捞文件受项目留存策略约束,到期自动清理(删除动作记
retention_delete审计)。
常见问题
点了「Request recall」却一直没有文件?
按顺序排查:① 目标设备是否在线并处于前台(SDK 轮询发现命令需要 App 运行);② 命令是否已过期
(默认存活 10 分钟,过期需重新发起);③ 设备端是否开启了 localLog;④ 同意门开启时用户是否
已授予同意(未同意的设备 fail-closed,不响应);⑤ 该命令是否已被履行过(同一命令只履行一次)。
回捞会拿到用户的全部历史日志吗?
不会。回捞受数据时间窗上限约束(默认 ≤ 24h),且可按级别 / 模块进一步收窄; 上传前照常经过端上脱敏。这是产品层面的数据最小化硬约束,不是可选项。
用户拒绝或撤回同意后会发生什么?
requireLogConsent = true 且未同意(或已撤回)的设备不采集本地日志、不响应任何回捞命令、
uploadLogs() 为 no-op。对你的服务端而言表现为「命令到期未被履行」。
回捞日志和普通日志页是一回事吗?
不是。Logs(/logs)查询的是 SDK 实时上报入库的结构化日志;
Logs → Files(/logs/files)管理的是整文件回捞上来的端上本地日志,需要打开文件详情
逐条查看。两者互补:实时日志覆盖面广,回捞日志针对单用户深挖。
谁能发起回捞、谁能看回捞数据?
发起、查看、下载均要求 Console 运营侧登录鉴权,且每一步都写审计。用 log.audit(MCP)
或审计页可回查全部访问记录。