Crash上报与原始信息采集标准
适用场景
本章适用于所有需要接入Crash采集SDK的移动端/桌面端应用。主要场景包括:
- 新项目首次集成Crash SDK
- 存量项目升级SDK版本或调整采集策略
- 跨团队(客户端、QA、数据平台)对齐采集字段规范
- 验收采集数据质量,确保归因分析基础可靠
前置条件
- 已确定目标平台(iOS / Android / Windows / macOS / Linux)对应Crash SDK版本
- 已获取SDK接入文档及(AppKey / AppSecret)
- 已完成项目编译环境搭建(如Xcode、Android Studio、CMake)
- 已确认数据存储与传输合规要求(GDPR / 隐私协议)
操作步骤
步骤1:上报SDK配置要点
按平台初始化SDK,核心配置项包括:
| 配置项 | 类型 | 说明 | 示例值 |
|---|---|---|---|
| AppKey | String | 应用标识,必填 | com.example.myapp |
| AppVersion | String | 当前版本号,必填 | 3.2.1 |
| EnableCrashReport | Boolean | 是否启用Crash采集 | true |
| MaxLogSize | Int | 本地日志上限(MB) | 50 |
| UploadStrategy | Enum | 上传策略:REALTIME/BATCH/WIFIONLY | REALTIME |
配置示例(Android):
CrashConfig config = new CrashConfig.Builder()
.setAppKey("com.example.myapp")
.setAppVersion("3.2.1")
.setEnableCrashReport(true)
.setUploadStrategy(UploadStrategy.REALTIME)
.build();
CrashSDK.init(config);
⚠️ 确保初始化代码放在应用启动最早执行点(
Application.onCreate() 或 main() 入口),避免漏采集启动阶段Crash。步骤2:必采字段定义(堆栈、设备、OS、版本、时间)
每个Crash原始记录必须包含以下5个字段,缺一不可:
| 字段 | 字段名 | 格式/约束 | 采集来源 |
|---|---|---|---|
| 堆栈 | stack_trace | 多行文本,包含异常类型、消息、完整调用栈 | 系统异常处理器 / Signal Handler |
| 设备 | device_model | 字符串,如 iPhone15,4 / SM-S928B | 系统API(Build.MODEL / sysctl) |
| 操作系统 | os_version | 字符串,如 iOS 17.4.1 / Android 14 | 系统API(os.version) |
| 应用版本 | app_version | 字符串,如 3.2.1 (build 2048) | SDK初始化时传入 |
| 发生时间 | crash_timestamp | ISO 8601 毫秒精度,如 2025-02-18T14:30:12.345Z | 系统时钟(UTC) |
最佳实践: 增加辅助字段(如
thread_name、device_arch、memory_usage)可提升归因准确率,但5个必采字段必须先行采集,不可因扩展字段延迟或失败导致核心字段丢失。步骤3:采集优先级策略
当系统资源受限(如内存耗尽、磁盘满、低电量)时,按以下优先级采集:
- P0(必须即刻采集):堆栈 + 发生时间。即使后续字段丢失,也必须先保存堆栈和时间戳。
- P1(尽力采集):设备型号 + 操作系统版本。通过后台异步线程补充采集。
- P2(延迟采集):应用版本号。可从本地持久化缓存获取,允许在下次启动时补全。
注意: 优先级策略需在SDK配置中显式声明,默认应使用“全部采集,失败则降级”模式。严禁因辅助字段采集失败而放弃整个Crash记录。
步骤4:数据完整性校验规则
每条Crash原始记录在本地序列化后、上传前,必须通过以下校验:
| 校验项 | 规则 | 校验失败处理 |
|---|---|---|
| 必采字段存在性 | stack_trace/device_model/os_version/app_version/crash_timestamp 均非空 | 丢弃本条记录并记录异常日志 |
| 堆栈格式 | 堆栈必须以C/C++/Java/Kotlin/ObjC异常关键字开头,至少包含3层调用帧 | 标记为“无效堆栈”,保留原文本供人工审计 |
| 时间合理性 | 时间戳距当前系统时间前后偏差不超过±5分钟 | 调整至系统当前时间并打上时钟偏差标记 |
| 字段类型 | 所有字段为String类型,长度不超过预设上限(如堆栈≤64KB) | 截断至上限并记录截断警告 |
校验伪代码示例:
def validate_crash_record(record):
for field in REQUIRED_FIELDS:
if not record.get(field):
raise ValidationError(f"缺失必采字段: {field}")
if not is_valid_stack_trace(record['stack_trace']):
record['stack_trace_invalid'] = True
ts = parse_iso8601(record['crash_timestamp'])
if abs(now() - ts) > 300:
record['time_corrected'] = now().isoformat()
return record
输入输出物
| 类别 | 内容 | 格式/载体 |
|---|---|---|
| 输入 | Crash原始事件(信号/异常对象) | 系统运行时数据 |
| 输出 | 结构化Crash原始信息记录 | JSON / Protocol Buffers 序列化文件 |
| 中间产物 | SDK初始化日志、字段采集日志、校验日志 | 文本日志文件(≤50MB) |
责任边界
- 客户端开发团队:负责SDK集成、配置项正确设置、必采字段采集逻辑验证。
- QA团队:通过注入Crash测试用例验证5个必采字段是否完整上报,校验规则是否正确执行。
- 数据平台团队:接收Raw Crash数据,对采集完整性做二次校验,推动降级策略优化。
- Crash治理负责人:监督采集质量,制定优先级及校验规则变更审批。
记录材料
- SDK版本与配置清单:记录各平台使用的SDK版本、初始化参数快照。
- 字段采集覆盖率报告:每日统计必采字段缺失率、校验失败率。
- 异常处理日志:包括SDK未初始化、字段截断、时间修正、降级事件等。
异常处理
| 异常场景 | 处理措施 | 对接团队 |
|---|---|---|
| SDK未正确初始化 | 应用启动时检查配置,若未初始化则打印警告,并尝试使用默认配置(仅采集P0字段) | 客户端开发 |
| 必采字段缺失 | 丢弃该条记录,记录缺失字段到本地错误日志;同时触发告警通知数据平台 | 数据平台 |
| 校验失败(如堆栈格式异常) | 保留原文本,标记为“待审计”,上传时附带校验状态字段 | Crash治理负责人 |
| 本地存储满 | 触发LRU淘汰策略:优先删除时间最久且已上传的旧记录;若仍无法写入则丢弃新Crash(记录计数统计) | 客户端开发 |
验收标准
- 字段完整性:在QA构造的100次Crash测试中,每条记录的5个必采字段全部非空,字段完整率≥100%。
- 优先级正确性:模拟资源受限场景(如磁盘剩余空间<1MB),采样100次Crash,P0字段保存率≥99%,P1字段保存率≥90%。
- 校验规则执行:时间偏差超过±5分钟的Crash记录100%被修正并标记;无效堆栈100%被标记并保留原文。
- 异常处理不崩溃:SDK在初始化失败、校验失败、存储满等异常场景下,宿主应用不崩溃,不影响主流程运行。