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://bb8650f2e5ec5ba7c67930e73a68c9@10.1.10.211:9000/6
    即協議是http,服務器地址是ip地址,這在本地開發可能沒問題,但是部署后就可能接口調不通;
    所以根據需要把http換成https,ip改成域名;如下:
    https://bb8650f2e5ec5ba7c67930e73a68c9@sentry.baidu.com/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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容