tl;dr:
你需要收集错误
我最近的工作生活中让我认识到一个道理: 我们都需要承认自己很菜。 我们以为科技发达了,产生了一种一切尽在掌握中的错觉。然后一次疫情冲击完全摧毁这种自信。我们以为我们很厉害,代码不会出 bug,但事实上你晚上睡觉都不踏实,感觉有个 case 写得有问题,但是好像又没问题。终有一天,会有个用户指着鼻子骂你说提现不成功的 bug 都两个月了你们都不知道修。
有时候,我们是会产生一种一切尽在掌握中的错觉,我是最厉害的,我的代码不可能有 bug。实际上它们大多数情况下都是错觉。😶
最近读 GFS 的论文更印证了没什么是稳定的,也没有什么是可以信任的。他们的思路是:宕机是常事,快速重启恢复就行。
如果读到这里,作为读者的你仍然觉得自己可以掌控一切,靠领导的压迫力就能让代码没有 bug,靠给三倍工资就能让你的后端可用性达到 100%。 那么亲爱的你可能没必要看下去了。
我们都承认自己很菜,都承认自己会犯错,都承认自己没办法掌控一切。我们需要思考,面对这沮丧的现实,应该怎么做: 一个工程师应有的尊严应该是让用户毫无感知地使用产品。
所以你需要 监控, 报警,容灾,备份,异地多活,熔断降级 等等等等
这篇文章只讨论第一个问题:监控。
应用报错
我个人非常欣赏 Erlang 的一个哲学 crash early, crash fast。crash 的意义在于没有下次同样原因的 crash。绝大多数时候我们写的代码仍旧会有不在预期内的错误。整数除以 0 了,硬盘挂了,电缆被挖断了。我们需要知道为什么 crash 才能避免下次有同样的 crash。
一方面是 unit test 要写得很足。另一方面是报错应该收集起来,加以分析,查找。
sentry 是我用过的最多的平台,而且个人的免费版本完全够用,甚至也可以自己部署。它提供了多平台的 sdk 可以很方便地接入到现有的项目中。
比如有个 js 调用了 undefined method,sentry js sdk 会收集上下文信息,前后调用栈,上传到后台。在后台就能看到这个报错信息。如果上传了 sourcemap 甚至能直接对应到源码。非常方便。大部分 bug 都能很快找到思路。
小程序客户端
sentry 很好,用得简单,查起来方便。只是有个问题,它没有移动客户端。春节在家的时候,我摊在客厅等 ps4 启动的过程中想顺手看一下有没有新的 bug 报出来,竟然要去卧室拿电脑出来,打开网页才能看。完全没有效率。
所以在玩 送快递(死亡搁浅) 之余,我自己顺手为 sentry 开发了一个小程序客户端。
简单看了一下 sentry 的 api 文档,分页上路子有点儿野,看得出是不想在 body 中添加分页信息,所以通过 string 的形式挂到了 header 上,其他的倒也非常正规。基本的 restful 接口设计。看了没多久就开始写代码。
由于我之前一年多时间都在写小程序和 react, 当时也新出了一款基于 react-reconciler 做的 remax 看起来挺不错,就开始开发了,数据管理上沿用了我非常偏爱的 redux & redux-saga。
整个项目结构非常简单,主要的页面只有三个,分别是 landing
, list
, detail
。首先是 landing 页面承载所有的外部请求进入,做转发。之所以设计一个 landing 页是因为小程序和 web 不太一样。没办法做统一的路由上的数据管理。比如登陆,势必要在每个页面都挂一个鉴权的 hook 才能达到鉴权的效果,否则要么就是没有上下文,要么拿不到计算的状态,很麻烦。而且小程序跳转的二维码有众多限制。单入口的 landing page 做各种初始化会比较省力。
剩下的就是错误列表以及错误详情页面了。比较简单。
界面样式请看顶部的视频。