您可以將 Crashlytics 數據導出到BigQuery以進行進一步分析。 BigQuery 允許您使用 BigQuery SQL 分析數據,將其導出到另一個雲提供商,並將其用於 Google Data Studio 的可視化和自定義儀表板。
啟用 BigQuery 導出
- 轉到 Firebase 控制台中的集成頁面。
- 在BigQuery卡片中,點擊鏈接。
- 按照屏幕上的說明啟用 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 流式導出時,除了批處理表之外,您還將擁有一個實時表。以下是您應該注意的表之間的差異:
批處理表 | 實時表 |
---|---|
|
|
批處理表非常適合長期分析和識別隨時間推移的趨勢,因為我們在寫入事件之前會持久存儲事件,並且可以將它們回填到表中長達 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。該團隊現在想看看這次崩潰是否已經蔓延到全球不同國家的用戶。
要編寫此查詢,團隊需要:
為 Google Analytics 啟用 BigQuery 導出。請參閱將項目數據導出到 BigQuery 。
更新他們的應用程序以將用戶 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");
編寫一個查詢,該查詢使用用戶 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、ANR) |
問題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 模板的實時趨勢頁面上查看該數據。您可以使用該示例作為模板,根據您自己應用的原始崩潰數據快速創建新報告和可視化:
- 打開Crashlytics Data Studio 儀表板模板。
- 單擊右上角的使用模板。
- 在新數據源下拉列表中,選擇創建新數據源。
- 點擊BigQuery卡片上的選擇。
- 通過選擇My Projects > [your-project-name] > firebase_crashlytics > [your-table-name]選擇包含導出的 Crashlytics 數據的表。您的批處理表始終可供選擇;如果啟用了 Crashlytics BigQuery 流式導出,您可以改為選擇您的實時表。
- 在配置下,將Crashlytics 模板級別設置為默認。
- 單擊連接以創建新的數據源。
- 單擊添加到報告以返回到 Crashlytics 模板。
- 最後,單擊Create Report以創建 Crashlytics Data Studio Dashboard 模板的副本。