React Native のクラッシュレポートとエラー追跡

概要

React Native のクラッシュレポートとエラー追跡を有効にすると、リアルユーザーモニタリングで包括的なクラッシュレポートとエラートレンドを取得できます。この機能により、以下にアクセスが可能になります。

  • 集計済みの React Native クラッシュダッシュボードおよび属性
  • 記号化された React Native (JavaScript およびネイティブの iOS または Android) のクラッシュレポート
  • React Native のエラー追跡によるトレンド分析

スタックトレースを記号化するために、マッピングファイルを Datadog に手動でアップロードしてください。

クラッシュレポートは Error Tracking に表示されます。

セットアップ

まだ RUM React Native SDK をインストールしていない場合は、アプリ内セットアップ手順に従うか、React Native RUM セットアップドキュメントを参照してください。

クラッシュレポートの追加

初期化スニペットを更新して、ネイティブ JavaScript のクラッシュレポートを有効にします。

const config = new DdSdkReactNativeConfiguration(
    '<CLIENT_TOKEN>',
    '<ENVIRONMENT_NAME>',
    '<RUM_APPLICATION_ID>',
    true,
    true,
    true // javascript のクラッシュレポートを有効にする
);
config.nativeCrashReportEnabled = true; // enable native crash reporting

制限

Datadog は、50MB までのアップロードを受け付けます。

ソースマップとバンドルのサイズを計算するには、次のコマンドを実行します。

npx react-native bundle \
  --dev false \
  --platform ios \
  --entry-file index.js \
  --bundle-output build/main.jsbundle \
  --sourcemap-output build/main.jsbundle.map

sourcemapsize=$(wc -c build/main.jsbundle.map | awk '{print $1}')
bundlesize=$(wc -c build/main.jsbundle | awk '{print $1}')
payloadsize=$(($sourcemapsize + $bundlesize))

echo "Size of source maps and bundle is $(($payloadsize / 1000000))MB"

クラッシュレポートのシンボル化

アプリケーションのサイズを小さくするために、リリース用にビルドされる際に、そのコードは最小化されます。エラーを実際のコードにリンクするために、以下のシンボル化ファイルをアップロードする必要があります。

  • iOS の JavaScript バンドル用の JavaScript ソースマップ
  • Android の JavaScript バンドル用の JavaScript ソースマップ
  • iOS ネイティブコード用の dSYM
  • Android ネイティブコードのコード難読化を有効にしている場合、Proguard マッピングファイル

シンボル化されたファイルを自動的に送信するようにプロジェクトを設定するには、npx datadog-react-native-wizard を実行します。

オプションについては、ウィザード公式ドキュメントを参照してください。

datadog-react-native-wizard の代替となるもの

datadog-react-native-wizard を使ってもうまくいかない場合、あるいはリリースごとにシンボル化ファイルを自動的にアップロードしたくない場合は、次のステップに従ってクラッシュレポートをシンボル化してください。

iOS ビルドにおける JavaScript ソースマップのアップロード

プロジェクトに @datadog/datadog-ci を開発依存としてインストールする必要があります。

yarn add -D @datadog/datadog-ci

npm install --save-dev @datadog/datadog-ci

各リリースビルドで自動的に (React Native >= 0.69)

リリースビルドのたびにソースマップを手動でアップロードするのは時間がかかり、エラーも起こりがちです。Datadog は、リリースビルドを実行するたびにソースマップを自動的に送信することを推奨します。

プロジェクトのルートに datadog-sourcemaps.sh という名前のスクリプトファイルを作成し、以下の内容を記述します。

#!/bin/sh
set -e

# XCode からビルドを実行する場合、yarn を使用することはできません。
# どの Yarn の実行ファイルが適切かをまず確認します
package_manager_test_command="bin" # `yarn bin` と `npm bin` の両方が有効なコマンドです
test_and_set_package_manager_bin()
{
  $(echo $1 $package_manager_test_command) && export PACKAGE_MANAGER_BIN=$1
}

test_and_set_package_manager_bin "yarn" || # npm を使用している場合は yarn を npm で置き換えます
test_and_set_package_manager_bin "/opt/homebrew/bin/node /opt/homebrew/bin/yarn" || # npm を使用している場合は yarn を npm で置き換えます
echo "package manager not found"

REACT_NATIVE_XCODE="node_modules/react-native/scripts/react-native-xcode.sh"
DATADOG_XCODE="$(echo $PACKAGE_MANAGER_BIN) datadog-ci react-native xcode"

/bin/sh -c "$DATADOG_XCODE $REACT_NATIVE_XCODE"

このスクリプトは yarn datadog-ci react-native xcode コマンドを実行するのに最適な方法を見つけます。

  • fastlane のようなツールや、BitriseAppCenter のようなサービスを使ってアプリを構築する場合、yarn を使用することができます
  • XCode から直接リリースビルドを実行する場合、Mac では /opt/homebrew/bin/node /opt/homebrew/bin/yarn を使用する必要があります

これは、すべての正しいパラメーターでソースマップをアップロードすることを世話するこのコマンドを実行します。詳細については、datadog-ci のドキュメントを参照してください。

XCode で .xcworkspace を開き、プロジェクト > Build Phases > Bundle React Native code and images を選択します。スクリプトを以下のように編集します。

set -e
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
# 以下の 2 行を追加します
REACT_NATIVE_XCODE="./datadog-sourcemaps.sh"
export SOURCEMAP_FILE=./main.jsbundle.map

# 次の行を編集します
/bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE"

アップロードを動作させるためには、Datadog API キーを指定する必要があります。コマンドラインツールや外部サービスを利用する場合は、環境変数 DATADOG_API_KEY として指定します。XCode からビルドを実行する場合は、API キーを含む datadog-ci.json ファイルをプロジェクトのルートに作成します。

{
    "apiKey": "<YOUR_DATADOG_API_KEY>"
}

また、Datadog のサイト (datadoghq.eu など) を環境変数 DATADOG_SITE や、datadog-ci.json ファイルに datadogSite キーとして指定することも可能です。

各リリースビルドで自動的に (React Native < 0.69)

XCode で .xcworkspace を開き、プロジェクト > Build Phases > Bundle React Native code and images を選択します。スクリプトを以下のように編集します。

set -e

export NODE_BINARY=node
# XCode からビルドを実行する場合、${this.packageManager} を使用することはできません。
# したがって、まずどの ${this.packageManager} コマンドが適切かを確認する必要があります
package_manager_test_command="bin" # `yarn bin` と `npm bin` の両方が有効なコマンドです
test_and_set_package_manager_bin()
{
  $(echo $1 $package_manager_test_command) && export PACKAGE_MANAGER_BIN=$1
}

test_and_set_package_manager_bin "yarn" || # npm を使用している場合は yarn を npm で置き換えます
test_and_set_package_manager_bin "/opt/homebrew/bin/node /opt/homebrew/bin/yarn" || # npm を使用している場合は yarn を npm で置き換えます
echo "package manager not found"

export SOURCEMAP_FILE=./build/main.jsbundle.map
$(echo $PACKAGE_MANAGER_BIN datadog-ci react-native xcode)

このスクリプトは yarn datadog-ci react-native xcode コマンドを実行するのに最適な方法を見つけます。

  • fastlane のようなツールや、BitriseAppCenter のようなサービスを使ってアプリを構築する場合、yarn を使用することができます
  • XCode から直接リリースビルドを実行する場合、Mac では /opt/homebrew/bin/node /opt/homebrew/bin/yarn を使用する必要があります

これは、すべての正しいパラメーターでソースマップをアップロードすることを世話するこのコマンドを実行します。詳細については、datadog-ci のドキュメントを参照してください。

アップロードを動作させるためには、Datadog API キーを指定する必要があります。コマンドラインツールや外部サービスを利用する場合は、環境変数 DATADOG_API_KEY として指定します。XCode からビルドを実行する場合は、API キーを含む datadog-ci.json ファイルをプロジェクトのルートに作成します。

{
    "apiKey": "<YOUR_DATADOG_API_KEY>"
}

また、Datadog のサイト (datadoghq.eu など) を環境変数 DATADOG_SITE や、datadog-ci.json ファイルに datadogSite キーとして指定することも可能です。

各ビルドで手動 (Hermes なし)

ソースマップを出力するためには、XCode のビルドフェーズ “Bundle React Native Code and Images” を編集する必要があります。

  1. XCode で ios/YourAppName.xcworkspace ファイルを開きます。
  2. 左側のパネルで、”File” アイコンを選択し、プロジェクトをクリックします。
  3. 中央のパネルで、上のバーから “Build Phases” を選択します。

set -e の行の後にこれを追加して、スクリプトを変更します。

set -e
export SOURCEMAP_FILE=./build/main.jsbundle.map # <- ソースマップの出力にこの行を追加します
# スクリプトの残りを変更せずにおきます

今後、すべての iOS ビルドで、バンドル用のソースマップを見つけることができます。

XCode からバンドルファイルのパスを見つけるには、XCode の Report Navigator を表示し、BUNDLE_FILE でフィルターをかけてその場所を確認します。

通常の場所は ~/Library/Developer/Xcode/DerivedData/YourAppName-verylonghash/Build/Intermediates.noindex/ArchiveIntermediates/YourAppName/BuildProductsPath/Release-iphoneos/main.jsbundle で、YourAppName はアプリ名で verylonghash は 28 文字のハッシュです。

ソースマップをアップロードするには、React Native プロジェクトからこれを実行します。

export DATADOG_API_KEY= # API キーを入力します
export SERVICE=com.myapp # サービス名で置き換えます
export VERSION=1.0.0 # XCode のアプリのバージョンで置き換えます
export BUILD=100 # XCode のアプリのビルドで置き換えます
export BUNDLE_PATH= # バンドルパスを入力します

yarn datadog-ci react-native upload --platform ios --service $SERVICE --bundle $BUNDLE_PATH --sourcemap ./build/main.jsbundle.map --release-version $VERSION --build-version $BUILD

各ビルドで手動 (Hermes あり)

現在、React Native で Hermes を使用した場合、不正なソースマップが生成されるバグがあります。

これを解決するには、正しいソースマップファイルを生成するために、ビルドフェーズの一番最後に行を追加する必要があります。

ビルドフェーズをこのように編集します。

set -e
export SOURCEMAP_FILE=./build/main.jsbundle.map # <- ソースマップの出力にこの行を追加します

# スクリプトの残りを変更せずにおきます

# 以下の行を追加して、パッケージャーとコンパイラーのソースマップを 1 つのファイルにまとめます
REACT_NATIVE_DIR=../node_modules/react-native
source "$REACT_NATIVE_DIR/scripts/find-node.sh"
source "$REACT_NATIVE_DIR/scripts/node-binary.sh"
"$NODE_BINARY" "$REACT_NATIVE_DIR/scripts/compose-source-maps.js" "$CONFIGURATION_BUILD_DIR/main.jsbundle.map" "$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/main.jsbundle.map" -o "../$SOURCEMAP_FILE"

ソースマップをアップロードするには、React Native プロジェクトルートからこれを実行します。

export DATADOG_API_KEY= # API キーを入力します
export SERVICE=com.myapp # サービス名で置き換えます
export VERSION=1.0.0 # XCode のアプリのバージョンで置き換えます
export BUILD=100 # XCode のアプリのビルドで置き換えます
export BUNDLE_PATH= # バンドルパスを入力します

yarn datadog-ci react-native upload --platform ios --service $SERVICE --bundle $BUNDLE_PATH --sourcemap ./build/main.jsbundle.map --release-version $VERSION --build-version $BUILD

Android ビルドにおける JavaScript ソースマップのアップロード

各リリースビルドで自動的に

android/app/build.gradle ファイルで、apply from: "../../node_modules/react-native/react.gradle" 行の後に、以下を追加します。

apply from: "../../node_modules/@datadog/mobile-react-native/datadog-sourcemaps.gradle"

アップロードを動作させるためには、Datadog API キーを指定する必要があります。環境変数 DATADOG_API_KEY として指定するか、API キーを含む datadog-ci.json ファイルをプロジェクトのルートに作成します。

{
    "apiKey": "<YOUR_DATADOG_API_KEY>"
}

また、Datadog のサイト (datadoghq.eu など) を環境変数 DATADOG_SITE や、datadog-ci.json ファイルに datadogSite キーとして指定することも可能です。

各ビルドで手動

Android では、バンドルファイルは android/app/build/generated/assets/react/release/index.android.bundle に、ソースマップファイルは android/app/build/generated/sourcemaps/react/release/index.android.bundle.map に配置されます。アプリケーションにもっと包括的なバリアントがある場合は、パスの release をバリアント名で置き換えてください。

ビルドを実行した後、React Native プロジェクトのルートからこのコマンドを実行して、ソースマップをアップロードします。

export DATADOG_API_KEY= # API キーを入力します
export SERVICE=com.myapp # サービス名で置き換えます
export VERSION=1.0.0 # android/app/build.gradle の versionName に置き換えます
export BUILD=100 # android/app/build.gradle の versionCode に置き換えます
export BUNDLE_PATH=android/app/build/generated/assets/react/release/index.android.bundle
export SOURCEMAP_PATH=android/app/build/generated/sourcemaps/react/release/index.android.bundle.map

yarn datadog-ci react-native upload --platform android --service $SERVICE --bundle $BUNDLE_PATH --sourcemap $SOURCEMAP_PATH --release-version $VERSION --build-version $BUILD

iOS dSYM ファイルのアップロード

各ビルドで手動

詳しくは、iOS のクラッシュレポートとエラー追跡のドキュメントをご覧ください。

Android Proguard のマッピングファイルのアップロード

まず、プロジェクトで Proguard のミニフィケーションが有効になっていることを確認します。デフォルトでは、React Native のプロジェクトでは有効になっていません。

詳しくは、React Native Proguard のドキュメントをご覧ください。

それでもわからない場合は、(cd android && ./gradlew tasks --all) | grep minifyReleaseWithR8 を実行すると、何か返ってくるかどうか確認します。返ってくる場合、ミニフィケーションが有効になっています。

各ビルドで手動

android/app/build.gradle ファイルで、プラグインを追加し、ファイルの一番上でこれを構成します。

plugins {
    id("com.datadoghq.dd-sdk-android-gradle-plugin") version "1.5.0"
}

datadog {
    checkProjectDependencies = "none" // これは、React Native プロジェクトでは、どんな場合でも必要です。
}

アップロードを動作させるためには、Datadog API キーを指定する必要があります。環境変数 DATADOG_API_KEY として指定するか、API キーを含む datadog-ci.json ファイルをプロジェクトのルートに作成します。

{
    "apiKey": "<YOUR_DATADOG_API_KEY>"
}

また、Datadog のサイト (datadoghq.eu など) を環境変数 DATADOG_SITE や、datadog-ci.json ファイルに datadogSite キーとして指定することも可能です。 詳しくは、Datadog Android SDK Gradle プラグインをご覧ください。

ビルド後にプラグインを実行するには、(cd android && ./gradlew app:uploadMappingRelease) を実行します。

ビルドごとにアップロードを自動化

前のステップと同様に、プラグインをインストールします。

android/app/build.gradle ファイルから、applicationVariants のループを探します。applicationVariants.all { variant -> のような形になるはずです。

ループの中に、以下のスニペットを追加します。

        if (project.tasks.findByName("minify${variant.name.capitalize()}WithR8")) {
            tasks["minify${variant.name.capitalize()}WithR8"].finalizedBy { tasks["uploadMapping${variant.name.capitalize()}"] }
        }

クラッシュレポートの検証

React Native のクラッシュレポートとエラー追跡の構成を確認するには、react-native-crash-tester のようなパッケージをインストールすると、ネイティブ側または JavaScript 側からアプリをクラッシュさせることが可能です。

その他の参考資料