异常问题追踪(Exception Tracking)是用户体验监控提供的核心能力之一。该功能针对网络请求异常、页面加载异常、卡顿、崩溃、ANR 等问题,自动捕获异常信号及堆栈信息,追踪异常根因或代码行,并通过用户操作轨迹回溯,还原问题发生现场。
功能概述
通过异常问题追踪,您可以:
自动捕获应用运行中的各类异常,无需手动埋点。
获取异常发生时的完整堆栈信息,精准定位到代码行。
结合用户会话轨迹,回溯异常发生前的用户操作路径,还原问题现场。
通过分阶段网络耗时指标,区分网络层与服务端的异常根因。
实时监控应用稳定性,及时发现和响应线上问题。
前提条件
使用异常问题追踪功能前,请确保已完成以下准备工作:
已在控制台创建应用并获取初始化代码。
已完成 SDK 的集成和初始化。具体操作请参见前端应用。
说明:SDK 初始化成功后,异常问题追踪功能默认开启,网络请求异常、崩溃、ANR、卡顿等事件将自动采集,无需额外配置。
工作原理
异常检测机制
SDK 提供两种异常检测方式:
自动捕获:SDK 自动监听网络请求失败、应用崩溃信号、主线程阻塞、帧率下降等异常事件,无需业务代码介入。
手动上报:对于业务逻辑中主动捕获的异常(如 try-catch 中的错误),可通过 SDK 提供的接口手动上报,适用于记录非致命错误或业务异常。
堆栈采集与解析
当异常发生时,SDK 自动采集异常现场的调用堆栈信息。不同平台的堆栈解析机制如下:
前端应用(Web / 小程序):SDK 采集 JavaScript Error 的调用堆栈。对于经过压缩混淆的生产代码,上报到服务端后,通过您上传的 SourceMap 文件对堆栈进行还原,将压缩后的代码位置映射回原始源码的文件名、方法名和行列号。
移动端应用(iOS / Android):SDK 采集崩溃线程及所有线程的完整调用堆栈,并记录二进制镜像信息(模块名称、架构、UUID、加载地址等)。上报到服务端后,通过您上传的符号表(iOS dSYM 文件 / Android Mapping 文件)对堆栈地址进行符号化还原,将内存地址转换为可读的类名、方法名和代码行号。
无论哪种平台,最终目标一致:将原始堆栈还原为可读的源码位置,帮助您精准定位异常代码。
异常与上下文关联
每个异常事件在采集时自动关联以下上下文信息:
Session ID:异常所属的用户会话,可回溯异常发生前的完整用户行为轨迹。
页面信息:异常发生时用户所在的页面名称和页面 ID。
用户信息:用户 ID、用户名称等自定义标识。
设备与环境:设备型号、操作系统版本、网络类型、应用版本等。
通过这些关联信息,您可以在控制台中从一个异常事件出发,查看该用户在异常发生前后的完整操作轨迹,还原问题现场。
异常处理流程
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 异常发生 │───▶│ 信号捕获 │───▶│ 堆栈采集 │
└──────────────┘ └──────────────┘ └──────┬───────┘
│
▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 控制台展示 │◀───│ 服务端符号化 │◀───│ 关联上下文 │
│ 根因定位 │ │ 堆栈还原 │ │ 上报数据 │
└──────────────┘ └──────────────┘ └──────────────┘说明:崩溃(Crash)事件由于导致应用退出,其数据会在下次应用启动时自动上报。
异常类型详解
网络请求异常(Resource Error)
SDK 自动拦截应用发起的网络请求,当请求失败、超时或返回 HTTP 错误状态码时,自动记录异常信息及完整的分阶段耗时指标,帮助区分网络层与服务端的问题根因。
属性 | 说明 |
请求 URL | 完整的请求地址 |
HTTP 方法 | 请求方法(GET、POST 等) |
状态码 | HTTP 响应状态码 |
错误类型 | 错误分类标识(如超时、连接失败等) |
资源类型 | 资源类型(API、Image、Media、Font 等) |
DNS 耗时 | DNS 解析耗时(ms) |
TCP 连接耗时 | TCP 连接建立耗时(ms) |
TLS 耗时 | TLS 握手耗时(ms) |
首字节时间(TTFB) | 从请求发出到收到第一个字节的时间(ms) |
响应耗时 | 完整响应耗时(ms) |
请求大小 | 请求体大小(bytes) |
响应大小 | 响应体大小(bytes) |
通过分阶段耗时指标,您可以快速判断异常发生在哪个环节:
DNS 耗时异常:可能是 DNS 解析服务不稳定或域名配置问题。
TCP/TLS 耗时异常:可能是网络链路不稳定或证书配置问题。
TTFB 异常:通常指向服务端处理慢。
HTTP 错误状态码(4xx/5xx):服务端返回错误,需排查后端逻辑。
页面加载异常(View Error)
SDK 自动采集每个页面的加载耗时,当页面加载时间超过设定阈值时,标记为慢加载页面。
属性 | 说明 |
页面名称 | 页面标识名称 |
页面 URL | 页面路径 |
页面加载耗时 | 页面从开始加载到加载完成的时间(ms) |
慢加载标记 | 是否超过慢加载阈值 |
页面停留时长 | 用户在该页面的停留时间(ms) |
说明:慢加载阈值通过控制台远程配置下发,您可以根据业务需要调整。
应用崩溃(Crash)
SDK 自动捕获应用运行中的崩溃事件,包括未捕获异常和系统级异常。崩溃数据在下次应用启动时自动上报。
捕获的崩溃类型:
崩溃类型 | 说明 | 适用平台 |
未捕获异常 | 运行时未捕获的异常(如 iOS NSException、Android UncaughtException) | 移动端 |
系统信号异常 | 如 SIGSEGV(非法内存访问)、SIGABRT(异常终止)、SIGBUS(总线错误)等 | 移动端 |
JavaScript Error | JS 运行时未捕获的异常(TypeError、ReferenceError 等) | 前端 / 小程序 |
Promise Rejection | 未处理的 Promise 拒绝 | 前端 / 小程序 |
野指针访问 | 访问已释放对象导致的崩溃 | 移动端 |
采集的属性:
属性 | 说明 |
异常类型 | 崩溃的分类标识 |
异常子类型 | 具体的信号类型或异常类别 |
异常名称 | 异常名称 |
异常原因 | 导致崩溃的原因描述 |
堆栈信息 | 崩溃现场的完整调用堆栈 |
崩溃线程 ID | 发生崩溃的线程标识(移动端) |
二进制镜像信息 | 模块名称、架构、UUID、加载地址,用于堆栈符号化(移动端) |
所在页面 | 崩溃发生时用户所在的页面 |
会话 ID | 崩溃所属的会话 |
应用状态 | 崩溃时应用是否在前台 |
崩溃时间 | 崩溃发生的精确时间戳 |
ANR(Application Not Responding)
SDK 自动检测主线程长时间无响应的情况。当主线程被阻塞超过阈值时,SDK 判定为 ANR 事件,自动采集当时的主线程堆栈信息。
属性 | 说明 |
异常类型 | ANR / 主线程死锁 |
堆栈信息 | ANR 发生时的主线程调用堆栈 |
二进制镜像信息 | 用于堆栈符号化的模块信息 |
所在页面 | ANR 发生时用户所在的页面 |
会话 ID | ANR 所属的会话 |
ANR 的常见原因包括:
主线程执行大量同步 IO 操作(如文件读写、数据库查询)。
主线程执行复杂计算或大数据量处理。
死锁或线程间等待。
同步网络请求阻塞主线程。
卡顿(Long Task)
SDK 自动监控主线程执行情况和渲染帧率,当检测到长时间阻塞或帧率下降时,记录卡顿事件。
属性 | 说明 |
卡顿类型 | 卡顿分类(主线程阻塞、帧率卡顿等) |
卡顿时长 | 主线程阻塞的持续时间(ms) |
堆栈信息 | 卡顿发生时的主线程调用堆栈 |
二进制镜像信息 | 用于堆栈符号化的模块信息 |
所在页面 | 卡顿发生时用户所在的页面 |
会话 ID | 卡顿所属的会话 |
SDK 检测的卡顿类型包括:
主线程阻塞:主线程执行时间超过阈值的任务。
帧率卡顿(FPS Drop):渲染帧率低于阈值,用户感知到界面不流畅。
磁盘 IO 阻塞:主线程上的磁盘读写操作导致的卡顿。
CPU 过载:CPU 占用过高导致的性能下降。
异常根因追踪
异常问题追踪的核心价值在于从异常现象出发,快速定位根因代码并还原问题现场。提供以下能力支撑根因追踪:
堆栈解析定位代码行
SDK 采集的原始堆栈需要经过解析还原才能定位到源码位置:
前端应用:通过上传 SourceMap 文件,将压缩混淆后的代码位置映射回原始源码的文件名、方法名和行列号。
移动端应用:通过上传符号表(iOS dSYM 文件 / Android Mapping 文件),将内存地址还原为可读的类名、方法名和代码行号。
解析还原后,您可以:
定位类名和方法名:明确异常发生在哪个类的哪个方法中。
定位源文件和行号:精确到具体的代码文件和行号。
通过还原后的堆栈,您可以直接跳转到对应代码位置排查问题。
会话轨迹回溯还原现场
每个异常事件都关联了 Session ID 和页面信息。在控制台中,您可以从异常事件出发,查看该用户在异常发生前的完整操作轨迹:
用户依次访问了哪些页面。
在每个页面上执行了哪些操作(点击、滑动等)。
触发了哪些网络请求,请求是否成功。
异常发生前是否已经出现了其他异常或卡顿。
这些信息帮助您理解异常发生的完整上下文,而不仅仅是一个孤立的堆栈。
多维度聚合分析
控制台对同类异常进行自动聚合,您可以从多个维度分析异常的影响范围和分布规律:
设备维度:异常是否集中在特定机型或系统版本。
版本维度:异常是否在某个版本引入。
页面维度:异常是否集中在特定页面。
时间维度:异常是否在特定时间段集中爆发。
使用场景
场景一:崩溃根因定位
线上版本崩溃率突然上升。通过控制台查看崩溃列表,找到新增的崩溃类型,查看符号化后的堆栈信息定位到具体代码行。进一步通过会话轨迹回溯,发现崩溃均发生在用户执行特定操作序列后,确认是新版本引入的逻辑缺陷。
场景二:网络异常排查
用户反馈"数据加载失败"。通过用户 ID 找到对应会话,在会话轨迹中定位到失败的网络请求。查看请求的分阶段耗时:DNS 和 TCP 连接正常,但 TTFB 超过 10 秒且最终返回 504 状态码,判断为服务端超时问题,转交后端团队排查。
场景三:卡顿问题优化
用户反馈"列表滑动不流畅"。通过控制台查看卡顿事件,发现大量帧率卡顿集中在商品列表页。查看卡顿堆栈,发现主线程在滑动过程中执行了同步的图片解码操作,将图片解码改为异步处理后,卡顿问题消除。
常见问题
异常问题追踪功能是否需要手动开启?
不需要。SDK 初始化成功后,崩溃、ANR、卡顿、网络异常等事件自动采集,无需额外配置。
崩溃数据是实时上报的吗?
移动端崩溃会导致应用退出,因此崩溃数据会在下次应用启动时自动上报。前端 JavaScript Error 为实时上报。其他异常类型(网络异常、卡顿、ANR 等)均为实时上报。
如何上传符号表 / SourceMap 进行堆栈解析?
您可以在控制台的应用设置中上传对应文件:前端应用上传 SourceMap 文件,iOS 应用上传 dSYM 文件,Android 应用上传 Mapping 文件。建议在 CI/CD 流程中集成自动上传,确保每个版本的解析文件都能及时上传。
自定义异常如何上报?
对于业务代码中主动捕获的异常,可通过 SDK 提供的自定义异常上报接口手动上报。具体 API 用法请参见各平台的 SDK 配置参考文档。
ANR 和卡顿有什么区别?
ANR 是指主线程长时间完全无响应(通常为死锁或严重阻塞),属于严重异常。卡顿是指主线程短暂阻塞或帧率下降导致界面不流畅,影响用户体验但不会导致应用无响应。两者的检测机制和阈值不同,ANR 的阈值通常更高。
异常采集是否影响应用性能?
SDK 的异常采集机制经过优化,对应用性能的影响极小。堆栈采集仅在异常发生时触发,不会持续消耗资源。卡顿和帧率监控采用轻量级的检测方案,对主线程的额外开销可忽略不计。