Crashlytics についてのトラブルシューティングとよくある質問


このページでは、Crashlytics の使用に関するトラブルシューティングのヘルプ情報と、よくある質問への回答を紹介します。お探しの情報が見つからない場合や、サポートが必要な場合は、Firebase サポートにお問い合わせください。

一般的なトラブルシューティングとよくある質問

Firebase コンソールの [問題] テーブルに一覧表示される問題には、2 つの異なる形式があります。また、問題内に「バリアント」と呼ばれる特徴が存在する場合もあります。その理由を説明します。

2023 年初頭、Google はイベントをグループ化するための向上した分析エンジンをリリースしました。このリリースでは、設計の更新が行われ、新しい問題向けの高度な機能(バリアントなど)が含まれています。詳しくは、最近のブログ投稿をご覧ください。最新情報については以下からもご確認いただけます。

Crashlytics は、アプリのすべてのイベント(クラッシュ、致命的でないイベント、ANR など)を分析し、問題と呼ばれるイベントのグループを作成します。1 つの問題の中のすべてのイベントには共通の障害点があります。

イベントを問題としてグループ化するために、向上した分析エンジンでは、スタック トレース内のフレーム、例外メッセージ、エラーコード、その他のプラットフォームまたはエラータイプの特性など、イベントの多くの要素を確認するようになりました。

ただし、このようにグループ化されたイベントの中には、障害に至るまでのスタック トレースが異なるものが含まれることがあります。スタック トレースが異なる場合は、根本原因が異なる可能性があります。一つの問題の中のこの違いを表現するため、問題の中にバリアントが作成されるようになりました。個々のバリアントは、一つの問題の中に含まれ、同じ障害点と類似のスタック トレースを持つイベントのサブグループです。バリアントによって、問題の中の最も一般的なスタック トレースをデバッグし、異なる根本原因によって障害が発生しているかどうかを判断できます。

改良点は以下のとおりです。

  • [問題] の行に表示されるメタデータを改善
    アプリで問題を簡単に把握し、優先順位を設定できるようになりました。

  • 問題の重複の低減
    行番号を変更しても新しい問題は発生しません。

  • さまざまな根本原因による複雑な問題のデバッグが容易に
    バリアントを使用して、問題内で最も一般的なスタック トレースをデバッグできます。

  • より有意義なアラートとシグナル
    新しい問題は実際の新しいバグを表すようになりました。

  • 検索機能の強化
    それぞれの問題に、例外タイプやパッケージ名など、検索可能なメタデータが追加されました。

改良された機能の提供の詳細は次のとおりです。

  • アプリから新しいイベントを受け取ると、既存の問題と一致するかどうかが確認されます。

  • 一致するものがない場合は、よりスマートなイベント グループ アルゴリズムをイベントに自動的に適用し、改良されたメタデータ設計を使って新しい問題を作成します。

これは、イベントのグループ分けに関する最初の大きなアップデートです。フィードバックがある場合や問題が発生した場合は、レポートに記入してお知らせください。

クラッシュの影響を受けていない指標(クラッシュの影響を受けていないユーザーやセッションなど)またはベロシティ アラートが表示されない場合は、 Crashlytics SDK 11.7.0 以降 を使用していることを確認してください。

パンくずリストのログが表示されない場合は、アプリの Google Analytics の構成を確認することをおすすめします。次の要件を満たしていることを確認してください。

Unity の IL2CPP を使用していて、シンボリケートされていないスタック トレースが表示される場合は、次の手順をお試しください。

  1. Crashlytics Unity SDK の v8.6.1 以降を使用していることを確認します。

  2. シンボル ファイルを生成してアップロードするための、Firebase CLI の crashlytics:symbols:upload コマンドが設定され、実行されていることを確認します。

    リリースビルドを作成するたびに、または Firebase コンソールでシンボリケートされたスタック トレースを表示するビルドを作成するたびに、この CLI コマンドを実行する必要があります。詳しくは、読み取り可能なクラッシュ レポートの取得をご覧ください。

はい。Crashlytics は、IL2CPP を使用するアプリに対して、シンボリケートされたスタック トレースを表示できます。この機能は、Android プラットフォームまたは Apple プラットフォームでリリースされたアプリで使用できます。必要な手順は次のとおりです。

  1. Crashlytics Unity SDK の v8.6.0 以降を使用していることを確認します。

  2. お使いのプラットフォームで必要なタスクを完了します。

    • Apple プラットフォーム アプリの場合: 特別な操作は必要ありません。Apple プラットフォーム アプリの場合、Firebase Unity Editor プラグインが、シンボルをアップロードするように Xcode プロジェクトを自動的に構成します。

    • Android アプリの場合: シンボル ファイルを生成してアップロードするための、Firebase CLI crashlytics:symbols:upload コマンドが設定され、実行されていることを確認します。

      リリースビルドを作成するたびに、または Firebase コンソールでシンボリケートされたスタック トレースを表示するビルドを作成するたびに、この CLI コマンドを実行する必要があります。詳しくは、読み取り可能なクラッシュ レポートの取得をご覧ください。

クラッシュなしの値は、特定の期間にアプリを利用したユーザーのうち、クラッシュが発生しなかったユーザーの割合を表します。

クラッシュの影響を受けていないユーザーの割合を計算する式は次のとおりです。入力値は Google Analytics から提供されます。

CRASH_FREE_USERS_PERCENTAGE = 1 - (CRASHED_USERS / ALL_USERS) x 100

  • クラッシュが発生すると、Google Analyticsapp_exception イベントタイプを送信します。CRASHED_USERS はそのイベントタイプに関連付けられているユーザーの数を表します。

  • ALL_USERS は、Crashlytics ダッシュボードの右上にあるプルダウン メニューから選択した期間中にアプリを利用したユーザーの合計数を表します。

クラッシュの影響を受けていないユーザーの割合は、時間の経過に伴う集計です。平均ではありません。

たとえば、アプリに 3 人のユーザーがいて、それぞれユーザー A、ユーザー B、ユーザー C とします。次の表は、それぞれの日にアプリを利用したユーザーと、その日にクラッシュが発生したユーザーを示しています。

月曜日 火曜日 水曜日
アプリを利用したユーザー A、B、C A、B、C A、B
クラッシュが発生したユーザー C B A
  • 水曜日にクラッシュの影響を受けていないユーザーの割合は 50% です(ユーザーの 2 人に 1 人はクラッシュの影響を受けませんでした)。
    水曜日にアプリを利用したユーザーは 2 人でしたが、そのうち 1 人(ユーザー B)にはクラッシュが発生しませんでした。

  • 過去 2 日間にクラッシュの影響を受けていないユーザーの割合は 33.3% です(ユーザーの 3 人に 1 人はクラッシュの影響を受けませんでした)。
    過去 2 日間にアプリを利用したユーザーは 3 人でしたが、クラッシュが発生しなかったのはそのうち 1 人(ユーザー C)だけでした。

  • 過去 3 日間にクラッシュの影響を受けていないユーザーの割合は 0% です(ユーザー 3 人の中にクラッシュの影響を受けなかったユーザーはいませんでした)。
    過去 3 日間にアプリを利用したユーザーは 3 人でしたが、クラッシュが発生しなかったユーザーはいませんでした。

クラッシュの影響を受けていないユーザーの値を異なる期間で比較しないでください。1 人のユーザーがクラッシュを経験する確率は、アプリの使用回数が増えるほど高くなるため、クラッシュの影響を受けていないユーザーの値は、期間が長くなるほど小さくなる可能性があります。

ノートを使用すると、特定の問題に関する質問やステータスの更新などについて、プロジェクト メンバーがコメントを残すことができます。

ノートには、投稿したメンバーの Google アカウントのメールアドレスがラベル付けされます。このメールアドレスは、ノートを見ることができるプロジェクト メンバー全員に対して、ノートとともに表示されます。

ノートを表示、書き込み、削除するために必要なアクセス権は次のとおりです。

クラッシュの影響を受けていない指標についてをご覧ください。

ノートを使用すると、特定の問題に関する質問やステータスの更新などについて、プロジェクト メンバーがコメントを残すことができます。

ノートには、投稿したメンバーの Google アカウントのメールアドレスがラベル付けされます。このメールアドレスは、ノートを見ることができるプロジェクト メンバー全員に対して、ノートとともに表示されます。

ノートを表示、書き込み、削除するために必要なアクセス権は次のとおりです。

統合

プロジェクトで Google Mobile Ads SDK と Crashlytics を併用している場合は、例外ハンドラの登録時にクラッシュ レポート機能が干渉している可能性があります。この問題を解決するには、disableSDKCrashReporting を呼び出して Mobile Ads SDK でクラッシュ レポート機能をオフにしてください。

Crashlytics を BigQuery にリンクすると、作成される新しいデータセットは、Firebase プロジェクトのロケーションに関係なく自動的に米国に配置されます。

問題の回帰

以前にクローズした問題が再発して Crashlytics が新しいレポートを受け取った場合に、対象の問題で回帰が発生したことになります。回帰が発生した問題は、アプリに適した方法で対応できるよう Crashlytics によって自動的に再オープンされます。

次のような場合、Crashlytics は問題を回帰として分類します。

  1. Crashlytics が初めて、クラッシュ「A」に関するクラッシュ レポートを受け取りました。Crashlytics は、そのクラッシュに対応する問題(問題「A」)をオープンしました。
  2. あなたはこのバグを速やかに修正し、問題「A」をクローズしてから、アプリの新しいバージョンをリリースしました。
  3. 問題をクローズした後で、Crashlytics が問題「A」に関する別のレポートを受け取りました。
    • このレポートが、この問題をクローズしたときに Crashlytics で認識されていたバージョン(つまり、なんらかのクラッシュに関するレポートを送信したことがあるバージョン)のアプリから送信されたものである場合は、Crashlytics は問題が回帰であると見なしません。この問題はクローズのままです。
    • このレポートが、この問題をクローズしたときに Crashlytics で認識されていなかったバージョン(つまりクラッシュに関するレポートを以前に送信したことがないバージョン)のアプリから送信されたものである場合、Crashlytics は問題を回帰と見なして再オープンします。

問題の回帰が発生すると、回帰検出アラートが送信されます。つまり回帰シグナルを問題に追加して、Crashlytics が問題を再オープンしたことを知らせます。この回帰アルゴリズムによって問題を再オープンしたくない場合は、問題をクローズする代わりに「ミュート」します。

レポートを送信したアプリのバージョンが、問題をクローズした時点でクラッシュ レポートを一度も送信したことのない古いバージョンである場合、Crashlytics は問題の回帰が発生したと見なし、その問題を再オープンします。

このような状況は、バグを修正し、新しいバージョンのアプリをリリースしたにもかかわらず、バグが修正されていない古いバージョンを利用しているユーザーがいる場合に発生することがあります。問題をクローズした時点でクラッシュ レポートを一度も送信したことのない、古いバージョンのアプリがまだ使用されている場合、そのバージョンでバグが発生してクラッシュ レポートが送信されると、問題の回帰がトリガーされます。

この回帰アルゴリズムによって問題を再オープンしたくない場合は、問題をクローズする代わりに「ミュート」します。

キャッチされなかった例外を致命的として報告する

Crashlytics では、キャッチされなかった例外を致命的として報告できます(Unity SDK の v10.4.0 以降)。次のよくある質問では、この機能を使用する理由とベスト プラクティスについて説明します。

キャッチされなかった例外を致命的として報告することで、アプリが引き続き実行されている場合でも、例外が発生すればゲームをプレイできなくなる可能性があることをよりリアルに示すことができます。

致命的エラーの報告を開始すると、クラッシュの影響を受けていないユーザー(CFU)の割合は減少する可能性がありますが、CFU 指標はアプリによるエンドユーザー エクスペリエンスの影響を適切に反映したものになります。

キャッチされなかった例外を Crashlytics が致命的な例外として報告するには、次の 2 つの条件が両方とも満たされている必要があります。

キャッチされなかった例外が致命的として報告されるようになった場合、これらのキャッチされなかった例外を処理する方法は、次のとおりです。

スローされた例外をキャッチして処理する

例外は、予期しない状態または例外的な状態を反映するために作成され、スローされます。スローされた例外によって反映される問題を解決するには、プログラムを既知の状態に戻します(このプロセスは例外処理と呼ばれます)。

プログラムを既知の状態に戻せない場合を除き、予測されるすべての例外をキャッチして処理することをおすすめします。

キャッチするコードの種類と、キャッチした例外の処理に使用するコードを制御するには、例外を生成する可能性があるコードを try-catch ブロック内にラップします。特定の例外を適切に処理できるように、catch ステートメントの条件をできるだけ絞り込んでください。

Unity または Crashlytics で例外をログに記録する

Unity または Crashlytics で例外を記録して問題のデバッグに役立てるには、複数の方法があります。

Crashlytics を使用する際の最も一般的な推奨オプションを 2 つ紹介します。

  • オプション 1: Unity コンソールに出力するものの、開発中またはトラブルシューティング中は Crashlytics に報告しない

    • 例外の内容を Unity コンソールに出力する Debug.Log(exception)Debug.LogWarning(exception)Debug.LogError(exception) を使用して Unity コンソールに出力しますが、例外を再スローしません。
  • オプション 2: 次の状況の場合は、Crashlytics にアップロードして、Crashlytics ダッシュボードに統合レポートを表示する:

    • 例外をロギングして、その後発生する可能性のある Crashlytics イベントをデバッグすることが有益である場合は、Crashlytics.Log(exception.ToString()) を使用します。
    • 例外をキャッチして処理した後も、Crashlytics に報告する必要がある場合は、Crashlytics.LogException(exception) を使用して、致命的でないイベントとしてログに記録します。

ただし、致命的なイベントを Unity Cloud Diagnostics に手動で報告する場合は、Debug.LogException を使用できます。このオプションでは、オプション 1 のように Unity コンソールに例外が出力されますが、(すでにスローされているのか、またはキャッチされているのかに関係なく)例外もスローされます。ローカル以外の場所でエラーをスローします。つまり、Debug.LogException(exception)try-catch ブロックで囲んだ場合でも、キャッチされない例外は発生します。

したがって、次のすべての操作を行う場合にのみ、Debug.LogException を呼び出します。

  • Unity コンソールに例外を出力する
  • 例外を致命的なイベントとして Crashlytics にアップロードする。
  • 例外をスローし、キャッチされなかった例外として処理し、Unity Cloud Diagnostics に報告する。

キャッチされた例外を Unity コンソールに出力し、 Crashlytics に致命的でないイベントとしてアップロードする場合は、代わりに次の手順を行います。

try
{
    methodThatThrowsMyCustomExceptionType();
}
catch(MyCustomExceptionType exception)
{
    // Print the exception to the Unity console at the error level.
    Debug.LogError(exception);
    // Upload the exception to Crashlytics as a non-fatal event.
    Crashlytics.LogException(exception); // not Debug.LogException
    //
    // Code that handles the exception
    //
}