共计 5231 个字符,预计需要花费 14 分钟才能阅读完成。
一. Rollbar 能够帮你解决哪些问题
无特地阐明,文中 Rollbar 统指 Rollbar-flutter
1. 代码复用
Rollbar 官网文档说是纯 Dart 实现,该特色意味着自带”代码复用”光环。
如图当接入端 (Third-APP) 调用 Rollbar SDK 时示意蕴含的网络 (异样数据上传等) 和存储 (异样存储管理) 可达到复用成果。
若 Flutter 异样监控框架非纯 Dart 实现 (第三篇中 Bugsnag),就存在代码无奈复用问题,如图,Dart-Crash-SDK 是这层壳依赖对端 SDK,最终导致各平台(android,ios,…) 都须对端 SDK(android-crash-sdk, ios-crash-sdk,…)适配,导致网络和存储逻辑对端 SDK 都须各自实现一遍,重大逻辑反复。
由此在做软件多端架构设计时,Dart 侧可了解成是多平台公共代码汇合,如果存在多端逻辑性能代码齐全能够抽离到 Dart 侧以复用,缩小测试和人力老本。
2. 定制包装操作
后面两篇文章咱们晓得,捕捉到原始异样后对其中的 Error 和 StackTrace 有相当局部的工作是对原始异样数据的 包装 再将包装类数据发送给对端或者后盾,不同框架包装过程是不一样的,如下图中 Catcher 框架包装后类对象是 Report,Bugsnag 对异样进行两次包装,第一次是 BugsnagError,第二次是 BugsnagEvent。
这很好了解,因为对于同一事物不同框架的需要是不一样的,不同需要注定了不同的包装行为。
原始异样数据就像一条鱼,口味油腻的 Catcher 抉择清蒸,重口味的 Bugsnag 抉择红烧,不同框架就是不同口味的吃鱼人。而 Rollbar 将包装行为抽象化,将原始的鱼以某种形式提供给你,让你享受自在烹饪乐趣。
3. 线程切换
异样产生后有很多耗时操作,如原始异样数据包装中存在读取额定字段,异样的存储,查问,加密,上报等。耗时操作都在 main isolate 中做, 势必会影响到 main isolate 的 UI 构建等行为,异样数据量比大时 UI 会有卡顿状况,就像图中状况,
Rollbar 反对将异样耗时解决操作交给子 isolate(crash isolate),让 main isolate 放弃专一做 UI 构建等以进步利用的晦涩度。
4. 追溯生成门路
该需要与第三篇 Flutter 异样监控 – 叁 | 从 bugsnag 源码学习如何追溯异样产生门路 雷同
该需要目标是能残缺记录用户操作的整个行为门路,这样达到清晰领导用户操作过程,对问题的定位很有帮忙。能够了解成一个小型的埋点零碎,只是该埋点零碎只是针对异样来做的。
区别在代码层面实现,bugsnag 中有主动增加和手动增加门路两种状况,Rollbar 中只有手动增加,然而手动增加分类更加细化,比方图中将 Breadcrumb 结构过程被分成 Breadcrumb.error、Breadcrumb.navigation、Breadcrumb.widget、Breadcrumb.log 对应不同图标事件。
话说,追溯异样生成门路需要是标配么?目前看 Bugsnag 和 Rollbar 都有实现。
二. 如何应用
- 将包增加到您的文件中:
pubspec.yaml
dependencies:
rollbar_flutter: ^0.3.0-beta
- 运行
flutter pub get
代码中配置:
import 'package:rollbar_flutter/rollbar.dart';
Future<void> main() async {
const config = Config(
//accessToken 到 https://rollbar.com/ 注册获取
accessToken: 'YOUR-ROLLBAR-ACCESSTOKEN',
package: 'rollbar_flutter_example');
await RollbarFlutter.run(config, () {runApp(const MyApp());
});
}
- 要求
- Dart SDK >= 2.7.0
- Flutter >= 1.20.0
- A Rollbar account
三. 原理解析
Rollbar 是 Flutter 异样框架,当然少不了读这类源码套路,间接拿出第三篇文章中的通用浏览门路, 依照如下流程一步步走:
<img src=”https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ff77393473e6474b9faf93273ae2fe09~tplv-k3u1fbpfcp-watermark.image?” alt=”Untitled 7.png” width=”15%” />
1. Flutter 异样监控点
- 接入端通过 RollerFlutter.run 进入到 Rollbar 外部逻辑。
重点关注 Config 中默认的四个变量: - Notifier:管制发送事件是通过主线程还是其余线程中发送。
- Transformer:对异样数据进行转换的转换器。
- Wrangler: 提供对异样数据二次包装机会返回最终发送的实在数据。
- Sender: 将 Wrangler 提供的实在数据发送。
- 通过 FlutterError.onError(21 行)和 runZonedGuarded(13 行)两个监控点逻辑解决,将异样收拢到 Rollbar.error 办法中
- 将原始异样以 Event 形式交给 Notifier.notify(15 行)。
- 通过步骤 1 中 Config 提供默认实现晓得步骤 3 中_notifier 是 IsolatedNotifier,这样下图中 (14 行) 事件最终会发送到子线程中(45 行)。
这里次要波及到 isolate 双向通信常识,不分明能够看下这个帖子 Flutte 指北 -> Isolate
- 40~43:理论拿到的是步骤 1 中传入的几个默认值,其中 telemetry 变量能够了解成数据库封装对象用来缓存异样数据的。
- 46~49:在转换 Event 之前,须要对数据库中缓存的异样进行解决,其中数据库中缓存数据有两类 1. breadcrumb 2. Event。49 会对失常 Event 进行过期判断,如果过期就删除掉。
- 51~53:这个通过默认 wrangler 获取实在数据。
- 54:sender 发送实在数据到服务器等。
至此流程图如下:
<img src=”https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8c0473a57fb949378c72a6d485300d03~tplv-k3u1fbpfcp-watermark.image?” alt=”Untitled 13.png” width=”30%” />
2. 生成异样包装类
- 10 行:Event 转换成 Data 对象,次要是增加一些除了 Error 和 StackTrack 之外信息。比方客户端信息(以后 OS 零碎,OS 版本,dart 版本,平台 CPU 内核数目等)、包名,事件等级,环境等。
- 11 行:Data 对象交给 Transformer 转换器,让开发者能够自定义本人的转换行为。
- 12 行: 返回最终实在数据 Payload。
异样数据包装流程:
3. 操作包装类
下面步骤中通过对 Event 二次封装,生成最终包装类为 Payload, 最初该类转换成字符串发送到 Rollbar 后盾。
四. 如何进行线程切换
下面剖析可知线程切换通过 Notifier 实现,线程切换思路:通过 Config 配置自定义 Notifier 值来指定异样解决运行线程,AsyncNotifier 是 main UI isolate, IsolateNotifier 会新建子线程执行异样相干操作。
Notifier 定义
abstract class Notifier {// notifier version to be updated with each new release: [todo] automate
static const version = '0.4.0-beta';
static const name = 'rollbar-dart';
Sender get sender;
Wrangler get wrangler;
Telemetry get telemetry;
FutureOr<void> notify(Event event);
FutureOr<void> dispose();}
Notifier 及子类关系图
子 isolate 解决益处
默认初始化 IsolatedNotifier.spwan 将产生一个新线程。
总结了几点益处:
- 发送事件之前 Telemetry 会做数据库相干减少,查问和删除操作,这个耗时。
- Wrangler 对象会通过 Transformer 对 Event 进行二次保障操作,这个过程也可能耗时。
- Sender.send 发送事件的时候,如果以后利用某个时间段异样频繁,在主线程也可能影响 UI。
综上将可能耗时都放到异步线程, 能够进步主线程流畅性。
五. 如何定制包装类
下面剖析可知,包装过程通过 Transformer 来实现,自定义包装类思路:通过 Config 配置自定义 Transformer 值来实现自定义解决异样数据逻辑,能够进行加密等。
Transformer 定义
abstract class Transformer {FutureOr<Data> transform(Data data, {required Event event});
}
Transformer 子类
Config 默认实现是这个,如果想自定义数据包装过程,能够复写其中 transform,对其中 date 和 event 操作。
class NoopTransformer implements Transformer {const NoopTransformer(Config _);
@override
Data transform(Data data, {required Event event}) => data;
}
六. 设计模式相干
1. 繁多职责准则
类性能形象精准,清晰的职能分工:
- Isolate 切换模块,
Notifier
子类实现。 - 转换模块:
Transformer
对象给了自定义和默认的转换形式。 - 传输模块:
Wrangler
将提供最终实在数据并传输给 sender。 - 发送模块:
Sender
子类实现,能够扩大出 httpSender 等。 - 存储模块:
Telemetry
对数据库的包装,可插入,查问 异样和异样门路对象。
2. 可插拔设计
可插拔象征更自在的性能和更开闭的设计。Rollbar 像沉积木一样,将包装,传输,发送,存储通过组合形式对立配置起来更具灵活性。
通过非空命名构造函数提供默认实现,模块间接是以组合配置,内部可设置和替换,满足开闭准则。
const Config({
this.notifier = IsolatedNotifier.spawn,
this.wrangler = DataWrangler.new,
this.transformer = NoopTransformer.new,
this.sender = PersistentHttpSender.new,
});
PS: 始终没想明确 Dart 中构造函数的多非空可选参数与构建者模式有啥不同,感觉前者齐全能够替换构建者模式的场景,哪位大佬能通知我利用场景区别?
七. 其余
思考到篇幅起因,文章剖析了次要流程,其实还有很多点值得学习和借鉴。如
- 异样存储和序列化相干逻辑。
- 多 stacktrace 解决,例如:Android 平台中的 PlatformException。
- Dart2.15 中构造函数拆分。
八. 问题及阐明
- 官网 flutter 还是 beta 版本官网创立我的项目的时候没有 flutter 我的项目图标抉择,能够不选,间接将客户端 accesstoken 拿到 example 中即可。
- 在发送过程中会报 accesstoken 的谬误,这个是因为之前 accesstoken 配置谬误的状况下记录没发送进来导致的,将利用卸载或者利用数据库删掉后,再用最新的 accesstoken 测试即可。
九. 长处和毛病
长处
- 反对发送线程切换。
- 反对 dart 层数据库保持数据。
- 反对多 stacktrace 解决,例如:Android 平台中的 PlatformException。
- 整个流程看起来比拟顺畅,组件间分工明确,且反对 config 可配置。
- 反对追溯异样门路。
毛病
- 异样追溯门路没有针对导航和网络进行主动埋点的设计都是手动埋点有些麻烦,这齐全能够借鉴 Bugsnag 来做。
- 尽管 Rollbar 官网说是纯 Dart 实现,然而它存储相干底层用了 sqlite3, 这玩意是通过通道来实现的,非纯 Dart 实现存在依赖对端原生性能的危险,是否能够思考用纯 Dart 的 hive 来替换。
十. 参考链接
Flutter 异样监控 – 叁 | 从 bugsnag 源码学习如何追溯异样产生门路 – 掘金
Releases · rollbar/rollbar-flutter
Flutter
如果感觉文章对你有帮忙,点赞、珍藏、关注、评论,一键四连反对,你的反对就是我创作最大的能源。
❤️ 本文原创 听蝉 公众号: 码里特地有禅 欢送关注原创技术文章第一工夫推送 ❤️