小程序 Sentry 接入

date
Apr 18, 2020
slug
mini-program-sentry
status
Published
tags
小程序
Sentry
summary
小程序官方是有提供运行时错误报警查询,但是上传时未开启 ES6 转 ES5代码压缩 是没有sourcemap的。错误上报没有上下文信息。有时甚至很难判断错误发生的页面,光看到错误报警,却很难解决问题
type
Post

背景

小程序官方是有提供运行时错误报警查询,但是上传时未开启 ES6 转 ES5代码压缩 是没有sourcemap的。错误上报没有上下文信息。有时甚至很难判断错误发生的页面,光看到错误报警,却很难解决问题
 

接入

sentry sdk选择的丁香园开源的sentry-miniapp
在小程序入口 app.tsx 配置
import * as Sentry from "sentry-miniapp"

const {
  Integrations: { GlobalHandlers }
} = Sentry

// 初始化 Sentry
Sentry.init({
  dsn: "https://[email protected]/1000061",
  integrations: [new GlobalHandlers()]
})
// 全局添加tag信息,区分小程序环境,通过tag方式,方便后期在sentry平台筛选
Sentry.setTag('env', process.env.TARO_ENV)
此时会拦截并上报所有未被catch的错误,
除了这些,我们还可以在部分逻辑中手动上报错误,从而添加更多的上下文信息,如下
// 代表临时添加额外信息
Sentry.withScope(function(scope) {
  scope.setExtra('requestUrl', requestParams.url)
  scope.setExtra('data', res)
  // 手动上报错误
  Sentry.captureException(new Error('request error'))
})
 

过滤

qq小程序上报的错误当中有非常多的底层webview执行错误,没有参考价值并且干扰查看重要的错误信息
beforeSend(event) {
  if(
    /jsEnginScriptError|webviewScriptError|Java exception|@native/g.test(event.message ? event.message : '')
  ) {
    return null
  }
  return event
},

扩展

Sentry中过滤错误的方式(减少错误噪声)
  • 将仅来自于自己代码列入白名单
    • Raven.config('your-dsn', {
          whitelistUrls: [
              'www.example.com/static/js', // your code
              'ajax.googleapis.com'        // code served from Google CDN
          ]
      }).install();
  • 入站过滤器(inbound data filters)
    • sentry项目配置中可以选择过滤错误来源(老版本浏览器,第三方扩展程序,爬虫),也可以自定义过滤指定 ip 来源的错误
  • 忽略一些无法解决的错误
    • 可以再sentry管理平台中手动忽略错误
    • 可以使用ignoreErrors。不过要注意的是,对于相同的基本错误,浏览器可能会产生不同的错误消息,需要填写合适的正则以覆盖所有情况
      • Raven.config('your-dsn', {
            ignoreErrors: [
                'Can\'t execute code from freed script',
                /SecurityError\: DOM Exception 18$/
            ]
        }).install();
  • 使用beforeSend过滤某些错误
    • Sentry.init({
        beforeSend(event) {
          // Modify the event here
          if(event.user){
            // Don't send user's email address
            delete event.user.email;
          }
          return event;
        }
      });
  • 通过merge搜索器的过滤来快速筛选错误
 
 
 
 
 
 

参考

alexayan/sentry-mina
除了 Sentry 基础的特性,还提供以下小程序相关特性 记录客户端基本信息 记录页面 request 请求 记录应用生命周期(onAppLaunch, onAppShow, onAppHide) 记录页面导航 记录小程序 api 调用 记录 console 日志 记录应用框架异常和未捕获异常 记录微信小程序 Unhandled Promise Rejection Error 记录 setTimeout, setInterval 内异常 支持小程序 LogManager 支持小程序实时日志 getRealtimeLogManager 默认环境为微信小程序,其他平台小程序可在初始化时配置特定平台环境对象 控制台报 regeneratorRuntime is not defined 错误,在开发工具上启用 增强编译 可解决 @NullYing 开发中配置 sentry.io 的 url 地址。(sentry.io 未经过 icp 备案,需自己做转发) Breadcrumbs TryCatch 捕获并记录 setTimeout, setInterval 内的异常 new sentry.Integrations.TryCatch() LogManager 将 Sentry 事件数据记录到小程序 LogManager GlobalHandlers 记录 app.onError 和 app.onPageNotFound 日志 new sentry.Integrations.GlobalHandlers() 目前小程序只支持通过 request 发送日志到服务器,由于小程序 request 有并发限制, sentry-mina 以队列的方式发送日志请求,避免过多占用请求资源。 sentry-mina 发送日志,支持失败重试,默认重试 2 次。可以通过以下方式 进行配置。 sentry-mina 会记录未发送的日志,当用户重新进入小程序,会继续发送。
alexayan/sentry-mina
如何从海量的前端报错中筛选出真正有意义的信息
报错的监控和收集一直是各个互联网企业保证线上运作的产品稳定的措施。 先暂时笼统地把错误分为前端(本文仅讨论 Web 前端)和后端的报错。在大多数情况下,后端报错发生时,可以非常精确的定位到错误的发生位置,然后进行处理。 然而前端则不然,浏览器的种类繁多,各种兼容性问题层出不穷。同时还有因为用户网络问题才导致的错误,再者,还有全国各地运营商劫持 js 脚本同时造成报错的问题发生。 除此之外,还有一些只有在无头浏览器如 phantomjs 或者其它搜索引擎爬虫如 BingPreview 才会引发的报错。 以上种种情况,造成了前端报错数量不计其数,噪音数据多,又无法分辨错误是否与代码有关,导致难以处理。本文尝试从数据分析的角度,分析并过滤百姓网前端的报错,降低噪音数据,从中找到需要关注的错误。 要进行数据分析,首先得拿到足够多的数据量。 百姓网使用 Sentry(一个开源的实时错误上报和监控工具)来收集前端的报错。由于数量庞大,目前只会存储最近15天的数据,笔者通过打 Sentry 的 API 的形式将 15 天的数据拉下来存储到本地 mongodb 数据库中,15 天算下来大概有 27000 个 event,1500 多个 issue 。 其中,每一个 issue 即一种错误,其和许多 event 构成了一种 一对多 的关系。 如图所示,Issue 本身记录了这种错误的报错信息、报错的 js 文件 url、第一次和最后一次发生时间等等信息,而 event 则存储了某一次发生的函数调用栈、浏览器型号版本、ip地址、网页 url 等等。这为我们进行数据分析提供了非常详尽的信息。 本文主要从三个角度进行报错信息的处理: 百姓网作为一个分类信息网站,用户遍布全国,但是全国的网络环境却不尽相同。事实上,有些地区运营商,会劫持一些流量大的网站的脚本,进而投放广告或用其他行为来获取利益。同时也可能造成一些正常情况下不会发生的报错。因此,第一个可以突破的点,就是过滤掉跟劫持相关的报错。 要过滤掉跟劫持相关的报错,首先是要判断出一个报错是否是跟劫持有关。鉴于劫持是地区运营商的行为,所以只要统计某个错误上报的各个地区的比例,如果某个地区占的比例特别大,就能很大程度上佐证这个错误是由于在这个地区被劫持而造成的,毕竟每个地区的代码是一样的。 正好,Sentry 存储的错误的上报数据中有 ip 地址,我们可以将 ip 地址转换为省份城市方式来统计错误地区比例。 其中 ip 到地址的转换有多种免费又不限制次数的方法,请大家自行摸索 这里有点奇怪的是,有一部分是来自美国、柬埔寨、越南、等十多个国外的地方。。。 转换结束后,首先统计了一下 所有 的 issue,按省份发生的次数排序 ↓ 可以看出, A、 B、 C 这三个省份的占比特别大,而且省份 A 的报错占比居然比访问量占比大超过一倍。然而这三个省份的用户访问量并没有占到那么多。而往后的省份都比较低,根据其省份的用户访问量一起比较,差不多是在正常的水平。 根据这个情况,可以针对每一个 issue,统计该 issue 发生的所有 events 的地区,如果某一个地区占的比例非常大,那么这个 issue 很有可能是因为被运营商劫持而造成的。而且,统计出来占比较大的省份 A 和省份 B ,正是劫持情况最严重的的地区。这符合了我们最初的猜想。 于是,A, B, C 三个省份被我们列为"黑名单",把报错中这些地区占比较大的 issue 过滤掉,打算看看剩下的报错是否是值得我们关注的问题。 值得振奋的是,报错数量大大减少,issue 的数量一下子从 1500+ 降到了 300+。 原来跟劫持有关的噪音数据有这么多吗!(比划了一下大大的手势) 等等!会不会有一些有意义的数据被我们错误地当成噪音过滤掉了? 这么说,其实是有可能的,比如说某个有缺陷的功能在某些地区使用率更高,因此在某些地区的报错占比也更高,但并不是劫持造成的。又或者还有别的原因...
如何从海量的前端报错中筛选出真正有意义的信息

© Jeekdong 2021 - 2024