一. 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
如果感觉文章对你有帮忙,点赞、珍藏、关注、评论,一键四连反对,你的反对就是我创作最大的能源。
❤️ 本文原创听蝉 公众号:码里特地有禅 欢送关注原创技术文章第一工夫推送 ❤️