跳转到主要内容
MoleSignal Flutter App RUM SDK 与 Browser RUM SDK 使用同一种事件格式发送移动端遥测。Flutter 原生监测让移动端沿用相同的排障流程,同时避免伪造浏览器专属指标。

能力对齐

LCP、CLS 等浏览器专属指标不会在 Flutter 应用中生成。Flutter 上报 build、raster、刷新率、慢帧、冻结帧和内存数据。

环境要求

  • Flutter 3.35 或更高版本;
  • Dart 3.9 或更高版本;
  • 使用默认持久化身份存储时,需要 Android 24+ 或 iOS 13+。
设备品牌、型号、系统版本、电量和网络连接通过 device_info_plus、battery_plus 与 connectivity_plus 读取,这个包依赖它们。设置 trackDeviceInfo: false 则只发送 Flutter 自身提供的信息。

安装与初始化

clientToken 会随 App 下发,必须视为公开凭证。请使用 RUM 应用中与应用绑定的 msrum_ Client Token。
1

创建应用

打开 用户体验 → 应用,点击 创建应用,选择 Flutter 平台。打开接入向导 会给出端点、Token,以及填好标识符的配置。
2

添加包

更新 pubspec.yaml 后运行 flutter pub get。
3

在 runApp 之前初始化

请尽早调用 initRum:冷启动耗时从这里开始,一直算到第一帧。RumApp 会安装回放边界、自动 Tap 采集和受挫信号检测。除非 sessionReplaySampleRate 选中了当前会话,或手动开始录制,否则回放保持关闭。
4

验证第一个会话

打开 用户体验 → 探索,选择包含当前时间的时间范围,确认 checkout-mobile 的会话已出现,并打开它查看视图和设备上下文。
site 接受 MoleSignal 的源地址,也接受以 /api、/api/v1 或 /api/v1/rum 结尾的地址。SDK 会补全路径,并把事件发送到 POST /api/v1/rum/events。applicationId 必须是 Token 所绑定的应用:它会作为 application.id 发送,事件指明了别的应用时,MoleSignal 会拒绝。

会话与视图

会话由保存在 shared preferences 中的 UUID 标识。它在 15 分钟无活动或满四小时后结束,并在开始时只采样一次。SDK 不发送会话事件:MoleSignal 从视图派生会话。每个事件都带有 session.id、session.type 和 session.start;视图还带有 session.has_replay,会话录制过回放分段后它为 true。视图不会跨越两个会话:会话在某个视图展示期间续期时,该视图结束,同一个界面在新视图中继续,loading_type 为 session_renewal。 RumNavigationObserver 记录可见的命名路由。Router 或 go_router 应用请通过路由集成提供该 Observer。路由没有稳定名称,或导航不由 Navigator 管理时,请调用 startView。
view.url 是路由路径,除非设置 trackUrlQueryString,否则不含查询和 Fragment;view.name 是名称。开始一个视图会结束前一个视图。视图中只要有变化,就用更高的 view.revision 和当前的计数再次上报:每个 flushInterval 最多一次,并在视图开始、结束或 App 刷新时立即上报。App 进入后台时视图结束,返回时以 view_controller_redisplay 再次展示。第一次 startView 之前发生的事件归入 ApplicationLaunch 视图。

识别用户并记录应用活动

SDK 会串联已有的 FlutterError.onError 与 PlatformDispatcher.onError 处理器。请把其他 Isolate 中的错误转发到主 Isolate 并调用 addError。登出后,如果后续活动不应再归属于已识别的用户,请调用 clearUser()。 操作 有 tap、custom、back,以及自动产生的 application_start。自动 Tap 使用通用名称 Tap,因此不会读取任何界面内容。请用 RumUserAction 包裹重要控件,为它附加稳定的业务名称,同时不会接管 Flutter 的手势竞技场:
Tap 会在它发起的请求进行期间保持打开,最长五秒。这段时间内的错误、崩溃和资源会带上它的 action.id,操作会上报它们的数量。一秒内在 50 个逻辑像素范围内的三次 Tap,最后一次是 rage_tap;引发错误的 Tap 是 error_tap。设置 trackUserInteractions: true 才会采集 Tap;trackFrustrations 默认跟随它。 错误 带有 source、type、message、stack、结构化的 frames 和 handling。框架错误是 unhandled,来自 PlatformDispatcher.onError 的错误同时是崩溃。addError 上报 handled 错误,source 由你选择,默认是 custom。在收到响应之前就失败的请求是 network 错误;HTTP 错误状态只是一个资源。SDK 不设置 error.fingerprint;需要决定归并方式时,请传入 fingerprint:。

监控 HTTP 资源并关联后端链路

用 MoleSignalHttpClient 包装 package:http:
应用尚未使用 package:http 时,请把 http: ^1.6.0 声明为应用的直接依赖。包装器会记录脱敏后的 URL、方法、耗时、状态码、响应大小,以及可用的 W3C trace 标识。耗时在响应体读完、失败或被取消时结束。trace 上下文按以下顺序读取:响应的 traceparent、Server-Timing 中的 traceparent 条目、请求的 traceparent。只信任部分服务时,可以限制读取 trace 头的范围:
SDK 不会全局拦截网络。Dio 与其他客户端请在拦截器中调用 startResource 与 stopResource,或对已经完成的请求调用 addResource。

渲染性能字段

上传 Release Symbols

请用发布流水线中不可变的值设置 version、architecture 和 debugId,并在同一次构建产生的所有调试产物中使用相同的值。运行时检测或推导出的回退值适合开发阶段,但不能为生产环境提供稳定的符号化标识。 构建 Android 与 iOS 发布版时使用 --obfuscate 和 --split-debug-info,并用 --dart-define 传入标识:
使用 --split-debug-info 时,每个错误帧都带有 artifact_kind: flutter_symbols、符号文件用来解析的绝对地址与相对地址,以及构建时配置的 debug_id。请用 kind=flutter_symbols、对应的 android 或 ios 平台、规范化的架构和 Debug ID 上传每个生成的 .symbols 文件。通过 RumStackFrame 转发原生崩溃帧时,请另外上传 Android 原生 ELF 符号和 Apple dSYM DWARF 文件。 上传产物需要拥有 streams.configure 的管理 Token。绝不要把与应用绑定的 msrum_ Client Token 用于产物管理。

Source Maps 与 Symbols

生成、上传、匹配并验证 Flutter、Android、iOS 与 Web 的调试产物。

启用会话回放

Flutter 没有 DOM。捕获的第一帧会成为 rrweb Meta 与 FullSnapshot 事件,发生变化的帧会成为增量图像 Mutation,没有变化的帧会被跳过。因此现有的 MoleSignal 回放播放器可以用同一套流程渲染浏览器和 Flutter 会话。
sessionReplaySampleRate 只作用于被 sessionSampleRate 纳入的会话,两个比例相乘即为实际的回放覆盖率。手动录制同样只适用于已被纳入的会话。回放使用单独的队列,默认每 10 秒刷新一次,带有按会话递增的序号,目标分段约 1 MiB,单个请求上限为 8 MiB。分段发送到 POST /api/v1/rum/replay。

保护回放内容

默认的 RumPrivacyLevel.mask 会在 PNG 编码之前遮盖 Text、RichText 和可编辑区域。输入框在 allow 模式下也保持遮盖。SDK 还会移除 URL 查询和 Fragment,并递归脱敏常见的敏感上下文键。只有 RumPrivacyLevel.allow 才会发送原始堆栈文本,否则 error.stack 由脱敏后的帧重建。请用显式的隐私边界包裹敏感图片、地图、自绘内容、平台视图或整个组件:
RumReplayMask 与 RumReplayBlock 都会用不透明色块替换捕获区域。未遮盖的原始像素不会进入事件队列。
CustomPainter 绘制的文字无法从 Widget 类型识别,请显式包裹自绘区域。平台视图的捕获取决于平台合成方式,请在真实的 Android 与 iOS 设备上验证敏感的平台视图。

发送

事件会合并为 JSON 数组,带着 Client Token 发送到 POST {site}/api/v1/rum/events。超过 1 KiB 的批次在有 dart:io 的平台上会用 gzip 压缩;设置 compressRequests: false 可关闭。一个请求最多携带 48 KiB 的事件,远低于接收端接受的 5000 个事件和 5 MiB。
  • 被 MoleSignal 拒绝的事件会通过 onError 和 RumFlushResult 报告,不会再次发送。
  • 网络错误、超时、408、429 和 5xx 会以指数退避加抖动重试,不早于接收端给出的 Retry-After。事件保存在持久化的离线队列中。
  • 其他 4xx 会丢弃整个批次。
队列受条数、字节数和存留时间限制(maxQueueSize、maxQueueBytes、queueItemTtl)。视图较新的修订会替换仍在等待的旧修订,因此 MoleSignal 看到的修订序号可能不连续。

主要配置

RumSessionReplayConfiguration 默认每 5 秒捕获一次、在操作之后捕获、每个逻辑像素输出 0.5 个像素、图片最长边 900 像素、遮盖颜色为 #6B7280。excludedUrls、allowedTracingUrls、队列上限、重试延迟、超时、诊断、自定义传输和持久化同样可以配置。

刷新与停止

在必须等待队列中事件发送完成的受控切换之前,请调用 flush()。在最终清理时调用 stop():它会为当前视图做最后一次上报、移除采集,并刷新两个事件队列。两者都会返回 RumFlushResult,其中区分了已接受、已重试、已丢弃、剩余和超时的事件。

Browser RUM SDK

对比 Browser SDK 的接入方式和浏览器专属的监测。

RUM 事件格式

SDK 发送的事件及各事件的字段。

Source Maps 与 Symbols

还原 Flutter、Android、iOS 与 Web 发布版的堆栈。
最后修改于 2026年10月26日