iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0
自我挑戰組

React Native 奇幻之旅系列 第 25

【DAY25】React Native 使用 Sentry 監控錯誤、異常和性能

  • 分享至 

  • xImage
  •  

https://sentry.io/

Sentry 是一個用於應用程式錯誤監控和追蹤的工具,可以很方便的捕獲應用中發生的錯誤並定位錯誤發生的檔案、程式碼,並且有現成的庫可以在 React Native 中使用所以設置起來也不會太困難。

前置準備

需要準備以下資料:

  • Sentry URL
  • Sentry DSN
  • ORG Slug
  • Project Name
  • User Auth Token

Sentry DSN

Create Team

Create Project,選擇 REACT NATIVE 輸入 Project name 和 Team

這邊有設置步驟,還有直接將 DSN 寫在裡面了,可以先保存起來:

如果忘記保存,在 Project - Settings - Client Keys(DSN) 也能找到:

ORG Slug

ORG Slug 在 Organization - Settings - Organization Slug

Project Name

Project Name 在 Project - Settings - Name

User Auth Token

生成 User Auth Token

React Native CLI 使用 Sentry

安裝、設置直接使用這個指令一鍵完成:

npx @sentry/wizard@latest -s -i reactNative

它會幫你安裝 @sentry/react-native 並且生成 sentry.properties 到 android, ios 底下

在 App.js 用 Sentry.wrap(App) 就可以自動捕獲應用中的錯誤:

const App = () => {
    // ...
}

export default Sentry.wrap(App);

和 React navigation 一起用

Sentry 提供了 ReactNavigationInstrumentation 的 API,當路由變化時就會建立一個 transaction,以監控導航操作的效能和錯誤:

import React, { useRef, Ref } from 'react'
import { NavigationContainer, NavigationContainerRef } from '@react-navigation/native'
import * as Sentry from '@sentry/react-native'
import { RootStackParamList } from '@/_types_'

const routingInstrumentation = new Sentry.ReactNavigationInstrumentation()

Sentry.init({
  // ...
  integrations: [
    new Sentry.ReactNativeTracing({
      routingInstrumentation
    })
  ]
})

function App(): JSX.Element {
  const navigation = useRef<NavigationContainerRef<RootStackParamList>>(null)

  return (
    <NavigationContainer
      ref={navigation}
      onReady={() => routingInstrumentation.registerNavigationContainer(navigation)}
    >
      // ...
    </NavigationContainer>
  )
}

export default Sentry.wrap(App)

集成 Source Map

https://docs.sentry.io/platforms/react-native/sourcemaps/

集成 source map 可以定位錯誤到具體的程式碼,如果沒有上傳 source map,會定位到的是壓縮後的程式碼。

生成 Map 檔案

在根目錄執行以下指令(如果 main 檔案不是 index.js 記得改掉)

Android

npx react-native bundle --platform android --dev false --entry-file index.js --reset-cache --bundle-output index.android.bundle --sourcemap-output index.android.bundle.packager.map --minify false

iOS

npx react-native bundle --platform ios --dev false --entry-file index.js --reset-cache --bundle-output main.jsbundle --sourcemap-output main.jsbundle.map --minify false

執行完畢後根目錄底下會新增 index.android.bundle, index.android.bundle.packager.map, main.jsbundle, main.jsbundle.map

上傳 Source Map

  1. 設置 SENTRY 相關變數
    Sentry默認加載 .env 所以在 .env 設置 SENTRY_PROPERTIES 路徑可以讓 sentry-cli 讀取到你的 sentry 變數,設置完後使用 sentry-cli info 確認變數是否設置成功
    // .env
    SENTRY_PROPERTIES=./ios/sentry.properties
    
  2. 上傳 Source Map
    • release: package@versionName+versionCode, 如:com.test.pokedex@1.0+1
    • dist: source map 版本, 每次上傳時+1
    sentry-cli releases \
    files <release> \
    upload-sourcemaps \
    --dist <dist> \
    index.android.bundle index.android.bundle.packager.map main.jsbundle main.jsbundle.map
    
    範例:
    sentry-cli releases \
    files com.test.pokedex@1.0+1 \
    upload-sourcemaps \
    --dist 1 \
    index.android.bundle index.android.bundle.packager.map main.jsbundle main.jsbundle.map
    
  3. 在 Sentry.init 添加 release, dist
    • dist 是字串不是數字
    Sentry.init({
      dsn: 'xxxxxx',
      release: 'com.test.pokedex@1.0+1',
      dist: '1',
      //...
    })
    

嘗試捕獲第一個 Error

以上都設置完成後,在 App.js 丟出第一個 Error 試試看 Sentry 能不能補捉得到:

// App.js
useEffect(() => {
  throw new Error("My first Sentry error!");
}, [])

Sentry 不僅抓到了錯誤,還可以看到錯誤的程式碼所在位置,debug 起來更方便了:

Expo 使用 Sentry

在 Expo 使用 Sentry 就比較簡單了,只需要做一些基礎設置。

安裝 sentry-expo 和依賴

npx expo install sentry-expo
npx expo install expo-application expo-constants expo-device @sentry/react-native

在 app.json plugins 中添加 sentry-expo

"plugins": [
  "sentry-expo"
  // ...
]

App.js

  • 設置 Sentry DSN
  • export default App 改為 export default Sentry.Native.wrap(App)
import React from 'react'
import * as Sentry from 'sentry-expo'

Sentry.init({
  dsn: process.env.SENTRY_DSN,
})

const App = () => {
  return (
    // ...
  );
}

export default Sentry.Native.wrap(App)

將 User Auth Token 添加到 Expo 的 Project secrets

名稱必須為 SENTRY_AUTH_TOKEN

也可以使用指令直接新增 eas secret:create --scope project --name SENTRY_AUTH_TOKEN --value <SENTRY_AUTH_TOKEN> --type string

Source map

app.json 或者 app.config.js 中添加 hooks.postPublish

  • organization 是 Sentry ORG Slug
  • project 則是 Sentry Project Name
{
  "expo": {
    "hooks": {
      "postPublish": [
        {
          "file": "sentry-expo/upload-sourcemaps",
          "config": {
            "organization": "sentry org slug, or use the `SENTRY_ORG` environment variable",
            "project": "sentry project name, or use the `SENTRY_PROJECT` environment variable"
          }
        }
      ]
    }
    // ...
  }
}

設置好後 Expo 會自動在 eas build 的時候上傳 source map,release 和 dist 都會按照格式自動設置,所以並不需要再做額外的設置。

查東西的時候看見了這篇文章,很詳細的解說了 Sentry 的各種使用方式,有興趣可以看一下:Sentry-CLI 使用详解(2021 Sentry v21.8.x)

參考資料


上一篇
【DAY24】React Native Debugging 基本的調試工具和方法
下一篇
【DAY26】EXPO + Github Action 自動化構建 React Native 應用
系列文
React Native 奇幻之旅31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言