最近阅读 Catcher、BugSnag、Rollbar 三个 Flutter 异常监控开源框架,文章链接如下:
Flutter 异常监控 - 贰 | 框架 Catcher 原理分析
Flutter 异常监控 - 叁 | 从 bugsnag 源码学习如何追溯异常产生路径
Flutter 异常监控 - 肆 | Rollbar 源码赏析
这篇文章将从实现功能,优缺点,设计思想等方面做个总结,方便开发中技术选型。
罗列下认为比较重点需求,并不表示框架所有需求只有这些。
所有上述需求主要体现在异常产生到发送过程中,大致包括如下几个方面
| Catcher | Bugsnag | Rollbar | |
|---|---|---|---|
| 自定义 UI 显示异常 | 是(4 种报告模式) | 不支持 | 不支持 |
| 异常处理线程 | main isolate | 对端决定 | 子 isolate |
| 自定义包装过程 | 部分支持 | 不支持 | 支持 |
| 异常存储 | 不支持 | 对端存储 | Dart 侧存储 |
| 自定义上报处理程序 | 6 种 | 1 种(自研) | 1 种(自研) |
| 异常路径生成追溯 | 不支持 | 自动 + 手动 | 手动 |
| 是否纯 Dart 实现 | Dart | 对端+Dart | Dart |
| 对端异常处理 | 不支持 | 支持 | 部分支持 |
| 是否有自研后台 | 无 | 有 | 有 |
| 支持平台 | 全平台 | android,ios | android,ios |
如果问哪个最牛逼,我只能说:“没有不好的框架,只有乱用的人”。谁又不是个(某人心中的)宝宝呢?不同场景下谁都是自己的王者。
正确食用方式:
| 应用场景 | |
|---|---|
| Catcher | 如果对异常 UI 显示和自定义上报要求很高,且支持全平台,可以选 Catcher。 |
| Bugsnag | 如果对端各平台 SDK 有深耕和技术积累,可以参考 Bugsnag 来统一 Dart 端接口设计和自动埋点。 |
| Rollbar | 如果侧重功能可插拔,对 UI 性能要求高,重度 Dart 用户且未来需要支持全平台,可以选 Rollbar。 |
设计模式中最重要的原则是开闭原则,23 种设计模式都是以开闭原则为核心。
开闭原则:“对扩展开放,对修改关闭。” ,其中关键是识别需求中的变与不变,封装变化隔离不变。
用 Rollbar 框架举例:
拿复用代码来说,变化的是多平台及多平台中不同的网络和存储实现,不变的是各平台都需要实现这套异常网络上报和存储逻辑。隔离不变,就是将网络和存储放在 Dart 侧,封装变化,将不同平台捕获异常方式封装起来放到各自对应平台目录实现,这样就达到了复用代码目的。
这块可以看下Flutter 异常监控 - 肆 | Rollbar 源码赏析 中的代码复用分析,这里就不赘述了。
拿线程控制来说,变化的是在哪个线程,不变的是在线程中做的事情。Rollbar 中抽象 Notifier 来对线程控制,隔离不变,从 Config 中获取 Wrangler,Sender,Telemetry 来对异常事件进行操作,先存储再包装最后发送,这些是异常处理的标准流程,封装变化,将线程切换封装在 Notifier 中。
这三个开源项目,总结下来分两个流派:
有人会说,管它白猫黑猫抓到老鼠就是好猫,只要能上报后台看到结果不就 OK 了,管那么多干嘛,领导又不在乎这个。回答 Flutter 异常谁上报的实质是回答下面三个问题:
你认为 Flutter 是掌控全局(ios android ,window,web…)的大佬还是跟随其他平台的小弟?
从创建一个新的 Flutter 项目伊始 Flutter 官方就给出了答案,flutter create 命令结束,可看到 ios 和 android。。。 目录,这些目录理解成差异目录,表示同一个功能对应不同平台的实现是什么,然后将实现填充在其中。
没错 Flutter 是掌控全局的人,他定义了一套统一的 Dart 侧接口供各平台差异实现,各差异目录作用是为处理差异化功能而非因宿主已有现成功能方便桥接用。
显然,按 Flutter 是大佬的思路,站在多平台统一的上帝视角来看,Flutter 异常范围是包括其他平台异常的,比如其他平台的 OOM 等而非单纯考虑 Dart 侧异常。
用一个场景来说明问题:如果按照不同平台维度建立项目,相同项目则对应不同平台,如果按照 Flutter 来建立项目就是一个。
那么问题来了,是在安卓端和 ios 端分别建立一套数据存储异常呢,还是将不同平台异常收拢到 Flutter 平台来统一管理和上报?
显然考虑到代码复用和人力成本,大可将其他平台异常抛都给 Flutter 侧来处理和上报,存储和上报都可复用,后台也一套代码。
很多开源库喜欢将 flutter 作为小弟角色,异常都给到对端,这样导致的问题也很明显,安卓和 ios 两个后台异常系统都会出现 flutter 异常数据,默认存储两份上报两次,比如 Bugsnag,这时肯定有人会说 Bugsnag 垃圾,强依赖对端,通用性不行,复用性不行。
但我们需要看到更深层次原因:迁移成本。
软件开发本来就是一个迭代过程,是先有安卓和 ios 再有 Flutter ,人家已经在各自平台有稳定的 crash-sdk 了,推翻不用重新弄一套的行为太过激进,势必存在原来上报系统的重构和迁移,稳定性先不论,平白就增加了很多开发和测试的人力成本,不划算,直接桥接到原来功能岂不更好。
如图,人家就是每个平台都已经有 SDK 了,而且 star 上 bugsnag-android 比 bugsnag-flutter 多得多,这叫先来后到,稳。


依赖反转是不错的思路,子平台将异常收集传递给 Flutter 统一管理和上报。管理和上报本来就是各端通用能力,没必要浪费人力各端重复实现,异常的情况每个平台接口都不一样,这种差异化的 api 就应该由各个平台来实现,刚好契合 Flutter 中目录分治理念。
有点像代码设计的思路,如果是通用的代码需要提取处理作为公共使用,如果有差异部分就应该分到各个子类中取实现。lib 中负责是各个平台公共部分,存在差异的是各个平台捕获异常的 api 方式。
看需求,当前整个框架实现了哪些功能,跟自己想到的需求实现方式上有什么不同。
其次就是看不足,看不足可以对框架理解更深。如 Catcher 的局限性是它不支持异常的本地序列化断网了就发送不了,而且没自己后台,仅仅侧重于 Adapter 角色;Bugsnag 又太依赖对端,支持异常序列化断网仍可发送,但不是 Flutter 本身实现而是对端能力,Bugsnag 的扩展性相对于 Catcher 来说就差很多,包括多平台的适配上来说比不上 Catcher,但它有自己后台有盈利能力。
最后是看设计,如 Rollbar 中对类设计模块抽象精准且优美,单一原则和开闭原则做得很好。Catcher 中对 UI 显示和处理程序的开闭也做得很好,有时候看大佬们的设计思想只会觉得”编程即艺术”。
如果觉得文章对你有帮助,点赞、收藏、关注、评论,一键四连支持,你的支持就是我创作最大的动力。
❤️ 本文原创听蝉 公众号:编程黑板报 欢迎关注原创技术文章第一时间推送 ❤️
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图