Google は、黒人コミュニティのための人種的公平の促進に取り組んでいます。詳細をご覧ください。

Firebase Crashlytics データを BigQuery にエクスポートする

Crashlytics のデータを BigQuery にエクスポートすれば、さらに詳しい分析を行えます。BigQuery では、BigQuery SQL を使用してデータを分析できます。また、データを別のクラウド プロバイダにエクスポートできるほか、可視化や Google データポータルのカスタム ダッシュボードでデータを使用できます。

BigQuery Export を有効にする

  1. Firebase コンソールの [統合] ページに移動します。
  2. BigQuery カードで、[リンク] をクリックします。
  3. 画面上の指示に従って BigQuery を有効にします。

プロジェクトを BiqQuery にリンクすると、次のようになります。

  • Firebase は、Firebase プロジェクトから BigQuery へのデータの毎日の同期を設定します。
  • デフォルトでは、プロジェクト内のすべてのアプリが BigQuery にリンクされ、後からプロジェクトに追加するアプリはすべて BigQuery に自動的にリンクされます。データを送信するアプリを管理することもできます。
  • Firebase は、BigQuery に既存データのコピーをエクスポートします。リンクされたアプリごとのバッチテーブルからも、毎日の同期によりデータがエクスポートされます。
  • Crashlytics BigQuery ストリーミング エクスポートを有効にしている場合、リンクされたすべてのアプリにリアルタイム テーブルも作成されます。このテーブルには、常に更新を続けるデータが格納されます。

BigQuery エクスポートを無効にするには、Firebase コンソールでプロジェクトのリンクを解除します。

BigQuery にエクスポートされるデータの概要

Firebase Crashlytics データは、firebase_crashlytics という名前の BigQuery データセットにエクスポートされます。デフォルトでは、プロジェクト内のアプリごとに用意される Crashlytics データセットに個々のテーブルが作成されます。Firebase は、アプリのバンドル ID に基づいてテーブルの名前を付けます。ピリオドはアンダースコアに変換され、名前の末尾にプラットフォーム名が追加されます。

たとえば、ID が com.google.test のアプリのデータは、com_google_test_ANDROID という名前のテーブルに格納されます。このバッチテーブルは毎日 1 回更新されます。Crashlytics BigQuery ストリーミング エクスポートを有効にしている場合、Firebase Crashlytics のデータもリアルタイムで com_google_test_ANDROID_REALTIME にストリーミングされます。

テーブル内の各行はアプリで発生したイベントを表します。この中には致命的なエラーもあれば、そうでないものもあります。

Crashlytics BigQuery ストリーミング エクスポートを有効にする

BigQueryStreaming を使用すると、Crashlytics のデータをリアルタイムでストリーミングできます。ライブ ダッシュボードでの情報の表示、ライブでのロールアウトの監視、アラートやカスタム ワークフローをトリガーするアプリケーション問題のモニタリングなど、ライブデータが必要なあらゆる目的で使用できます。

Crashlytics BigQuery ストリーミング エクスポートは、BigQuery サンドボックスでは使用できません。

Crashlytics BigQuery ストリーミング エクスポートを有効にすると、バッチテーブルに加えてリアルタイム テーブルも作成されます。この 2 つのテーブルには次の違いがあります。

バッチテーブル リアルタイム テーブル
  • データは 1 日 1 回エクスポートされます。
  • BigQuery へのバッチ書き込み前に、イベントが永続的に保存されます。
  • 最大で 90 日前まで遡ってテーブルのバックフィルを行えます。
  • データはリアルタイムでエクスポートされます。
  • テーブルのバックフィルは行えません。

バッチテーブルには書き込み前のイベントが永続的に保存されるため、このテーブルは長期分析で経時的な傾向を識別する場合に適しています。また、最大で 90 日前まで遡ってテーブルのバックフィルを行うことができます。リアルタイム テーブルに書き込まれたデータはすぐに BigQuery に書き込まれるため、ライブ ダッシュボードやカスタム アラートにはリアルタイム テーブルが適しています。この 2 つのテーブルを合成クエリで組み合わせると、両方のメリットを利用できます。下記の例 9 のクエリをご覧ください。

デフォルトでは、リアルタイム テーブルのパーティションの有効期限は 30 日間です。これを変更する方法については、パーティションの有効期限の更新をご覧ください。

Crashlytics BigQuery ストリーミングを有効にする

ストリーミングを有効にするには、BigQuery の [統合] ページに移動し、[Crashlytics] で [ストリーミングを含める] チェックボックスをオンにします。

データポータルのテンプレート

データポータルのテンプレートでリアルタイム テーブルを有効にするには、データポータルを使用してエクスポートされた Crashlytics データの可視化の手順に沿って操作します。

ビュー

BigQuery UI を使用して、以下のサンプルクエリをビューに変換できます。詳細な手順については、ビューを作成するをご覧ください。

エクスポートされたデータで可能な操作

BigQuery Export では、デバイスの種類、オペレーティング システム、例外(Android アプリ)またはエラー(iOS アプリ)、Crashlytics ログなど、未加工のクラッシュ データを利用できます。

BigQuery での Firebase Crashlytics データの操作

以下では、Crashlytics データに実行できるクエリの例を紹介します。 ここで説明するクエリを使用すると、Crashlytics ダッシュボードでは提供されないレポートを生成できます。

Crashlytics クエリの例

次の例は、障害イベントデータを、より簡単に理解できる概要に集約するレポートを生成する方法を示しています。

例 1: 日別のクラッシュ数を確認する

あるチームで新しい写真共有アプリを開発しています。修正するバグがほとんどなくなり、チームの主任開発者はリリース可能な状態になったと考えました。しかし、チームのメンバーは過去 1 か月間の 1 日あたりの障害件数を確認し、バグバッシュでアプリが時間とともに安定してきたことを確認したいと考えています。

SELECT
  COUNT(DISTINCT event_id) AS number_of_crashes,
  FORMAT_TIMESTAMP("%F", event_timestamp) AS date_of_crashes
FROM
 `projectId.firebase_crashlytics.package_name_ANDROID`
GROUP BY
  date_of_crashes
ORDER BY
  date_of_crashes DESC
LIMIT 30;

例 2: 最も多いクラッシュを確認する

あるプロジェクト マネージャーが、生産計画の優先順位を正しく判断するため、自社製品で最も多い障害の上位 10 件を特定しようとしています。そこで、次のようなクエリを作成し、関連するデータを抽出することにしました。

SELECT
  DISTINCT issue_id,
  COUNT(DISTINCT event_id) AS number_of_crashes,
  COUNT(DISTINCT installation_uuid) AS number_of_impacted_user,
  blame_frame.file,
  blame_frame.line
FROM
  `projectId.firebase_crashlytics.package_name_ANDROID`
WHERE
  event_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(),INTERVAL 168 HOUR)
  AND event_timestamp < CURRENT_TIMESTAMP()
GROUP BY
  issue_id,
  blame_frame.file,
  blame_frame.line
ORDER BY
  number_of_crashes DESC
LIMIT 10;

例 3: クラッシュ数が多い上位 10 台のデバイスを特定する

秋は新しいスマートフォンのシーズンです。この季節はまた、新しいデバイス固有の問題が多発する時期でもあります。今後起きる可能性がある互換性の問題を事前に把握するため、先週最も多く障害が発生した 10 台のデバイスを特定するクエリを作成しました。

SELECT
  device.model,
COUNT(DISTINCT event_id) AS number_of_crashes
FROM
  `projectId.firebase_crashlytics.package_name_ANDROID`
WHERE
  event_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 168 HOUR)
  AND event_timestamp < CURRENT_TIMESTAMP()
GROUP BY
  device.model
ORDER BY
  number_of_crashes DESC
LIMIT 10;

例 4: カスタムキーでフィルタリングする

あるゲーム デベロッパーが、ゲームのどのレベルで最も多くの障害が発生するかを調べようとしています。統計情報を追跡するため、Crashlytics のカスタムキー current_level を設定しました。このキーは、ユーザーが次のレベルに到達するたびに更新されます。

Objective-C

CrashlyticsKit setIntValue:3 forKey:@"current_level";

Swift

Crashlytics.sharedInstance().setIntValue(3, forKey: "current_level");

Java

Crashlytics.setInt("current_level", 3);

次に、このキーを BigQuery Export で使用し、current_level 値の分布を障害イベントと関連付けて報告するクエリを作成しました。

SELECT
COUNT(DISTINCT event_id) AS num_of_crashes,
  value
FROM
  `projectId.firebase_crashlytics.package_name_ANDROID`
UNNEST(custom_keys)
WHERE
  key = "current_level"
GROUP BY
  key,
  value
ORDER BY
  num_of_crashes DESC

例 5: ユーザー ID を抽出する

デベロッパーがアプリを開発し、早期アクセスを有効にしました。ほとんどのユーザーは問題なく利用していますが、3 人のユーザーから異常な数の障害件数が報告されました。根本的な原因を突き止めるため、これらのユーザーの ID を使用して障害イベントを取得するクエリを作成しました。

SELECT *
FROM
  `projectId.firebase_crashlytics.package_name_ANDROID`
WHERE
  user.id IN ("userid1", "userid2", "userid3")
ORDER BY
  user.id
 

例 6: 特定のクラッシュ問題が発生しているすべてのユーザーを抽出する

デベロッパーからベータテスターのグループに重大なバグが報告されました。テストチームは、上記の例 2 のクエリを使用してクラッシュ問題の ID を特定し、このクラッシュの影響を受けたアプリユーザーのリストを抽出するクエリを実行しました。

SELECT user.id as user_id
FROM
  `projectId.firebase_crashlytics.package_name_ANDROID`
WHERE
  issue_id = "YOUR_ISSUE_ID"
  AND application.display_version = ""
  AND user.id != ""
ORDER BY
  user.id;

例 7: クラッシュの影響を受けたユーザーの数を国別にまとめる

新しいリリースのロールアウト中に重大なバグが見つかりました。 クラッシュ問題の ID を調べるため、上記の例 2 のクエリを使用しました。次に、このクラッシュが世界的にどのように影響しているのかを確認します。

このクエリを作成するために、次の作業が必要になります。

  1. Google アナリティクスの BigQuery Export を有効にします。詳しくは、プロジェクト データを BigQuery にエクスポートするをご覧ください。

  2. ユーザー ID を Google アナリティクス SDK と Crashlytics SDK の両方に渡すようにアプリを更新します。

    Objective-C
    CrashlyticsKit setUserIdentifier:@"123456789";
    FIRAnalytics setUserID:@"12345678 9";
    
    Swift
    Crashlytics.sharedInstance().setUserIdentifier("123456789");
    Analytics.setUserID("123456789");
    
    Java
    Crashlytics.setUserIdentifier("123456789");
    mFirebaseAnalytics.setUserId("123456789");
    
  3. Google アナリティクスの BigQuery データセットに記録されているイベントと Crashlytics の BigQuery データセットに保存されているクラッシュ情報をユーザー ID フィールドで結合するクエリを作成します。

    SELECT DISTINCT c.issue_id, a.geo.country, COUNT(DISTINCT c.user.id) as num_users_impacted
    FROM `projectId.firebase_crashlytics.package_name_ANDROID` c
    INNER JOIN  `projectId.analytics_YOUR_TABLE.events_*` a on c.user.id = a.user_id
    WHERE
     c.issue_id = "YOUR_ISSUE_ID"
     AND a._TABLE_SUFFIX BETWEEN '20190101'
     AND '20200101'
    GROUP BY
     c.issue_id,
     a.geo.country,
     c.user.id
    

例 8: 今日ここまでの上位 5 件の問題

Crashlytics BigQuery ストリーミング エクスポートを有効にする必要があります

SELECT
  issue_id,
  COUNT(DISTINCT event_id) AS events
FROM
  `your_project.firebase_crashlytics.package_name_ANDROID_REALTIME`
WHERE
  DATE(event_timestamp) = CURRENT_DATE()
GROUP BY
  issue_id
ORDER BY
  events DESC
LIMIT
  5;

例 9: DATE 以降から今日までの上位 5 件の問題

Crashlytics BigQuery ストリーミング エクスポートを有効にする必要があります。

この例では、バッチテーブルとリアルタイム テーブルを組み合わせて、信頼性の高いバッチデータに加え、リアルタイム情報を提供します。event_id が主キーであるため、DISTINCT event_id を使用して 2 つのテーブルで共通するすべてのイベントの重複を排除できます。

SELECT
  issue_id,
  COUNT(DISTINCT event_id) AS events
FROM (
  SELECT
    issue_id,
    event_id,
    event_timestamp
  FROM
    `your_project.firebase_crashlytics.package_name_ANDROID_REALTIME`
  UNION ALL
  SELECT
    issue_id,
    event_id,
    event_timestamp
  FROM
    `your_project.firebase_crashlytics.package_name_ANDROID`)
WHERE
  event_timestamp >= "2020-01-13"
GROUP BY
  issue_id
ORDER BY
  events DESC
LIMIT
  5;

BigQuery 内の Firebase Crashlytics スキーマについて

Crashlytics と BigQuery をリンクすると、Firebase は最近発生した致命的な障害イベントと致命的でない障害イベントをエクスポートします。この中には、リンクの 2 日前までのイベントが含まれており、最大 90 日前まで遡ってテーブルのバックフィルを行えるオプションも用意されています。

リンクの 2 日前の時点からユーザーがリンクを無効にするまで、Firebase は Crashlytics イベントを毎日エクスポートします。エクスポート後に BigQuery でデータを利用できるようになるまでに数分かかることがあります。

データセット

Firebase Crashlytics は、BigQuery に Crashlytics データ用の新しいデータセットを作成します。このデータセットは、複数のアプリがある場合でもプロジェクト全体をカバーします。

テーブル

ユーザーがアプリのデータ エクスポートを無効にしない限り、Firebase Crashlytics はプロジェクトに含まれるアプリごとに、データセット内にテーブルを作成します。Firebase は、アプリのバンドル ID に基づいてテーブルの名前を付けます。ピリオドはアンダースコアに変換され、名前の末尾にプラットフォーム名が追加されます。

たとえば、ID が com.google.test の Android アプリのデータは com_google_test_ANDROID という名前のテーブルに格納され、リアルタイム データ(有効にされてる場合)は com_google_test_ANDROID_REALTIME という名前のテーブルに格納されます。

テーブルには、デベロッパーが定義した Crashlytics カスタムキーに加えて、Crashlytics データの標準セットが含まれています。

テーブルの各行は、アプリで発生したエラーを表します。

テーブルの列は、致命的なエラーの場合も致命的でないエラーの場合も同じです。Crashlytics BigQuery ストリーミング エクスポートが有効にされている場合、リアルタイム テーブルにはバッチテーブルと同じ列があります。エクスポート データには以下の列が含まれます。

スタック トレースなし

スタック トレースのないイベントを表す行にある列。

フィールド名 データタイプ 説明
platform STRING Android と iOS
bundle_identifier STRING バンドル ID。例: com.google.gmail
event_id STRING イベントの一意の ID
is_fatal BOOLEAN アプリがクラッシュしたかどうか
issue_id STRING イベントに関連する問題
event_timestamp TIMESTAMP イベントの発生時間
device RECORD イベントが発生したデバイス
device.manufacturer STRING デバイスの製造元
device.model STRING デバイスのモデル
device.architecture STRING X86_32、X86_64、ARMV7、ARM64、ARMV7S または ARMV7K
memory RECORD デバイスのメモリ ステータス
memory.used INT64 使用済みのメモリ(バイト)
memory.free INT65 未使用のメモリ(バイト)
storage RECORD デバイスの永続ストレージ
storage.used INT64 使用済みストレージ(バイト)
storage.free INT64 未使用のストレージ(バイト)
operating_system RECORD デバイスの OS の詳細
operating_system.display_version STRING OS のバージョン
operating_system.name STRING OS 名
operating_system.modification_state STRING MODIFIED または UNMODIFIED(つまり、デバイスが制限解除またはルート化されているかどうか)
application RECORD イベントを生成したアプリ
application.build_version STRING アプリのビルド バージョン
application.display_version STRING
user RECORD オプション: アプリのユーザーに関して収集された情報
user.name STRING オプション: ユーザーの名前
user.email STRING オプション: ユーザーのメールアドレス
user.id STRING オプション: ユーザーに関連付けられているアプリ固有の ID
custom_keys REPEATED RECORD デベロッパーが定義した Key-Value ペア
custom_keys.key STRING デベロッパーが定義したキー
custom_keys.value STRING デベロッパーが定義した値
installation_uuid STRING アプリとデバイスのインストールを一意に識別する ID
crashlytics_sdk_versions STRING イベントを生成した Crashlytics SDK のバージョン
app_orientation STRING PORTRAIT、LANDSCAPE、FACE_UP または FACE_DOWN
device_orientation STRING PORTRAIT、LANDSCAPE、FACE_UP または FACE_DOWN
process_state STRING BACKGROUND または FOREGROUND
logs REPEATED RECORD Crashlytics Logger によって生成されたタイムスタンプ付きのログメッセージ(有効な場合)
logs.timestamp TIMESTAMP ログの作成時間
logs.message STRING ログに記録されたメッセージ
breadcrumbs REPEATED RECORD タイムスタンプ付きの Google アナリティクスのパンくずリスト(有効な場合)
breadcrumbs.timestamp TIMESTAMP パンくずリストに関連付けられているタイムスタンプ
breadcrumbs.name STRING パンくずリストに関連付けられている名前
breadcrumbs.params REPEATED RECORD パンくずリストに関連付けられたパラメータ
breadcrumbs.params.key STRING パンくずリストに関連付けられたパラメータキー
breadcrumbs.params.value STRING パンくずリストに関連付けられたパラメータ値
blame_frame RECORD クラッシュまたはエラーの根本的原因として識別されたフレーム
blame_frame.line INT64 フレーム ファイルの行番号
blame_frame.file STRING フレーム ファイルの名前
blame_frame.symbol STRING ハイドレードされたシンボル。ハイドレード可能でない場合は未加工のシンボル。
blame_frame.offset INT64 コードを含むバイナリ イメージへのバイト オフセット。Java 例外で設定解除。
blame_frame.address INT64 コードを含むバイナリ イメージのアドレス。Java フレームで設定解除。
blame_frame.library STRING フレームを含むライブラリの表示名
blame_frame.owner STRING DEVELOPER、VENDOR、RUNTIME、PLATFORM または SYSTEM
blame_frame.blamed BOOLEAN Crashlytics の分析で、このフレームがクラッシュまたはエラーの原因と判断されたかどうか
exceptions REPEATED RECORD Android のみ: このイベントで発生した例外。ネストされている例外は発生順と逆に表示されます(読み取り: 最後のレコードが最初にスローされる例外)。
exceptions.type STRING 例外タイプ。例: java.lang.IllegalStateException
exceptions.exception_message STRING 例外に関連するメッセージ
exceptions.nested BOOLEAN 最後にスローされた例外を除くすべて(すなわち、最初のレコード)の場合は true。
exceptions.title STRING スレッドのタイトル
exceptions.subtitle STRING スレッドのサブタイトル
exceptions.blamed BOOLEAN エラーまたはクラッシュが原因で例外が発生しているかどうかを Crashlytics が判断する場合は true
exceptions.frames REPEATED RECORD 例外に関連付けられているフレーム
exceptions.frames.line INT64 フレーム ファイルの行番号
exceptions.frames.file STRING フレーム ファイルの名前
exceptions.frames.symbol STRING ハイドレードされたシンボル。ハイドレード可能でない場合は未加工のシンボル。
exceptions.frames.offset INT64 コードを含むバイナリ イメージへのバイト オフセット。Java 例外で設定解除。
exceptions.frames.address INT64 コードを含むバイナリ イメージのアドレス。Java フレームで設定解除。
exceptions.frames.library STRING フレームを含むライブラリの表示名
exceptions.frames.owner STRING DEVELOPER、VENDOR、RUNTIME、PLATFORM または SYSTEM
exceptions.frames.blamed BOOLEAN Crashlytics の分析で、このフレームがクラッシュまたはエラーの原因と判断されたかどうか
エラー REPEATED RECORD iOS のみ: 致命的ではないエラー
error.queue_name STRING スレッドが実行されていたキュー
error.code INT64 アプリのカスタムログに記録された NSError に関連するエラーコード
error.title STRING スレッドのタイトル
error.subtitle STRING スレッドのサブタイトル
error.blamed BOOLEAN Crashlytics の分析で、このフレームがエラーの原因と判断されたかどうか
error.frames REPEATED RECORD スタック トレースのフレーム
error.frames.line INT64 フレーム ファイルの行番号
error.frames.file STRING フレーム ファイルの名前
error.frames.symbol STRING ハイドレードされたシンボル。ハイドレード可能でない場合は未加工のシンボル。
error.frames.offset INT64 コードを含むバイナリ イメージへのバイト オフセット
error.frames.address INT64 コードを含むバイナリ イメージ内のアドレス
error.frames.library STRING フレームを含むライブラリの表示名
error.frames.owner STRING DEVELOPER、VENDOR、RUNTIME、PLATFORM または SYSTEM
error.frames.blamed BOOLEAN Crashlytics の分析で、このフレームがエラーの原因と判断されたかどうか
threads REPEATED RECORD イベント発生時に存在していたスレッド
threads.crashed BOOLEAN スレッドがクラッシュしたかどうか
threads.thread_name STRING スレッドの名前
threads.queue_name STRING iOS のみ: スレッドが実行されていたキュー
threads.signal_name STRING アプリをクラッシュさせたシグナルの名前。クラッシュしたネイティブ スレッドにのみ存在します。
threads.signal_code STRING アプリをクラッシュさせたシグナルのコード。クラッシュしたネイティブ スレッドにのみ存在します。
threads.crash_address INT64 アプリケーションをクラッシュさせたシグナルのアドレス。クラッシュしたネイティブ スレッドにのみ存在します。
threads.code INT64 iOS のみ: アプリケーションのカスタムログの NSError エラーコード
threads.title STRING スレッドのタイトル
threads.subtitle STRING スレッドのサブタイトル
threads.blamed BOOLEAN Crashlytics の分析で、このフレームがクラッシュまたはエラーの原因と判断されたかどうか
threads.frames REPEATED RECORD スレッドのフレーム
threads.frames.line INT64 フレーム ファイルの行番号
threads.frames.file STRING フレーム ファイルの名前
threads.frames.symbol STRING ハイドレードされたシンボル。ハイドレード可能でない場合は未加工のシンボル。
threads.frames.offset INT64 コードを含むバイナリ イメージへのバイト オフセット
threads.frames.address INT64 コードを含むバイナリ イメージ内のアドレス
threads.frames.library STRING フレームを含むライブラリの表示名
threads.frames.owner STRING DEVELOPER、VENDOR、RUNTIME、PLATFORM または SYSTEM
threads.frames.blamed BOOLEAN Crashlytics の分析で、このフレームがエラーの原因と判断されたかどうか

データポータルを使用してエクスポートされた Crashlytics データの可視化

Google データポータルを使うと、BigQuery の Crashlytics データセットを、読みやすく、共有しやすい、全面的にカスタマイズ可能なレポートに変換できます。

データポータルの使用方法の詳細については、データポータル クイックスタート ガイドのデータポータルへようこそを試してください。

Crashlytics レポート テンプレートを使用する

データポータルには、エクスポートされた Crashlytics BigQuery スキーマからの包括的なディメンションと指標のセットを含む Crashlytics のサンプル レポートがあります。Crashlytics BigQuery ストリーミング エクスポートを有効にしている場合、エクスポートされたデータはデータポータルのテンプレートの [Realtime trends] ページで確認できます。このサンプルをテンプレートとして使用すると、実際のアプリのクラッシュ データに基づいて新しいレポートやビジュアル資料を手軽に作成できます。

  1. Crashlytics データポータル ダッシュボード テンプレートを開きます。
  2. 右上にある [テンプレートを使用] をクリックします。
  3. [新しいデータソース] プルダウンから [新しいデータソースを作成する] を選択します。
  4. BigQuery カードの [選択] をクリックします。
  5. [My Projects] > [<プロジェクト名>] > [firebase_crashlytics] > [<テーブル名>] の順に選択して、エクスポートされた Crashlytics データを含むテーブルを選択します。バッチテーブルは常に選択可能です。Crashlytics BigQuery ストリーミング エクスポートを有効にしている場合は、代わりにリアルタイム テーブルを選択できます。
  6. [Configuration] で、[Crashlytics Template level] を [Default] に設定します。
  7. [Connect] をクリックして新しいデータソースを作成します。
  8. [Add to Report] をクリックして Crashlytics テンプレートに戻ります。
  9. 最後に、[Create Report] をクリックして Crashlytics データポータル ダッシュボード テンプレートのコピーを作成します。