Nuxt.js接入Sentry

Sentry简介

Sentry 是一个流行的错误监控平台,帮助开发者分析,修复问题,优化代码的性能。可以进行错误捕获,问题追踪,并提供问题详情,适用于多个平台,多种语言。


sentry后台

  1. sentry默认是纯英文界面,左上角用户 > User settings > Account Details 修改中文,选择Simplified Chinese 即可;一并把时区修改为东八区;修改后刷新网页即可显示中文
    提示:尽量第一次就把时区更改,否则下次再进行修改有可能一直修改失败(我就是这样)

    image.png

  2. 项目 > 右上角创建项目,选择一个平台;
    官网的Platforms选项中是没有nuxt的,所以Platforms选择vue,其实配置上是一样的,配置文件不同而已(vue.config.js/nuxt.config.js);
    3.底部信息按实际填即可,项目名字即为实际项目名, 点击创建后,会自动跳转接入文档指引

    image.png


sentry接入

  1. 安装依赖:npm install --save @sentry/vue @sentry/tracing
  2. plugins目录新增sentry插件,记得nuxt.config.js中引入该插件


    image.png
  • dsn:项目唯一标识,由 协议+秘钥+服务器地址+项目编号组成;
    当在Sentry平台新建一个项目后,Sentry会自动为该project分配一个dsn,dsn用于告诉Sentry将event发送到哪里,如果不设置dsn,Sentry也不会发送event;
    dsn遵从下面的格式{PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}{PATH}/{PROJECT_ID}
    dsn查看步骤:点进你的的项目→Settings→ 客户端密钥(DSN)
    注意:这里有个坑,我排查了好久
    一般,sentry生成的dsn是这样的:http://[email protected]:9000/6
    即协议是http,服务器地址是ip地址,这在本地开发可能没问题,但是部署后就可能接口调不通;
    所以根据需要把http换成https,ip改成域名;如下:
    https://[email protected]/6

  • environment:环境变量

详细配置参考官网configuration

  1. 写个bug测试一下
 handleTest() {
    const a = '11'
    a.forEach()
    console.log(g.f)
 },
image.png

image.png

点进去就可看到详细信息
But
压缩混淆之后的代码就导致:即使代码报错了,我们也只能看到错误信息,还是非常难定位到具体是哪行代码出现的错误,如上图;
所以我们如果要定位到问题所在还需要上传sourcemap文件。


上传sourceMap

  1. 安装SentryWebpackPlugin插件
npm install --save-dev @sentry/webpack-plugi

@sentry/webpack-plugin是针对webpack项目,如果是vite项目使用vite-plugin-sentry插件

  1. 在nuxt.config.js文件的 build 参数添加
 build: {
    extend(config, { isClient, isDev }) {
      if (isClient && !isDev) {
        config.devtool = 'source-map'
      }
    },
    plugins: [
      new SentryWebpackPlugin({
        include: '.nuxt/dist/client',
        urlPrefix: '~/home/_nuxt/', // 上传sourceMaps文件的前缀
        ignore: ['node_modules', 'webpack.config.js'],
        project: 'demo',
        configFile: process.env.VUE_APP_TITLE === 'production' ? 'sentry.properties' : 'sentry.test.properties', // 相当于.sentryclirc配置文件
        cleanArtifacts: true // 上传前清除原工件
      })
    ]
  }
  • sentry.test.properties文件
# 组织名称
defaults.org=font-end
# sentry服务器的地址
defaults.url=https://sentry.dev.test.com
# 上传sourceMaps要用到的token
auth.token=8f9ca900719b4eedea68ed82726ddcee06d2c8a105c26e8b5087069ebc7b1e
  • sentry.properties文件
# 组织名称
defaults.org=font-end
# sentry服务器的地址
defaults.url=https://sentry.test.com
# 上传sourceMaps要用到的token
auth.token=8f9ca900719b4eed8ea8ed82726ddce006d2c8a105c4268b508069ebc7b1e

以上配置都可在.sentryclirc文件中配置,sentry会自动检测并使用.sentryclirc文件中的配置信息
其中必填属性:

  • org:组织名字


    image.png
  • project:生成sentry sdk的时候建立的名字,项目面板查看

  • url:sentry的后台地址(如果是私有部署的,则是自己的地址,例https://sentry.test.com)

  • auth.token:token为API令牌,不是安全令牌;查找:左上角用户 > 用户设置 > 授权令牌;第一次需要点击右上角创建


    image.png
  • include:指定路径让sentry-cli来检测有没有.map与.js文件,如果有就会上传到sentry

非必填属性:

  • urlPrefix:上传sourceMaps文件的前缀,若不传,则默认是根目录即:/
    注意:
    填写的路径要和线上的url资源的相对路径一致
    比如:
    我的线上资源是经过nginx代理了一层,路径是:https://www.test.com/home/_nuxt/feb4126.js
    那么我此处填写的是:'~/home/_nuxt/'

  • ignore:忽略文件夹或文件不要被检测。 一般都会将node_moudules与webpack.config.js忽略掉。

  • cleanArtifacts:每次先清除已经存在的文件,再上传

  • configFile:用来替代.sentryclirc文件

tips:出现一下任何一点,都可能会出现map文件上传成功,但是报错定位依然失败的情况。

  1. 插件方法SentryWebpackPlugin中设置的release要和Sentry.init中的保持一致;也可以两个都不设置,sentry会生成哈希值,默认帮我们保持一致
  2. urlPrefix填写的路径要一定和线上的url资源的相对路径一致

还有一点:只需在生产环境(线上环境)上传sourceMap
开发环境上传sourceMap文件过于频繁,sentry会报错


ok,忙活了那么久,又到了验证的时候!

  1. 同样,写一个bug;
  2. 执行打包,上传sourceMap,验证是否上传成功:找到自己项目>点击设置>source Map,如下图


    image.png

然后去问题模块,找到错误信息,点进详情;
可以看到,已经显示了具体位置;
sourcemap上传到sentry后,sentry会通过反解sourcemap,通过行列信息映射到源文件上;


image.png

Sentry面板介绍

image.png

image.png
image.png

面包屑:还原出错误发生时,用户的关键操作路径,包括点击事件,发送请求,console log 等。 更精准的还原错误触发场景。通过全局监听console,xhr,UI等事件,SetTimeout 等方式实现

image.png

分别是错误页面,UA,用户,浏览器,设备等信息;


根据业务自定义错误详情面板

sentry 源码内有以下方法可调用:


image.png

写几个例子:

  1. 主动上报错误
    有时候sentry认为这不是一个错误,但开发者认为是,此时可以主动上报一个错误
this.$sentry.captureException(new Error('错误'));

2.captureMessage自定义上报信息
以我项目为例,我把接口错误区分出http错误(400或者500等)和接口业务报错

// http核心上报方法
export const reportCore = (opts) => {
  if (!isOpenSentry) return
  Sentry.withScope(function (scope) {
    scope.setLevel('error')
    Sentry.captureMessage(`${opts.message}—${opts.url}`, {
      contexts: {
        message: opts
      }
    })
  })
}

// 处理http错误信息
export const reportHttpInfoHandle = (error) => {
  const res = error.response || error
  return {
    title: '上报信息【HTTP】',
    url: res.config.url,
    data: res.config.data || res.config.params || '',
    method: res.config.method,
    status: res.status,
    statusText: res.statusText,
    responseData: JSON.stringify(res.data),
    message: res.message || res.data.error_msg || res.data,
    time: releaseTime(true)
  }
}

// 网络报错信息上报
export const reportHttp = (error) => reportCore(reportHttpInfoHandle(error))

// 接口业务错误信息上报
export const reportHttpBusiness = (error) => {
  const opts = {
    ...reportHttpInfoHandle(error),
    title: '上报信息【API业务错误】'
  }
  reportCore(opts)
}

// 获取当前时间
function releaseTime(flag = false) {
  const now = new Date()
  const fmt = (v) => (v < 10 ? `0${v}` : v)
  const date = `${now.getFullYear()}-${fmt(now.getMonth() + 1)}-${fmt(now.getDate())}`
  if (!flag) return date
  const time = `${fmt(now.getHours())}:${fmt(now.getMinutes())}:${fmt(now.getSeconds())}`
  return `${date} ${time}`
}

上报后的效果

image.png

3.setLevel 为上报事件设置级别;可用的值有: fatal/critical/error/warning/log/info/debug/
每一个上报事件都有级别,默认是info,颜色是蓝色;如下图
image.png

为了让它看上去更重要,更醒目,可以通过setLevel更改,提醒色就会变成更醒目的橘黄色,如下图
image.png

// http核心上报方法
export const reportCore = (opts) => {
  if (!isOpenSentry) return
  Sentry.withScope(function (scope) {
    scope.setLevel('error')
    Sentry.captureMessage(`${opts.message}—${opts.url}`, {
      contexts: {
        message: opts
      }
    })
  })
}
  1. 为错误信息增加’面包屑‘
    breadCrumbs里还原了错误发生时用户的关键操作路径,包括点击事件,xhr等,还有 Expection等,这里可以丰富breadCrumbs
Sentry.addBreadcrumb({
  message: '自定义信息',
  // ...
});
  1. 设置用户信息
 Sentry.configureScope((scope) => {
      scope.setUser({
        user_account: '110',
        user_name: '章三',
        user_mobile: '110'
      })
      Sentry.captureException(err)
    })

效果:


image.png

上面的写法会把用户信息放置在 User 栏里,如果也想让tag里有,则可:

Sentry.configureScope((scope) => {
      scope.setTag('user_account', '110')
      scope.setTag('user_name', '章三')
      scope.setTag('user_mobile', '110')
      Sentry.captureException(err)
    })

效果:


image.png

你可能感兴趣的:(Nuxt.js接入Sentry)