UnityプロジェクトにおけるSmartBeatの活用例紹介




「[Applibot Advent Calendar 2020](https://qiita.com/advent-calendar/2020/applibot)」 22日目の記事になります。
前日は@S4ch1mosさんの 「[入社1年目のタスク管理について](https://qiita.com/S4ch1mos/items/f88f89554c245f96e395)」 という記事でした！

今回の記事では、SmartBeatの利用事例をご紹介します。


#はじめに
アプリのクラッシュはユーザに不快感をもたらし、継続率やストアのレーティング、新規DL数に悪影響を及ぼします。
しかし、これをもれなく調査し修正していくことは容易ではなく、ツールを利用した効率的な対応が求められています。


![スクリーンショット 2020-12-10 22.12.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905814/82e84f7b-6f9e-e075-f9f4-a4e4518cecdd.png)


Smartbeatは、スマートフォンアプリ向けのエラー検知・解析ツールです。
http://smrtbeat.com/
様々なプラットフォームに対応しており、軽量です。エラー、クラッシュの発生をリアルタイムに可視化し、その修正を支援する機能が備わっています。

SmartBeatは単にSDKを導入するだけでも各種情報を取得できますが、ちょっとした工夫によってさらに便利になります。



# 拡張キーの追加

下記メソッドによって、ユーザの状態を記録しておき、エラー発生時に確認することができます。

```C#
SmartBeat.SmartBeat.addExtraData(key, value);
```

<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905814/8d55f989-ac92-bdb2-81cf-5b640bd1d480.png">

どんな情報を追加しても良いですが、「ユーザが最後に選択した〇〇のID」は導入しやすく、調査のヒントとして有用なことが多いです。
再現手順の確立が難しいバグは、一部の条件でのみ利用されるアセットやコードに問題があることが多いためです。




あるタイトルでの拡張例を示します。


### 拡張キーにインゲームへ渡す情報を追加
ゲームの設計として、実際にゲームが行われるパート（インゲーム）とその準備をするパート（アウトゲーム）に分かれることがあります。
このとき、アウトゲームからインゲームに渡す情報（もしくはその逆）をSmartBeatの拡張キーに渡すと、問題の切り分けがしやすくなります。
例えば、多数のエラーが発生した場合に操作キャラクターには偏りがないがステージIDには偏りがある、となればそれらのステージに共通して使われるアセットやコードに疑いを絞っていくことが可能になります。


### 拡張キーにアセットバージョンを追加
あるシステムでは、全アセットバンドルのバージョン管理に用いられるhashリストに対応して1つの番号を割り振り、それをアセットバージョンと名付けています。
アセットバージョンはアセットビルドをするごとに1つ割り当てられ、クライアントは起動時に最新のアセットバージョンとhashリストを取得、以降はサーバに自身の保持するアセットバージョンを送信し続け、その古さが許容できなくなった時にタイトルに画面遷移してhashリストを取得し直すという挙動です。
つまり、ユーザのプレイ体感を守るためにある程度アセットが古い状態であることを許容する設計になっています。


このアセットバージョンを拡張キーに追加しておくことで、ユーザがどのアセットバージョンでプレイしているかを確認することができます。
緊急度の低いアセットの修正であれば、新しいアセットバージョンで問題が発生していなければ順次解消されるということがすぐに分かります。
（緊急度が高い場合は最低保証アセットバージョンを最新に引き上げ全プレイヤーをタイトルバックさせることとなります）



# 通信エラーの取得
通信基盤の仕組みとして、通信時に問題が発生した場合、共通のロジックによってそれをキャッチして処理するような作りにすることはよく行われることです。
共有のエラー処理を実行するついでにSmartBeatにログを送信することで、ユーザの通信エラー発生状況を詳細に把握することができるようになります。

特に、サーバ側でのエラーログ収集が難しい(or面倒な)下記のようなケースでは、この方法によってかなりの確度で収集することができます。

- アセットサーバとの通信
- mBaaSとの通信
- 通信ライブラリから発されるネットワークエラー

任意のタイミングでのログ送信は、下記のような記述で行います。

```C#
SmartBeat.SmartBeat.HandleLog(log, stackTrace, logType);
```

# レアケースで生じるバグの調査
お問い合わせなどで少数報告があるものの、開発チームで再現することができない問題が発生することが稀にあります。
特に、アクションゲームではタイミング依存のバグが発生することが多いです。

例えば「自身が特定の技Aを発動している瞬間に敵が技Bを発動するとあるボタンが押せなくなる」といった事象が起きた場合、大抵最初から技ABが浮上することはなく、なぜか急にボタンが押せなくなった、などといった報告からスタートすることがほとんどです。
どうにかして開発環境で再現できれば「バグの尻尾を掴んだ」状態になりますが、それが難しい場合の調査は困難を極めます。

このようなやむを得ない場合に限りますが、その事象が発生しうる箇所からログを送信することで再現の手がかりを掴むことができます。
また、同時に影響ユーザ数や再現頻度を知ることができるので、その問題の調査優先度を決める判断材料とすることができます。




# パンくず機能
任意の箇所から行動ログのような形でパンくずを残すことができます。

```C#
SmartBeat.SmartBeat.leaveBreadcrumb("Change state : xx");
```

以前は任意に追加したパンくずのみが表示されていましたが、今年の夏頃に公開されたバージョン1.20よりUnityからの情報やOSからの情報など表示されるようになりました。
シーンの読み込みやアクティブシーンの切り替え、バッテリー低下やメモリワーニングなどが確認できます。
自前の実装としては、画面遷移の共通処理にパンくずの記録処理を追加し、問題発生までにどのような画面遷移をしたかを確認できるようにしています。

![スクリーンショット 2020-12-10 21.28.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905814/bc4b735a-5084-b34d-27d0-c613d53e68ac.png)
![スクリーンショット 2020-12-10 21.30.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905814/be4715f7-7274-5d38-6d82-b07ef0802886.png)


# 今後のアップデートについて

現在はメモリの利用量が多すぎることによるクラッシュ（Out Of Memory）の発生数をデイリーで確認できる機能がありますが、さらに発生経路などを調査できるようアップデートすることが予告されています。
今後さらに便利になるSmartBeatに期待しています。


#まとめ
SmartBeatの拡張機能について、ちょっとした工夫と簡単な実装で便利に利用できる例を紹介しました。

以上、Applibot Advent Calendar 2020 22日目の記事でした！
明日は @TakumaKurosawa さんです！