您可以将 Firebase Crashlytics 数据导出到 BigQuery 以便进一步分析。借助 BigQuery,您可以使用 BigQuery SQL 分析数据,将其导出至其他云提供商,然后使用 Looker Studio 实现可视化并构建自定义信息中心。
您可以对导出的数据执行哪些操作?
BigQuery 导出的数据包含原始崩溃数据,其中包括设备类型、操作系统、异常(Android 应用)或错误(Apple 应用)和 Crashlytics 日志,以及其他数据。 您可以在本页后面部分查看导出的 Crashlytics 数据以及其表架构。
以下是一些示例,展示您可以如何使用导出的 Crashlytics 数据:
运行查询
您可以对 Crashlytics 数据运行查询,以生成报告,将崩溃事件数据汇总为更易理解的摘要。由于 Firebase 控制台的 Crashlytics 信息中心不提供这类报告,因此这些报告可以作为对崩溃数据分析与理解的补充。在本页面后面部分,您可以找到一些示例查询。使用 Looker Studio 模板
Crashlytics 提供一个预构建的 Looker Studio 模板,用于直观呈现导出的数据。创建视图
您可以使用 BigQuery 界面创建“视图”,它是由 SQL 查询定义的虚拟表。如需详细了解不同类型的视图及其创建方法,请参阅 BigQuery 文档。将 Crashlytics 专用数据与 Firebase 会话数据相结合
您还可以在设置 Crashlytics 数据导出时导出 Firebase 会话数据。使用这些会话数据可以更好地了解未发生崩溃问题的用户和未发生崩溃问题的会话。
流式导出到 BigQuery 的优势
默认情况下,数据会以每日批量导出的方式导出到 BigQuery。 此外,您还可以使用 BigQuery 流式传输实时流式传输 Crashlytics 数据和 Firebase 会话。您可以将其用于任何需要实时数据的用途,例如在实时信息中心内展示信息、实时观察发布情况,或者监控触发提醒和自定义工作流的应用问题。
启用向 BigQuery 的流式导出后,您还将获得实时表(除了批处理表之外)。这两种类型的表都具有相同的数据集架构,但批处理表和实时表之间存在一些重要区别:
| 批处理表 | 实时表 |
|---|---|
|
|
批处理表非常适合用于长期分析以及识别随时间推移而变化的趋势,因为我们在写入事件之前会先将事件数据持久存储,而且最多可在表中回填 30 天前的事件数据*。在将数据写入实时表时,我们会立即将其写入 BigQuery,因此这种表非常适合用于实时信息中心和自定义提醒。您可以使用拼接查询将这两种表结合使用,从而同时获享两者的优势。
默认情况下,实时表的分区过期时间为 30 天。如需了解如何修改此设置,请参阅 BigQuery 文档中的设置分区过期时间。
* 如需详细了解回填支持,请参阅升级到新的导出基础设施。
启用导出到 BigQuery
在 Firebase 控制台中,前往集成页面。
在 BigQuery 卡片中,点击关联。
按照屏幕上的说明启用导出到 BigQuery 的功能,包括以下选项:
如需更好地了解“未遇到崩溃问题的用户数”和“未发生崩溃问题的会话数”,请启用 Firebase 会话数据导出功能。
如需在 BigQuery 中近乎实时地访问 Crashlytics 数据和 Firebase 会话数据,请启用流式导出。
启用导出功能后会发生什么?
Firebase 会导出与 BigQuery 相关联的应用中的数据。
在设置期间,默认情况下,您项目中的所有应用都会关联到 BigQuery,但您也可以选择在设置期间不关联特定应用。
您以后向 Firebase 项目中添加的所有应用都会自动关联到 BigQuery。
您可以随时管理哪些应用可导出数据。
Firebase 会将数据导出到您在设置期间选择的数据集位置。
此位置同时适用于 Crashlytics 数据集和 Firebase 会话数据集(如果已启用会话数据导出)。
此位置仅适用于导出到 BigQuery 中的数据,它不会影响存储在 Firebase 控制台的 Crashlytics 信息中心或 Android Studio 中使用的数据的位置。
创建数据集后,将无法更改其位置,但可以将数据集复制到其他位置,或手动将数据集移动(重新创建)到其他位置。如需了解详情,请参阅更改现有导出的位置。
Firebase 会安排每日将您的批量数据同步到 BigQuery。
关联到 BigQuery 后,初始批量数据导出可能需要最多 48 小时。
无论您在 BigQuery 中是否设置了任何定期导出,每天都会进行一次每日同步。请注意,同步作业的时间和时长可能会发生变化,因此我们不建议您根据特定的导出时间安排下游操作或作业。
Firebase 会将您的现有数据的副本导出到 BigQuery。
对于每个关联应用,此导出都包括一个批处理表,其中包含每日同步的数据。
对于过去长达 30 天的时间里或您启用导出到 BigQuery 功能后的最近日期中产生的批处理表(以最新的为准),您可以手动安排数据回填。
请注意,如果您在 2024 年 10 月中旬之前启用了 Crashlytics 数据导出功能,则还可以回填到您启用导出功能之前的 30 天。
如果您启用 BigQuery 流式导出,则以下内容适用。
每个关联的应用还将拥有自己的实时表,其中包含持续更新的数据(除了用于每日批量导出的应用批处理表之外)。
启用流式传输后,数据可能需要最多 1 小时才能开始流式传输。
示例查询
示例 1:使用 Firebase 会话数据计算“未遇到崩溃问题”指标
在最新版本中,您对应用进行了重大改版,以解决关键用户历程中的崩溃问题。您收到了用户的好评,但希望获得定量证据来证明您的应用比以前更稳定。
“未遇到崩溃问题”指标可帮助您获取此信息。这些指标是重要的衡量标准,可帮助您了解应用的总体健康状况。借助 Firebase 会话数据和 Crashlytics 事件,您可以通过基本查询计算这些指标。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
特定版本的未遇到崩溃问题的用户数:
SELECT TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) AS event_date, (1 - (COUNT (DISTINCT installation_uuid) / COUNT (DISTINCT instance_id))) AS CFU FROM `PROJECT_ID.firebase_sessions.PACKAGE_NAME_ANDROID` AS sessions LEFT JOIN `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` AS crashlytics ON TIMESTAMP_TRUNC(_PARTITIONTIME,DAY) = TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) WHERE crashlytics.error_type="FATAL" AND crashlytics.application.display_version="APP_VERSION" AND sessions.application.display_version = "APP_VERSION" GROUP BY event_date ORDER BY event_date
过去一周(过去 168 小时)未发生崩溃问题的会话:
SELECT TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) AS event_date, (1 - (COUNT (DISTINCT crashlytics.event_id) / COUNT (DISTINCT sessions.session_id))) AS CFS FROM `PROJECT_ID.firebase_sessions.PACKAGE_NAME_ANDROID` AS sessions LEFT JOIN `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` AS crashlytics ON TIMESTAMP_TRUNC(_PARTITIONTIME,DAY) = TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) WHERE crashlytics.error_type="FATAL" AND _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 168 HOUR) AND _PARTITIONTIME < CURRENT_TIMESTAMP() GROUP BY event_date ORDER BY event_date
示例 2:每天的崩溃次数
在努力解决尽可能多的 bug 之后,您认为自己的团队终于做好了准备,可以推出全新的照片共享应用。在推出之前,您想检查一下过去一个月内每天的崩溃次数,以确保这次大规模的纠错让应用的运行更加稳定了。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT COUNT(DISTINCT event_id) AS number_of_crashes, FORMAT_TIMESTAMP("%F", event_timestamp) AS date_of_crashes FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` GROUP BY date_of_crashes ORDER BY date_of_crashes DESC LIMIT 30;
示例 3:查找最普遍的崩溃
为了适当排定生产计划的优先级,您需要找出应用中 10 个最普遍的崩溃。您可以生成一个查询,以提供相关数据。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
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 `PROJECT_ID.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;
示例 4:10 大易崩溃设备
秋季是新手机的发布季!贵公司知道,这也意味着又到了解决新设备特有的问题的季节,尤其是 Android 设备。为了针对很可能出现的兼容性问题而未雨绸缪,您编写了一个查询,可以识别过去一周(168 小时)里出现最多崩溃的 10 款设备。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT device.model, COUNT(DISTINCT event_id) AS number_of_crashes FROM `PROJECT_ID.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;
示例 5:按自定义键过滤
您是游戏开发者,想知道游戏崩溃次数最频繁的是哪个关卡。
为了跟踪该统计信息,您可以设置一个名为 current_level 的自定义 Crashlytics 键,并在用户每次进入新的关卡时更新该键。
Swift
Crashlytics.sharedInstance().setIntValue(3, forKey: "current_level");
Objective-C
CrashlyticsKit setIntValue:3 forKey:@"current_level";
Java
Crashlytics.setInt("current_level", 3);
在导出到 BigQuery 的数据中使用该键,您可以编写一个查询来报告与各个崩溃事件相关联的 current_level 值的分布情况。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT
COUNT(DISTINCT event_id) AS num_of_crashes,
value
FROM
`PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
UNNEST(custom_keys)
WHERE
key = "current_level"
GROUP BY
key,
value
ORDER BY
num_of_crashes DESC示例 6:用户 ID 提取
您有一个处于抢先体验阶段的 Android 应用。该应用的大多数用户都很喜欢它,但有三位用户遇到了异常数量的崩溃。为了确定该问题的根源,您编写了一个查询,按照用户 ID 拉取这些用户的所有崩溃事件。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT *
FROM
`PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
user.id IN ("USER_ID_1", "USER_ID_2", "USER_ID_3")
ORDER BY
user.id
示例 7:查找面临特定崩溃问题的所有用户
您的团队向一组 Beta 版测试人员发布的版本中包含一个严重 bug。您的团队可以使用上面“查找最普遍的崩溃”示例中的查询来识别这一特定崩溃问题的 ID。现在,您的团队想要运行查询来提取受此崩溃影响的应用用户列表。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT user.id as user_id
FROM
`PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
issue_id = "ISSUE_ID"
AND application.display_version = "APP_VERSION"
AND user.id != ""
ORDER BY
user.id;示例 8:受崩溃问题影响的用户数量,按国家/地区细分
您的团队在发布新版本期间发现了一个严重 bug。您可以使用上面“查找最普遍的崩溃”示例中的查询来识别特定崩溃问题的 ID。您的团队现在想要确认该崩溃是否已蔓延至全球不同国家/地区的用户。
为了编写此查询,您的团队将需要执行以下操作:
启用将 Google Analytics 数据导出到 BigQuery 的功能。请参阅将项目数据导出到 BigQuery。
更新应用以将用户 ID 传递到 Google Analytics SDK 和 Crashlytics SDK。
Swift
Crashlytics.sharedInstance().setUserIdentifier("123456789"); Analytics.setUserID("123456789");Objective-C
CrashlyticsKit setUserIdentifier:@"123456789"; FIRAnalytics setUserID:@"12345678 9";Java
Crashlytics.setUserIdentifier("123456789"); mFirebaseAnalytics.setUserId("123456789");编写一个查询,通过用户 ID 字段将 Google Analytics 数据集中的事件与 Crashlytics 数据集中的崩溃联接:
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和
IOS(而不是软件包名称和ANDROID)。SELECT DISTINCT c.issue_id, a.geo.country, COUNT(DISTINCT c.user.id) as num_users_impacted FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` c INNER JOIN `PROJECT_ID.analytics_TABLE_NAME.events_*` a on c.user.id = a.user_id WHERE c.issue_id = "ISSUE_ID" AND a._TABLE_SUFFIX BETWEEN '20190101' AND '20200101' GROUP BY c.issue_id, a.geo.country, c.user.id
示例 9:今天到现在为止的 5 大问题
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT issue_id, COUNT(DISTINCT event_id) AS events FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID_REALTIME` WHERE DATE(event_timestamp) = CURRENT_DATE() GROUP BY issue_id ORDER BY events DESC LIMIT 5;
示例 10:自 DATE 起至今(包括今天)的 5 大问题
您还可以将批量表和实时表与拼接查询结合使用,以便将实时信息添加到可靠的批量数据中。由于 event_id 是主键,因此您可以使用 DISTINCT event_id 对两个表中的任何常见事件进行重复数据删除。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT issue_id, COUNT(DISTINCT event_id) AS events FROM ( SELECT issue_id, event_id, event_timestamp FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID_REALTIME` UNION ALL SELECT issue_id, event_id, event_timestamp FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`) WHERE event_timestamp >= PARSE_TIMESTAMP("%Y_%m_%d", "YYYY_MM_DD") GROUP BY issue_id ORDER BY events DESC LIMIT 5;
使用 Looker Studio 直观呈现导出的 Crashlytics 数据
Looker Studio 可以将您在 BigQuery 中的 Crashlytics 数据集转换为更易阅读、便于共享且完全可自定义的报告。
如需详细了解如何使用 Looker Studio,请参阅其欢迎指南。
使用 Crashlytics 报告模板
Looker Studio 提供了一个面向 Crashlytics 的示例报告,其中包含一整套来自已导出 Crashlytics BigQuery 架构的维度和指标。如果您已启用从 Crashlytics 到 BigQuery 的流式导出,则可以在 Looker Studio 模板的实时趋势页面上查看这些数据。您可以将该示例作为模板,根据您的应用原始崩溃数据快速创建新报告并进行可视化展示:
点击右上角的使用模板。
在新数据源下拉列表中,选择创建新数据源。
点击 BigQuery 卡片上的选择。
选择一个包含导出的 Crashlytics 数据的表,方法是依次选择我的项目 > PROJECT_ID > firebase_crashlytics > TABLE_NAME。
您的批处理表格始终可供选择。如果启用了将 Crashlytics BigQuery 流式导出,那么您可以改为选择实时表。
在配置下,将 Crashlytics 模板级设置为默认。
点击连接,创建新的数据源。
点击添加到报告,以返回 Crashlytics 模板。
最后,点击创建报告,以创建 Crashlytics Looker Studio 信息中心模板的副本。
了解 BigQuery 中的架构
Firebase 会在 BigQuery 中为导出的数据创建新数据集:
Firebase 会话数据集(如果已启用导出会话数据)
Crashlytics 个数据集
Crashlytics 数据会导出到名为 firebase_crashlytics 的 BigQuery 数据集。该数据集涵盖整个项目,即使该项目包含多个应用。
表
默认情况下,Firebase 会在 Crashlytics 数据集内为项目中每个已关联至 BigQuery 的应用分别创建单独的表。
这些表的命名基于应用的标识符(将句点转换为下划线),并在末尾附加应用平台(_IOS 或 _ANDROID)。例如,软件包名称为 com.google.test 的 Android 应用的数据将存储在名为 com_google_test_ANDROID 的表中。
如果启用了向 BigQuery 的流式导出,则数据也将实时流式传输到附加了
_REALTIME的表中(例如com_google_test_ANDROID_REALTIME)。表中的每一行均表示应用中发生的事件,包括崩溃、非严重错误和 ANR。
除了您在应用中定义的任何自定义 Crashlytics 键之外,这些表还包含一组标准的 Crashlytics 数据。
行
表中的每一行都表示应用遇到的一个错误。
列
对于崩溃、非严重错误和 ANR,表中的列完全相同。
如果启用了 BigQuery 流式导出,则实时表中的列与批处理表中的列相同。
行中可能存在表示无堆栈轨迹的事件的列。
下表列出了导出的 Crashlytics 数据表中的字段:
| 字段名称 | 数据类型 | 说明 |
|---|---|---|
app_orientation |
STRING | 例如,PORTRAIT、LANDSCAPE、FACE_UP、FACE_DOWN 等。 |
application |
RECORD | 引发事件的应用 |
application.build_version |
STRING | 应用的版本号 |
application.display_version |
STRING | |
blame_frame |
RECORD | 被确定为崩溃或错误根本原因的帧 |
blame_frame.address |
INT64 | 包含代码的二进制图片中的地址 Java 帧未设置 |
blame_frame.blamed |
BOOLEAN | Crashlytics 是否已确定此帧是导致崩溃或错误的原因 |
blame_frame.file |
STRING | 帧文件的名称 |
blame_frame.library |
STRING | 包含帧的库的显示名 |
blame_frame.line |
INT64 | 帧文件的行号 |
blame_frame.offset |
INT64 | 包含代码的二进制图片中的字节偏移量 Java 异常未设置 |
blame_frame.owner |
STRING | 例如 DEVELOPER、VENDOR、RUNTIME、PLATFORM 或 SYSTEM |
blame_frame.symbol |
STRING | 水化合符号,或原始符号(如果无法水化合) |
breadcrumbs |
REPEATED RECORD | 带有时间戳的 Google Analytics 路径(如果已启用) |
breadcrumbs.name |
STRING | 与路径关联的名称 |
breadcrumbs.params |
REPEATED RECORD | 与路径关联的参数 |
breadcrumbs.params.key |
STRING | 与路径关联的参数键 |
breadcrumbs.params.value |
STRING | 与路径关联的参数值 |
breadcrumbs.timestamp |
TIMESTAMP | 与路径关联的时间戳 |
bundle_identifier |
STRING | 在 Firebase 项目中注册的应用的唯一标识符(例如 com.google.gmail对于 Apple 平台应用,这是应用的软件包 ID。 对于 Android 应用,这是应用的软件包名称。 |
crashlytics_sdk_versions |
STRING | 生成事件的 Crashlytics SDK 版本 |
custom_keys |
REPEATED RECORD | 开发者定义的键值对 |
custom_keys.key |
STRING | 开发者定义的密钥 |
custom_keys.value |
STRING | 开发者定义的值 |
device |
RECORD | 发生事件的设备 |
device_orientation |
STRING | 例如,PORTRAIT、LANDSCAPE、FACE_UP、FACE_DOWN 等。 |
device.architecture |
STRING | 例如 X86_32、X86_64、ARMV7、ARM64、ARMV7S 或 ARMV7K |
device.manufacturer |
STRING | 设备制造商 |
device.model |
STRING | 设备型号 |
error |
REPEATED RECORD | (仅限 Apple 应用)非严重错误 |
error_type |
STRING | 事件的错误类型(例如 FATAL、NON_FATAL、ANR 等) |
error.blamed |
BOOLEAN | Crashlytics 是否已确定此帧是导致错误的原因 |
error.code |
INT64 | 与应用自定义记录的 NSError 关联的错误代码 |
error.frames |
REPEATED RECORD | 堆栈轨迹的帧 |
error.frames.address |
INT64 | 包含代码的二进制图片中的地址 |
error.frames.blamed |
BOOLEAN | Crashlytics 是否已确定此帧是导致错误的原因 |
error.frames.file |
STRING | 帧文件的名称 |
error.frames.library |
STRING | 包含帧的库的显示名 |
error.frames.line |
INT64 | 帧文件的行号 |
error.frames.offset |
INT64 | 包含代码的二进制图片中的字节偏移量 |
error.frames.owner |
STRING | 例如 DEVELOPER、VENDOR、RUNTIME、PLATFORM 或 SYSTEM |
error.frames.symbol |
STRING | 水化合符号,或原始符号(如果无法水化合) |
error.queue_name |
STRING | 线程正在运行的队列 |
error.subtitle |
STRING | 线程的副标题 |
error.title |
STRING | 线程的标题 |
event_id |
STRING | 事件的唯一 ID |
event_timestamp |
TIMESTAMP | 事件发生的时间 |
exceptions |
REPEATED RECORD | (仅适用于 Android)此事件期间发生的异常。嵌套异常以反向时间顺序呈现,这意味着最后一条记录是抛出的第一个异常 |
exceptions.blamed |
BOOLEAN | 如果 Crashlytics 确定异常导致错误或崩溃,则为 true |
exceptions.exception_message |
STRING | 与异常关联的消息 |
exceptions.frames |
REPEATED RECORD | 与异常关联的帧 |
exceptions.frames.address |
INT64 | 包含代码的二进制图片中的地址 Java 帧未设置 |
exceptions.frames.blamed |
BOOLEAN | Crashlytics 是否已确定此帧是导致崩溃或错误的原因 |
exceptions.frames.file |
STRING | 帧文件的名称 |
exceptions.frames.library |
STRING | 包含帧的库的显示名 |
exceptions.frames.line |
INT64 | 帧文件的行号 |
exceptions.frames.offset |
INT64 | 包含代码的二进制图片中的字节偏移量 Java 异常未设置 |
exceptions.frames.owner |
STRING | 例如 DEVELOPER、VENDOR、RUNTIME、PLATFORM 或 SYSTEM |
exceptions.frames.symbol |
STRING | 水化合符号,或原始符号(如果无法水化合) |
exceptions.nested |
BOOLEAN | 对于除最后抛出的异常(即第一条记录)之外的所有异常都为 true |
exceptions.subtitle |
STRING | 线程的副标题 |
exceptions.title |
STRING | 线程的标题 |
exceptions.type |
STRING | 异常类型(例如 java.lang.IllegalStateException) |
firebase_session_id |
STRING | 与来自 Crashlytics 的事件对应的 Firebase 会话的自动生成的 ID |
installation_uuid |
STRING | 标识唯一应用和设备安装的 ID |
is_fatal |
BOOLEAN | 应用是否崩溃 |
issue_id |
STRING | 与事件相关的问题 |
logs |
REPEATED RECORD | 由 Crashlytics 日志记录器生成的带时间戳的日志消息(如果已启用) |
logs.message |
STRING | 记录的消息 |
logs.timestamp |
TIMESTAMP | 日志创建时间 |
memory |
RECORD | 设备的内存状态 |
memory.free |
INT64 | 剩余的内存字节数 |
memory.used |
INT64 | 使用的内存字节数 |
operating_system |
RECORD | 设备上的操作系统的详细信息 |
operating_system.device_type |
STRING | 设备的类型(例如 MOBILE、TABLET、TV 等);也称为“设备类别” |
operating_system.display_version |
STRING | 设备上的操作系统的版本 |
operating_system.modification_state |
STRING | 设备是否已经过修改(例如,越狱应用为 MODIFIED,而已启用 root 权限的应用为 UNMODIFIED) |
operating_system.name |
STRING | 设备上的操作系统的名称 |
operating_system.type |
STRING | (仅限 Apple 应用)设备上运行的操作系统类型(例如 IOS、MACOS 等) |
platform |
STRING | 在 Firebase 项目中注册的应用平台(有效值:IOS 或 ANDROID) |
process_state |
STRING | BACKGROUND 或 FOREGROUND |
storage |
RECORD | 设备的永久性存储空间 |
storage.free |
INT64 | 剩余的存储空间字节数 |
storage.used |
INT64 | 使用的存储空间字节数 |
threads |
REPEATED RECORD | 事件发生时显示的线程 |
threads.blamed |
BOOLEAN | Crashlytics 是否已确定此帧是导致崩溃或错误的原因 |
threads.code |
INT64 | (仅限 Apple 应用)应用的自定义记录 NSError 的错误代码 |
threads.crash_address |
INT64 | 导致应用崩溃的信号的地址;仅出现在崩溃的原生线程上 |
threads.crashed |
BOOLEAN | 线程是否崩溃 |
threads.frames |
REPEATED RECORD | 线程帧 |
threads.frames.address |
INT64 | 包含代码的二进制图片中的地址 |
threads.frames.blamed |
BOOLEAN | Crashlytics 是否已确定此帧是导致错误的原因 |
threads.frames.file |
STRING | 帧文件的名称 |
threads.frames.library |
STRING | 包含帧的库的显示名 |
threads.frames.line |
INT64 | 帧文件的行号 |
threads.frames.offset |
INT64 | 包含代码的二进制图片中的字节偏移量 |
threads.frames.owner |
STRING | 例如 DEVELOPER、VENDOR、RUNTIME、PLATFORM 或 SYSTEM |
threads.frames.symbol |
STRING | 水化合符号,或原始符号(如果无法水化合) |
threads.queue_name |
STRING | (仅限 Apple 应用)运行线程的队列 |
threads.signal_code |
STRING | 导致应用崩溃的信号的代码;仅出现在崩溃的原生线程上 |
threads.signal_name |
STRING | 导致应用崩溃的信号的名称,仅出现在崩溃的原生线程上 |
threads.subtitle |
STRING | 线程的副标题 |
threads.thread_name |
STRING | 线程的名称 |
threads.title |
STRING | 线程的标题 |
unity_metadata.debug_build |
BOOLEAN | 指示该 build 是否为调试 build |
unity_metadata.graphics_copy_texture_support |
STRING | 支持以 Unity API 中定义的方式复制图形纹理 |
unity_metadata.graphics_device_id |
INT64 | 图形设备的标识符 |
unity_metadata.graphics_device_name |
STRING | 图形设备的名称 |
unity_metadata.graphics_device_type |
STRING | 图形设备的类型 |
unity_metadata.graphics_device_vendor_id |
INT64 | 图形处理器供应商的标识符 |
unity_metadata.graphics_device_vendor |
STRING | 图形设备的供应商 |
unity_metadata.graphics_device_version |
STRING | 图形设备的版本 |
unity_metadata.graphics_max_texture_size |
INT64 | 纹理渲染专用大小上限 |
unity_metadata.graphics_memory_size_mb |
INT64 | 图形内存(以 MB 为单位) |
unity_metadata.graphics_render_target_count |
INT64 | 图形渲染目标的数量 |
unity_metadata.graphics_shader_level |
INT64 | 图形着色器级别 |
unity_metadata.processor_count |
INT64 | 处理器(内核)数量 |
unity_metadata.processor_frequency_mhz |
INT64 | 处理器的频率(以 MHz 为单位) |
unity_metadata.processor_type |
STRING | 处理器类型 |
unity_metadata.screen_refresh_rate_hz |
INT64 | 屏幕的刷新率(以 Hz 为单位) |
unity_metadata.screen_resolution_dpi |
STRING | 屏幕的 DPI(以浮点数表示) |
unity_metadata.screen_size_px |
STRING | 屏幕大小(以像素为单位),格式为“宽 x 高” |
unity_metadata.system_memory_size_mb |
INT64 | 系统内存的大小(以 Mb 为单位) |
unity_metadata.unity_version |
STRING | 此设备上运行的 Unity 版本 |
user |
RECORD | (可选)收集的应用用户信息 |
user.email |
STRING | (可选)用户的电子邮件地址 |
user.id |
STRING | (可选)与用户关联的特定应用的 ID |
user.name |
STRING | (可选)用户的姓名 |
variant_id |
STRING | 与此事件相关的问题变体 请注意,并非所有事件都有关联的问题变体。 |
Firebase 会话数据集
Firebase 会话数据会导出到名为 firebase_sessions 的 BigQuery 数据集。该数据集涵盖整个项目,即使该项目包含多个应用。
表
默认情况下,Firebase 会在 Firebase 会话数据集内为项目中每个已关联至 BigQuery 的应用分别创建单独的表。
这些表的命名基于应用的标识符(将句点转换为下划线),并在末尾附加应用平台(_IOS 或 _ANDROID)。例如,软件包名称为 com.google.test 的 Android 应用的数据将存储在名为 com_google_test_ANDROID 的表中。
行
表中的每一行都表示发生过的一个会话事件。
列
如果启用了 BigQuery 流式导出,则实时表中的列与批处理表中的列相同。
下表列出了导出的 Firebase 会话数据表中的列:
| 字段名称 | 数据类型 | 说明 |
|---|---|---|
instance_id |
STRING | 设备中的 Firebase 安装 ID (FID)。标识唯一应用 + 设备安装 |
session_id |
STRING | 相应会话的唯一 ID |
first_session_id |
STRING |
自应用冷启动以来,相应会话所属的一系列会话中的第一个 ID。可用于对自冷启动以来发生的所有会话进行分组。如果相应会话是首次会话,则此字段将与 session_id 相同。
|
session_index |
INTEGER |
相应会话在应用冷启动后按顺序排列的位置。对于冷启动后的第一个会话,此值为 0。每次生成会话时,如果未发生冷启动(例如,在不活动 30 分钟后),该指数都会递增。
|
event_type |
STRING |
会话中发生的事件的类型(例如 SESSION_START)
|
event_timestamp |
TIMESTAMP | 事件发生的时间 |
received_timestamp |
TIMESTAMP | 服务器从设备接收到事件的时间 |
performance_data_collection_enabled |
BOOLEAN | 在会话期间,Firebase Performance Monitoring SDK 数据收集是否已启用 |
crashlytics_data_collection_enabled |
BOOLEAN | 会话期间是否启用了 Firebase Crashlytics SDK 数据收集功能 |
application |
RECORD | 描述应用 |
application.build_version |
STRING |
应用的版本号(例如 1523456)
|
application.display_version |
STRING |
应用的显示版本(例如 4.1.7)
|
device |
RECORD | 发生事件的设备 |
device.model |
STRING | 设备的型号 |
device.manufacturer |
STRING |
设备的制造商。对于 Apple 平台应用,此值将为 NULL。
|
operating_system |
RECORD | 描述设备的操作系统 |
operating_system.display_version |
STRING |
操作系统的显示版本(例如 10.2.1)
|
operating_system.name |
STRING | 操作系统的名称 |
operating_system.type |
STRING |
操作系统的类型(例如 IOS)。此字段仅针对 Apple 设备设置。
|
operating_system.device_type |
STRING |
设备的类型(例如 MOBILE、TABLET、TV)
|
升级到新的导出基础设施
2024 年 10 月中旬,Crashlytics 推出了一种新基础设施,用于将 Crashlytics 数据批量导出到 BigQuery。
所有 Firebase 项目最早将于 2025 年 9 月 15 日自动升级到新的批量导出基础架构。您也可以在此日期之前进行升级,不过需要确保您的 BigQuery 批处理表满足升级的前提条件。
您可以升级到新基础设施,但请确保您的 BigQuery 批处理表满足升级的前提条件。
确定您是否使用的是新基础设施
如果您是在 2024 年 10 月中旬或之后启用了批量导出功能,则您的 Firebase 项目会自动使用新的导出基础设施。
您可以查看项目使用的是哪种基础设施:前往 Google Cloud 控制台,如果“数据传输配置”标记为 Firebase Crashlytics with Multi-Region Support,则表示您的项目在使用新的导出基础设施。
旧导出基础设施与新导出基础设施之间的重要区别
新基础设施支持美国以外的 Crashlytics 数据集位置。
在 2024 年 10 月中旬之前启用了导出功能,并且升级到了新的导出基础设施 - 您现在可以选择更改数据导出位置。
在 2024 年 10 月中旬或之后启用了导出功能 - 在设置期间,系统会提示您选择数据导出位置。
新基础设施不支持回填您启用导出功能之前存在的数据。
旧基础设施支持回填导出功能启用日期之前长达 30 天的数据。
新基础设施支持回填过去长达 30 天的数据或自您最近启用导出到 BigQuery 功能后所产生的数据(以较近的日期为准)。
新基础设施会使用为 Firebase 项目中的 Firebase 应用设置的标识符为 BigQuery 批处理表命名。
旧基础设施会根据应用二进制文件中的软件包 ID 或软件包名称,将数据写入具有相应名称的批处理表。
新基础设施会根据为 Firebase 项目中注册的 Firebase 应用设置的软件包 ID 或软件包名称,将数据写入具有相应名称的批处理表。
第 1 步:升级的前提条件
检查您的现有 BigQuery 批处理表使用的标识符是否与为 Firebase 项目中注册的 Firebase 应用设置的软件包 ID 或软件包名称匹配。如果不匹配,则导出的批量数据可能会中断。大多数项目都将处于适当且兼容的状态,但在升级之前进行检查非常重要。
您可以在 Firebase 控制台中找到在 Firebase 项目中注册的所有 Firebase 应用:前往 项目设置,然后滚动到“您的应用”卡片,查看您的所有 Firebase 应用及其信息。
您可以在 Google Cloud 控制台的 BigQuery 页面中找到所有 BigQuery 批处理表。
例如,以下是升级时不会出现任何问题的理想状态:
您有一个名为
com_yourcompany_yourproject_IOS的批处理表,以及一个在 Firebase 项目中注册的 Firebase iOS+ 应用,其软件包 ID 为com.yourcompany.yourproject。您有一个名为
com_yourcompany_yourproject_ANDROID的批处理表,以及一个在 Firebase 项目中注册的 Firebase Android 应用,其软件包名称为com.yourcompany.yourproject。
如果您的批处理表名称与为注册的 Firebase 应用设置的标识符不匹配,那么您需要在进行手动升级之前或者在 2025 年 9 月 15 日之前,按照本页面后面部分的说明进行相应的操作,以免批量导出中断。
第 2 步:手动升级到新基础设施
如果您在 2024 年 10 月中旬之前启用了批量导出功能,那么只需在 Firebase 控制台中关闭 Crashlytics 数据导出功能,然后再重新开启该功能,即可手动升级到新基础设施。
下面是详细步骤:
在 Firebase 控制台中,前往集成页面。
在 BigQuery 卡片中,点击管理。
将 Crashlytics 滑块切换到“关闭”位置以停用导出功能。出现提示时,确认您要停止数据导出。
立即再次将 Crashlytics 滑块切换到“开启”位置以重新启用导出功能。出现提示时,确认您要导出数据。
您导出到 BigQuery 的 Crashlytics 数据现在使用新的导出基础设施。