New Relic でモバイルアプリケーション（React Native）のオブザーバリティを実現!

# はじめに
　React Native はクロスプラットフォームアプリの効率的な開発を可能にします。Expoはこのプラットフォームをさらに簡素化し、開発者がネイティブコードを書かずにiOS、Android、およびWebアプリを同時に開発・テスト・デプロイできるオープンソースのツールです。
 
　しかし、特定の外部ライブラリやカスタムネイティブモジュールを利用する際には、追加の設定が必要になることがあります。New Relic エージェントのインストールもその一例です。New Relicは、アプリケーションのパフォーマンスをリアルタイムでモニタリングし、問題を迅速に特定し解決するのに役立ちます。

　　このブログでは、Expo で構築した React Native アプリケーションに New Relic エージェントをインストールし、設定するための具体的な手順を分かりやすく解説します。開発者がモバイルアプリのモニタリングを簡単に設定できるよう、必要な手順を明確に説明することを目指しています。
  
:::note info
最新のアップデートの詳細はこちら
[New Relic アップデート一覧
](https://newrelic.com/jp/blog/nerdlog/new-relic-update  "New Relic アップデート一覧")
:::

:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::

# 今回のポイント
この記事で紹介しているポイントは、次の3つです。

**1\. Expo で構築した React Native アプリケーションに New Relic を導入する手順を公開**
　Expoで構築したアプリケーションにNew Relicエージェントをインストールする方法を解説します。New Relicでは「Add data」のガイドに従って設定しますが、Expoの場合、手順と必要な設定が異なります。これについて公式ドキュメントは設定の詳細を完全には解説していません。

https://docs.newrelic.com/jp/docs/mobile-monitoring/new-relic-monitoring-react-native/monitor-your-react-native-application/#optional-expo-integration
 
**2\. シミュレーターで起動して New Relic エージェントの動作を確認**
　Expo で構築したアプリケーションは、 Expo Go を使って動作確認が可能ですが、New Relic の計装には対応していません。どうやって動作確認を行うのか、私が実施した例を紹介します。
 
**3\. New Relic の UI 上で収集したモバイルアプリケーションのデータを確認**
　New Relic のエージェントを使って収集したモバイルアプリのデータの確認方法を紹介します。アプリの起動回数やアプリとバックエンドのサービスや使用している外部サービスの状況等を確認できます。
 
# New Relic Mobile のセットアップ
## 前提条件
* **Node.js**: 最新のLTSバージョンをインストール
* **Expo CLI**: コマンドラインから npm install -g expo-cli でインストール
* **Expoアカウント**: Expoの公式サイトでアカウントを作成
* **Managed workflow**: Expo は、Managed Workflow と Bare Workflowが選択できますが、今回はManaged Workflowを使用します
* **シミュレーターを使ってアプリの動作確認ができる状態であること**

## New Relic React Native エージェントのセットアップ
**1\. newrelic-react-native-agent パッケージのインストール**
下記のコマンドを使用して newrelic-react-native-agent パッケージをインストールします。
```console: newrelic-react-native-agent パッケージ
npx expo install newrelic-react-native-agent
```
**2\. プラグインに newrelic-react-native-agent パッケージが設定されていることを確認**
 ``app.json`` か ``app.config.js`` のいずれかのファイルに下記の設定が追加されていることを確認してください。
 私の環境では ``app.json`` を使用しています。
 ```json: app.json
  {
   "name": "my app",
   "plugins": ["newrelic-react-native-agent"]
 }
 ```
 並べて記載していますが、開発しているアプリケーションに導入するため、記載された箇所が離れているケースの方が多いです。並べる必要はないため、それぞれの項目が設定されていれば問題ありません。

## エージェントの初期化と設定
**3\. New Relic の AppToken の取得**
New Relic のUI上でReact Native エージェントのセットアップで使用する AppToken を取得します。
**[Add Data]から Mobile の React Native を選択します。**
![Add_Data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/53df38e7-67ae-2f95-d1ca-7f659701cfc6.png)

**アプリケーション名を入力して [Create] を押して作成します。その後、[Continue] を押して次の手順に進みます。**
![appname.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/021e5844-0978-55be-27f2-6feeb586989c.png)

この手順を終えると New Relic の UI 上に設定した名前のエンティティが表示されます。
![一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/5ba4c36f-c924-1b37-8928-e827edea8865.png)


作成したアプリの AppToken を確認するためにセットアップの手順を[React Native setup]まで進めましょう。

**AppToken を確認する**
エージェントの初期化時に設定する AppToken を確認します。セットアップのガイドの中だと下記の画面で確認が可能です。
![AppToken_adddata.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/d402dce9-a64b-51aa-a742-e88628a85e79.png)

また、設定したiOS と Android のそれぞれのアプリケーションの画面で確認することも可能です。
[SETTINGS] の [Application] に表示される Application Token です。 
![Apptoken.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/be7cb7a4-681f-8728-7f2e-0f22490ae6f8.png)


**4\. 初期化のコードを追加**
下記のコードを``index.js``に追加してください。初期化のタイミングはアプリのロードが終わったタイミングにしましょう。早すぎると依存関係の問題でエラーになります。

```js: index.js
// New RelicのReact Nativeエージェントをインポート
import NewRelic from 'newrelic-react-native-agent';
// アプリケーションの名前とバージョン情報をpackage.jsonからインポート
import {name, version} from './package.json';
// React NativeのPlatformとAppRegistryモジュールをインポート
import {Platform, AppRegistry} from 'react-native';

// OSごとに異なるAppTokenを設定する
let appToken;
if (Platform.OS === 'ios') {
    // iOS用のNew Relic AppToken
    appToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-NRMA';
} else {
    // Android用のNew Relic AppToken
    appToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-NRMA';
}

// New Relicエージェントの設定オプション
const agentConfiguration = {

    //Android Specific
    // Optional:Enable or disable collection of event data.
    analyticsEventEnabled: true,
    // Optional:Enable or disable crash reporting.
    crashReportingEnabled: true,
    // Optional:Enable or disable interaction tracing. Trace instrumentation still occurs, but no traces are harvested. This will disable default and custom interactions.
    interactionTracingEnabled: true,
    // Optional:Enable or disable reporting successful HTTP requests to the MobileRequest event type.
    networkRequestEnabled: true,
    // Optional:Enable or disable reporting network and HTTP request errors to the MobileRequestError event type.
    networkErrorRequestEnabled: true,
    // Optional:Enable or disable capture of HTTP response bodies for HTTP error traces, and MobileRequestError events.
    httpRequestBodyCaptureEnabled: true,
   // Optional:Enable or disable agent logging.
    loggingEnabled: true,
    // Optional:Specifies the log level. Omit this field for the default log level.
    // Options include: ERROR (least verbose), WARNING, INFO, VERBOSE, AUDIT (most verbose).
    logLevel: NewRelic.LogLevel.INFO,
    // iOS Specific
    // Optional:Enable/Disable automatic instrumentation of WebViews
    webViewInstrumentation: true,
    // Optional:Set a specific collector address for sending data. Omit this field for default address.
    // collectorAddress: "",
    // Optional:Set a specific crash collector address for sending crashes. Omit this field for default address.
    // crashCollectorAddress: "",
    // Optional:Enable or disable reporting data using different endpoints for US government clients
    // fedRampEnabled: false
    // Optional: Enable or disable offline data storage when no internet connection is available.
    // offlineStorageEnabled:true
};

// アプリ起動時にNew Relicエージェントを初期化
NewRelic.startAgent(appToken, agentConfiguration);
// アプリのバージョンをNew Relicに設定
NewRelic.setJSAppVersion(version);
// React Nativeアプリケーションのメインコンポーネントを登録
AppRegistry.registerComponent(name, () => App);
```
上記の設定内容を少し詳しく紹介します。設定の内容としては、大きく4つに分けられます。
* **パッケージのインポート**
関連するパッケージやモジュールをインポートしています。アプリのバージョン情報や アプリを実行しているプラットフォームの情報（iOS, Android）を取得できるようにしています。
```js:
// New RelicのReact Nativeエージェントをインポート
import NewRelic from 'newrelic-react-native-agent';
// アプリケーションの名前とバージョン情報をpackage.jsonからインポート
import {name, version} from './package.json';
// React NativeのPlatformとAppRegistryモジュールをインポート
import {Platform, AppRegistry} from 'react-native';
```
* **New Relic の AppToken の設定**
[前ステップ](https://qiita.com/drafts/e430da6d2cf561c3fd54/edit#%E3%82%A8%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%B3%E3%83%88%E3%81%AE%E5%88%9D%E6%9C%9F%E5%8C%96%E3%81%A8%E8%A8%AD%E5%AE%9A)で確認した AppToken を設定してください。iOS, Android でそれぞれ異なる Token を使用するため、間違えないように注意してください。
```js
// OSごとに異なるAppTokenを設定する
let appToken;
if (Platform.OS === 'ios') {
    // iOS用のNew Relic AppToken
    appToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-NRMA';
} else {
    // Android用のNew Relic AppToken
    appToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-NRMA';
}
```
* **エージェントの設定オプションの設定**
　設定可能な設定オプションは、下記のドキュメントから確認できます。計装するアプリケーションに合わせてカスタマイズしてください。

https://docs.newrelic.com/jp/docs/mobile-monitoring/new-relic-mobile/mobile-sdk/configure-settings/#react

```js
// New Relicエージェントの設定オプション
const agentConfiguration = {

    //Android Specific
    // Optional:Enable or disable collection of event data.
    analyticsEventEnabled: true,
    // Optional:Enable or disable crash reporting.
    crashReportingEnabled: true,
    // Optional:Enable or disable interaction tracing. Trace instrumentation still occurs, but no traces are harvested. This will disable default and custom interactions.
    interactionTracingEnabled: true,
    // Optional:Enable or disable reporting successful HTTP requests to the MobileRequest event type.
    networkRequestEnabled: true,
    // Optional:Enable or disable reporting network and HTTP request errors to the MobileRequestError event type.
    networkErrorRequestEnabled: true,
    // Optional:Enable or disable capture of HTTP response bodies for HTTP error traces, and MobileRequestError events.
    httpRequestBodyCaptureEnabled: true,
   // Optional:Enable or disable agent logging.
    loggingEnabled: true,
    // Optional:Specifies the log level. Omit this field for the default log level.
    // Options include: ERROR (least verbose), WARNING, INFO, VERBOSE, AUDIT (most verbose).
    logLevel: NewRelic.LogLevel.INFO,
    // iOS Specific
    // Optional:Enable/Disable automatic instrumentation of WebViews
    webViewInstrumentation: true,
    // Optional:Set a specific collector address for sending data. Omit this field for default address.
    // collectorAddress: "",
    // Optional:Set a specific crash collector address for sending crashes. Omit this field for default address.
    // crashCollectorAddress: "",
    // Optional:Enable or disable reporting data using different endpoints for US government clients
    // fedRampEnabled: false
    // Optional: Enable or disable offline data storage when no internet connection is available.
    // offlineStorageEnabled:true
};
```
* **エージェントの初期化・設定**
　これまで設定した情報を使って New Relic のエージェントを初期化しています。version と name は ``package.json`` からインポートした情報を使用しているため、変数名を揃えてください。
```js
// アプリ起動時にNew Relicエージェントを初期化
NewRelic.startAgent(appToken, agentConfiguration);
// アプリのバージョンをNew Relicに設定
NewRelic.setJSAppVersion(version);
// React Nativeアプリケーションのメインコンポーネントを登録
AppRegistry.registerComponent(name, () => App);
```

**5\. アプリケーションの起動確認**
　Expo Go を使ってアプリケーションを起動してエージェントの初期化の処理に問題がないか確認します。Expo の Managed workflow を使用しているため、ネイティブコードを ``expo prebuild --clean`` コマンドを使用して、プラグインの変更を反映してアプリを再構築します。
```console:アプリケーションの起動
# アプリの再構築
expo prebuild --clean

# アプリの起動
npx expo start
```
　エラーが発生せずにアプリが起動すれば確認は完了です。カスタムネイティブコードを使用する必要があるため、Expo Go を使用している場合は、この段階では New Relic へデータは連携されません。

　iOS のアプリとして実行して New Relic へデータを転送します。
```console: アプリの実行
npx expo run:ios
```

#  New Relic Mobile のデータを確認する
## サマリページで全体の状態を把握
　New Relic Mobile のサマリページではアプリケーションのクラッシュ率やアプリの起動回数、HTTPリクエストの応答時間等を確認することができます。また、左上のプルダウンメニューで対象のバージョンを選択するとアプリケーションのバージョンごとにパフォーマンス情報も分析できるようになっています。複数バージョンのアプリが稼働するモバイルアプリでは必須の機能です。
![summary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/0c1467f3-577b-01c4-a3f1-d15fb8382640.png)


## HTTP リクエストの状況
　今回検証に使用したアプリケーションは、外部のAPIやリソースを使用して作成しています。そういったアプリの場合には **[HTTP Requests]** のページが有効です。モバイルアプリのパフォーマンスに与える影響を理解するために、アプリが行うHTTPリクエストの詳細を分析できます。Group by でリクエストのドメインや URI、Content Type ごとにグループ化してそれぞれのリクエスト回数や応答時間をランキング形式で確認可能です。 
![HTTP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/a0ff3ba3-32e1-bd78-b5ce-cd35cb286f67.png)

# 最後に
　New Relicは、モバイルアプリケーションのパフォーマンスモニタリングと最適化に必要な情報をリアルタイムで提供します。API応答時間、アプリケーションのクラッシュ分析、ネットワークリクエストの監視など、アプリのパフォーマンスに影響を与える主要な指標を詳細に追跡します。New Relicを使用することで、開発者はアプリの問題を迅速に特定し、効率的に解決することが可能です。
　New Relic Mobile は、無料アカウントでも利用できます。是非永久無償ライセンスを[こちら](https://newrelic.com/jp/sign-up-japan)から試してみてください。

https://newrelic.com/jp/sign-up-japan
 
:::note info
[New Relic株式会社のQiita Organization](https://qiita.com/organizations/newrelic)では、新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::