概要

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 は、US1 または EU1 サイトでは 200 MB まで、それ以外のサイトでは 50 MB までのアップロードを受け付けます。

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

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"

もし build ディレクトリがまだ存在しない場合は、まず mkdir build を実行してディレクトリを作成します。その後、上記のコマンドを実行します。

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

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

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

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

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

アップロード時のオプションの受け渡し

Android で datadog-sourcemaps.gradle スクリプトを使用する

別のサービス名を指定するには、android/app/build.gradle ファイルの apply from: "../../node_modules/@datadog/mobile-react-native/datadog-sourcemaps.gradle" 行の前に、以下のコードを追加します。

project.ext.datadog = [
    serviceName: "com.my.custom.service"
]

iOS で datadog-ci react-native xcode コマンドを使用する

datadog-ci react-native xcode コマンドのオプションは、コマンドドキュメントページにあります。

クラッシュレポートの実装をテストする

ソースマップが正しく送信され、アプリケーションにリンクされていることを確認するために、react-native-performance-limiter パッケージでクラッシュを生成することができます。

yarn や npm でインストールして、ポッドを再インストールします。

yarn add react-native-performance-limiter # or npm install react-native-performance-limiter
(cd ios && pod install)

アプリから javascript のスレッドをクラッシュさせます。

import { crashJavascriptThread } from 'react-native-performance-limiter';

const crashApp = () => {
    crashJavascriptThread('custom error message');
};

新しいソースマップを送信するために、リリース用にアプリケーションを再構築し、クラッシュをトリガーし、エラー追跡ページでエラーが表示されるのを待ちます。

dSYMs と Proguard マッピングファイルのアップロードをテストするには、代わりにネイティブのメインスレッドをクラッシュさせます。

import { crashNativeMainThread } from 'react-native-performance-limiter';

const crashApp = () => {
    crashNativeMainThread('custom error message');
};

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

DATADOG_XCODE="../node_modules/.bin/datadog-ci react-native xcode"

/bin/sh -c "$DATADOG_XCODE"

このスクリプトは、すべての正しいパラメーターでソースマップをアップロードすることを担当するコマンドを実行します。詳細については、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=$DERIVED_FILE_DIR/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
export SOURCEMAP_FILE=$DERIVED_FILE_DIR/main.jsbundle.map
../node_modules/.bin/datadog-ci react-native xcode

このスクリプトは、すべての正しいパラメーターでソースマップをアップロードすることを担当するコマンドを実行します。詳細については、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 キーとして指定することも可能です。

各ビルドで手動

ソースマップを出力するためには、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 for React Native < 0.71 あり)

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

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

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

set -e
export SOURCEMAP_FILE=./build/main.jsbundle.map # <- ソースマップの出力にこの行を追加します
# React Native 0.70 では、ソースマップを生成するために USE_HERMES を true に設定する必要があります
export USE_HERMES=true

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

# 以下の行を追加して、パッケージャーとコンパイラーのソースマップを 1 つのファイルにまとめます
REACT_NATIVE_DIR=../node_modules/react-native

if [ -f "$REACT_NATIVE_DIR/scripts/find-node-for-xcode.sh" ]; then
    source "$REACT_NATIVE_DIR/scripts/find-node-for-xcode.sh"
else
    # Before RN 0.70, the script was named find-node.sh
    source "$REACT_NATIVE_DIR/scripts/find-node.sh"
fi
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 ソースマップのアップロード

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

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

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 キーとして指定することも可能です。

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

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/sourcemaps/react/release/index.android.bundle.map に配置されます。 バンドルファイルの場所は、React Native (RN) と Android Gradle Plugin (AGP) のバージョンに依存します。

  • RN >= 0.71 および AGP >= 7.4.0: android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle
  • RN >= 0.71 および AGP < 7.4.0: android/app/build/ASSETS/createBundleReleaseJsAndAssets/index.android.bundle
  • RN < 0.71: android/app/build/generated/assets/react/release/index.android.bundle

Android Gradle Plugin のバージョンは android/build.gradle ファイル内の com.android.tools.build:gradle で指定します。例: classpath("com.android.tools.build:gradle:7.3.1")

もし、アプリケーションがより包括的なバリアントを持っている場合は、パス中の release をバリアント名に置き換えてください。 android/app/build.gradle の react 構成で bundleAssetName を指定した場合は、 index.android.bundle をその値で置き換えてください。

ビルドを実行した後、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.1"
}

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()}"] }
        }

その他の参考資料