將 Firebase Crashlytics 數據導出到 BigQuery

您可以將 Crashlytics 數據導出到BigQuery以進行進一步分析。 BigQuery 允許您使用 BigQuery SQL 分析數據,將其導出到另一個雲提供商,並將其用於 Google Data Studio 的可視化和自定義儀表板。

啟用 BigQuery 導出

  1. 轉到 Firebase 控制台中的集成頁面。
  2. BigQuery卡片中,點擊鏈接
  3. 按照屏幕上的說明啟用 BigQuery。

當您將項目鏈接到 BigQuery 時:

  • Firebase 設置每天將您的數據從 Firebase 項目同步到 BigQuery。
  • 默認情況下,您項目中的所有應用都與 BigQuery 相關聯,您以後添加到項目中的所有應用都會自動與 BigQuery 相關聯。您可以管理哪些應用程序發送數據
  • Firebase將現有數據的副本導出到 BigQuery。對於每個鏈接的應用,這包括一個包含每日同步數據的批處理表。
  • 如果您啟用 Crashlytics BigQuery 流式導出,所有鏈接的應用程序還將有一個實時表,其中包含不斷更新的數據。

要停用 BigQuery 導出,請在 Firebase 控制台中取消關聯您的項目

哪些數據會導出到 BigQuery?

Firebase Crashlytics 數據導出到名為firebase_crashlytics的 BigQuery 數據集。默認情況下,將在 Crashlytics 數據集中為項目中的每個應用創建單獨的表。 Firebase 根據應用的包標識符命名表,句點轉換為下劃線,並在末尾附加一個平台名稱。

例如,ID 為com.google.test的應用的數據將位於名為com_google_test_ANDROID的表中。此批處理表每天更新一次。如果您啟用 Crashlytics BigQuery 流式導出,Firebase Crashlytics 數據也將實時流式傳輸到com_google_test_ANDROID_REALTIME

表中的每一行代表應用程序中發生的一個事件,包括崩潰、非致命錯誤和 ANR。

啟用 Crashlytics BigQuery 流式導出

您可以使用BigQueryStreaming實時流式傳輸您的 Crashlytics 數據。您可以將它用於需要實時數據的任何目的,例如在實時儀表板中顯示信息、實時觀看部署或監控觸發警報和自定義工作流的應用程序問題。

Crashlytics BigQuery 流式導出不適用於 BigQuery 沙盒。

當您啟用 Crashlytics BigQuery 流式導出時,除了批處理表之外,您還將擁有一個實時表。以下是您應該注意的表之間的差異:

批處理表實時表
  • 每天導出一次數據
  • 在批量寫入 BigQuery 之前持久存儲的事件
  • 最多可提前 90 天回填
  • 數據實時導出
  • 沒有可用的回填

批處理表非常適合長期分析和識別隨時間推移的趨勢,因為我們在寫入事件之前會持久存儲事件,並且可以將它們回填到表中長達 90 天。當我們將數據寫入您的實時表時,我們會立即將其寫入 BigQuery,因此它非常適合實時儀表板和自定義警報。這兩個表可以結合一個拼接查詢來獲得兩者的好處。請參閱下面的查詢示例 9

默認情況下,實時表的分區過期時間為 30 天。要了解如何修改它,請參閱更新分區過期時間。

啟用 Crashlytics BigQuery 流式傳輸

要啟用流式傳輸,請導航至 BigQuery集成頁面的 Crashlytics 部分,然後選中包含流式傳輸複選框。

數據洞察模板

要在 Data Studio 模板中啟用實時數據,請按照使用 Data Studio 可視化導出的 Crashlytics 數據中的說明進行操作。

意見

您可以使用 BigQuery UI 將下面的示例查詢轉換為視圖。有關詳細說明,請參閱創建視圖

你可以用導出的數據做什麼?

BigQuery 導出包含原始崩潰數據,包括設備類型、操作系統、異常(Android 應用)或錯誤(Apple 應用)、Crashlytics 日誌以及其他數據。

在 BigQuery 中使用 Firebase Crashlytics 數據

以下示例演示了可以對 Crashlytics 數據運行的查詢。這些查詢生成的報告在 Crashlytics 儀表板中不可用。

Crashlytics 查詢示例

以下示例演示瞭如何生成將崩潰事件數據匯總為更易於理解的摘要的報告。

示例 1:按天崩潰

在努力修復盡可能多的錯誤後,一位首席開發人員認為她的團隊終於準備好啟動他們的新照片共享應用程序。在他們這樣做之前,他們想檢查過去一個月每天的崩潰次數,以確保他們的 bug-bash 使應用程序隨著時間的推移更加穩定:

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";

迅速

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

爪哇

Crashlytics.setInt("current_level", 3);

在 BigQuery 導出中使用該鍵,然後他們編寫一個查詢來報告與每個崩潰事件相關的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 提取

開發人員有一個處於早期訪問階段的應用程序。他們的大多數用戶都喜歡它,但其中三個用戶經歷了異常數量的崩潰。為了解決問題,他們編寫了一個查詢,使用用戶 ID 為這些用戶提取所有崩潰事件:

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

示例 6:查找面臨特定崩潰問題的所有用戶

開發人員向一組 Beta 測試人員發布了一個嚴重錯誤。該團隊能夠使用上述示例 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:受崩潰問題影響的用戶數量,按國家/地區細分

現在,團隊在推出新版本期間發現了一個嚴重錯誤。他們能夠使用上面示例 2 中的查詢來識別特定的崩潰問題 ID。該團隊現在想看看這次崩潰是否已經蔓延到全球不同國家的用戶。

要編寫此查詢,團隊需要:

  1. 為 Google Analytics 啟用 BigQuery 導出。請參閱將項目數據導出到 BigQuery

  2. 更新他們的應用程序以將用戶 ID 傳遞到 Google Analytics SDK 和 Crashlytics SDK。

    Objective-C
    CrashlyticsKit setUserIdentifier:@"123456789";
    FIRAnalytics setUserID:@"12345678 9";
    
    迅速
    Crashlytics.sharedInstance().setUserIdentifier("123456789");
    Analytics.setUserID("123456789");
    
    爪哇
    Crashlytics.setUserIdentifier("123456789");
    mFirebaseAnalytics.setUserId("123456789");
    
  3. 編寫一個查詢,該查詢使用用戶 ID 字段將 Google Analytics BigQuery 數據集中的事件與 Crashlytics BigQuery 數據集中的崩潰連接起來:

    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從兩個表中刪除任何常見事件。

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 會導出最近的事件(崩潰、非致命錯誤和 ANR),包括鏈接前最多兩天的事件,並可選擇回填最多九十天。

從那時起,直到您禁用鏈接,Firebase 每天都會導出 Crashlytics 事件。每次導出後,數據可能需要幾分鐘才能在 BigQuery 中可用。

數據集

Firebase Crashlytics 在 BigQuery 中為 Crashlytics 數據創建一個新數據集。數據集涵蓋您的整個項目,即使它有多個應用程序。

Firebase Crashlytics 會在數據集中為您項目中的每個應用創建一個表,除非您選擇不導出該應用的數據。 Firebase 根據應用的包標識符命名表,句點轉換為下劃線,並在末尾附加一個平台名稱。

例如,ID 為com.google.test的 Android 應用的數據將位於名為com_google_test_ANDROID的表中,實時數據(如果啟用)將位於名為com_google_test_ANDROID_REALTIME的表中

除了開發人員定義的任何自定義 Crashlytics 鍵之外,表還包含一組標準的 Crashlytics 數據。

表中的每一行代表應用程序遇到的一個錯誤。

對於崩潰、非致命錯誤和 ANR,表中的列是相同的。如果啟用了 Crashlytics BigQuery 流式導出,則實時表將具有與批處理表相同的列。下面列出了導出中的列。

沒有堆棧跟踪

行中的列表示沒有堆棧跟踪的事件。

字段名稱數據類型描述
平台細繩蘋果或安卓應用
bundle_identifier細繩捆綁包 ID,例如 com.google.gmail
event_id細繩事件的唯一 ID
is_fatal布爾值應用程序是否崩潰
錯誤類型細繩事件的錯誤類型(FATAL、NON_FATAL、AN​​R)
問題ID細繩與事件相關的問題
event_timestamp時間戳事件發生時
設備記錄發生事件的設備
設備製造商細繩設備製造商
設備模型細繩設備型號
設備架構細繩X86_32、X86_64、ARMV7、ARM64、ARMV7S 或 ARMV7K
記憶記錄設備的內存狀態
使用過的內存INT64使用的內存字節數
無記憶INT65剩餘內存字節數
貯存記錄設備的持久存儲
存儲使用INT64使用的存儲字節數
免存儲INT64剩餘存儲字節數
操作系統記錄設備的操作系統詳細信息
操作系統.display_version細繩操作系統版本
操作系統名稱細繩操作系統名稱
operating_system.modification_state細繩MODIFIED or UNMODIFIED,即設備是否已經越獄/root
操作系統類型細繩設備上的操作系統類型。例如IOS、MACOS
操作系統.device_type細繩設備的類型。例如手機、平板電腦、電視
應用記錄生成事件的應用
application.build_version細繩應用程序的構建版本
application.display_version細繩
用戶記錄可選:收集的應用用戶信息
用戶名細繩可選:用戶名
用戶郵箱細繩可選:用戶的電子郵件地址
用戶身份細繩可選:與用戶關聯的應用特定 ID
自定義鍵重複記錄開發人員定義的鍵值對
custom_keys.key細繩開發人員定義的密鑰
custom_keys.value細繩開發人員定義的值
安裝_uuid細繩標識唯一應用和設備安裝的 ID
crashlytics_sdk_versions細繩生成事件的 Crashlytics SDK 版本
app_orientation細繩肖像、風景、FACE_UP 或 FACE_DOWN
設備方向細繩肖像、風景、FACE_UP 或 FACE_DOWN
進程狀態細繩背景或前景
日誌重複記錄Crashlytics 記錄器生成的帶時間戳的日誌消息(如果啟用)
日誌.時間戳時間戳什麼時候做的日誌
日誌消息細繩記錄的消息
麵包屑重複記錄帶時間戳的 Google Analytics 麵包屑(如果已啟用)
麵包屑.時間戳時間戳與麵包屑關聯的時間戳
麵包屑名稱細繩與麵包屑關聯的名稱
麵包屑.params重複記錄與麵包屑關聯的參數
麵包屑.params.key細繩與麵包屑關聯的參數鍵
麵包屑.params.value細繩與麵包屑關聯的參數值
責備框架記錄識別為崩潰或錯誤根本原因的幀
blame_frame.line INT64框架文件的行號
責備框架文件細繩框架文件的名稱
blame_frame.symbol細繩水合符號,如果不可水合,則為原始符號
blame_frame.offset INT64包含代碼的二進製圖像中的字節偏移量,Java 異常未設置
blame_frame.address INT64包含代碼的二進製圖像中的地址,對於 Java 幀未設置
blame_frame.library細繩包含框架的庫的顯示名稱
blame_frame.owner細繩開發者、供應商、運行時、平台或系統
blame_frame.blamed布爾值Crashlytics 的分析是否確定此幀是導致崩潰或錯誤的原因
例外重複記錄僅限 Android:此事件期間發生的異常。嵌套異常按時間倒序呈現(閱讀:最後一條記錄是第一個拋出的異常)
異常類型細繩異常類型,例如 java.lang.IllegalStateException
exceptions.exception_message細繩與異常關聯的消息
異常嵌套布爾值對除最後拋出的異常(即第一條記錄)之外的所有異常都是正確的
exceptions.title細繩線程的標題
exceptions.subtitle細繩線程的副標題
exceptions.blamed布爾值如果 Crashlytics 確定異常是導致錯誤或崩潰的原因,則為真
異常.frames重複記錄與異常關聯的幀
exceptions.frames.line INT64框架文件的行號
異常框架文件細繩框架文件的名稱
exceptions.frames.symbol細繩水合符號,如果不可水合,則為原始符號
exceptions.frames.offset INT64包含代碼的二進製圖像中的字節偏移量,Java 異常未設置
exceptions.frames.address INT64包含代碼的二進製圖像中的地址,對於 Java 幀未設置
exceptions.frames.library細繩包含框架的庫的顯示名稱
exceptions.frames.owner細繩開發者、供應商、運行時、平台或系統
exceptions.frames.blamed布爾值Crashlytics 的分析是否確定此幀是導致崩潰或錯誤的原因
錯誤重複記錄僅限 Apple 應用程序:非致命錯誤
error.queue_name細繩線程正在運行的隊列
錯誤代碼INT64與應用程序的自定義記錄的 NSError 關聯的錯誤代碼
錯誤標題細繩線程的標題
error.subtitle細繩線程的副標題
錯誤歸咎於布爾值Crashlytics 的分析是否確定此框架是錯誤的原因
錯誤幀重複記錄堆棧跟踪的幀
error.frames.line INT64框架文件的行號
錯誤幀文件細繩框架文件的名稱
error.frames.symbol細繩水合符號,如果不可水合,則為原始符號
error.frames.offset INT64包含代碼的二進製圖像的字節偏移量
錯誤幀地址INT64包含代碼的二進製圖像中的地址
error.frames.library細繩包含框架的庫的顯示名稱
error.frames.owner細繩開發者、供應商、運行時、平台或系統
error.frames.blamed布爾值Crashlytics 的分析是否確定此框架是錯誤的原因
線程重複記錄事件發生時出現的線程
線程.崩潰布爾值線程是否崩潰
線程.thread_name細繩線程的名稱
線程.queue_name細繩僅限 Apple 應用程序:線程正在運行的隊列
線程.signal_name細繩導致應用程序崩潰的信號名稱,僅出現在崩潰的本機線程上
線程.signal_code細繩導致應用崩潰的信號代碼;僅出現在崩潰的本機線程上
線程.crash_address INT64導致應用程序崩潰的信號地址;僅出現在崩潰的本機線程上
線程代碼INT64僅限 Apple 應用程序:應用程序自定義記錄的 NSError 的錯誤代碼
線程.title細繩線程的標題
線程.副標題細繩線程的副標題
線程.責備布爾值Crashlytics 的分析是否確定此幀是導致崩潰或錯誤的原因
線程.frames重複記錄線程的框架
線程.frames.line INT64框架文件的行號
線程框架文件細繩框架文件的名稱
線程.frames.symbol細繩水合符號或原始符號(如果不可水合)
線程.frames.offset INT64包含代碼的二進製圖像的字節偏移量
線程.幀.地址INT64包含代碼的二進製圖像中的地址
線程.frames.library細繩包含框架的庫的顯示名稱
線程.frames.owner細繩開發者、供應商、運行時、平台或系統
線程.frames.blamed布爾值Crashlytics 的分析是否確定此框架是錯誤的原因

使用 Data Studio 可視化導出的 Crashlytics 數據

Google Data Studio將您在 BigQuery 中的 Crashlytics 數據集轉換為易於閱讀、易於共享且完全可定制的報告。

要了解有關使用 Data Studio 的更多信息,請嘗試 Data Studio 快速入門指南Welcome to Data Studio

使用 Crashlytics 報告模板

數據洞察有一個 Crashlytics 示例報告,其中包含來自導出的 Crashlytics BigQuery 架構的一組全面的維度和指標。如果您啟用了 Crashlytics BigQuery 流式導出,則可以在 Data Studio 模板的實時趨勢頁面上查看該數據。您可以使用該示例作為模板,根據您自己應用的原始崩潰數據快速創建新報告和可視化:

  1. 打開Crashlytics Data Studio 儀表板模板
  2. 單擊右上角的使用模板
  3. 新數據源下拉列表中,選擇創建新數據源
  4. 點擊BigQuery卡片上的選擇
  5. 通過選擇My Projects > [your-project-name] > firebase_crashlytics > [your-table-name]選擇包含導出的 Crashlytics 數據的表。您的批處理表始終可供選擇;如果啟用了 Crashlytics BigQuery 流式導出,您可以改為選擇您的實時表。
  6. 配置下,將Crashlytics 模板級別設置為默認
  7. 單擊連接以創建新的數據源。
  8. 單擊添加到報告以返回到 Crashlytics 模板。
  9. 最後,單擊Create Report以創建 Crashlytics Data Studio Dashboard 模板的副本。