本文档介绍如何查找从 Cloud Logging 路由到 BigQuery 表的日志条目。Logging 接收器会将日志记录数据以小批量形式流式插入到 BigQuery 中,这样一来,您无需运行加载作业即可查询数据。为帮助您创建查询并了解 BigQuery 表的格式,本文档还介绍了用于路由日志的 BigQuery 架构。
Cloud Logging 使用旧版流式 API 将日志条目流式传输到 BigQuery。通常,日志条目会在一分钟内显示在 BigQuery 中。不过,创建新表后,可能需要几分钟时间才能看到第一批日志条目。
准备工作
如需查看接收器的概念讨论,请参阅路由和存储模型概览:接收器。
如需了解如何路由日志,请参阅将日志路由到支持的目的地。
如需了解已路由日志条目字段的命名方式,请参阅已路由日志的 BigQuery 架构。
查看日志
如需查看路由到 BigQuery 的日志,请执行以下操作:
-
在 Google Cloud 控制台中,前往 BigQuery 页面:
您也可以使用搜索栏查找此页面。
在浏览器面板中,展开您的项目并选择数据集。
日志条目显示在详细信息标签页中,您也可以通过查询表来返回数据。
查询示例
如需了解 BigQuery 查询语法,请参阅查询参考。表通配符函数(支持跨多个表进行查询)以及 Flatten 运算符(支持显示重复字段中的数据)特别有用。
Compute Engine 查询示例
以下 BigQuery 查询可检索数天内多种日志类型的日志条目:
该查询搜索日志
syslog
和apache-access
在过去三天内的条目。查询的执行日期是 2020 年 2 月 23 日,该查询涵盖了 2 月 21 日和 2 月 22 日接收的所有日志条目,以及 2 月 23 日截至查询发出那一刻所接收的日志条目。该查询检索单个 Compute Engine 实例
1554300700000000000
的结果。
SELECT timestamp AS Time, logName as Log, textPayload AS Message FROM (TABLE_DATE_RANGE(my_bq_dataset.syslog_, DATE_ADD(CURRENT_TIMESTAMP(), -2, 'DAY'), CURRENT_TIMESTAMP())), (TABLE_DATE_RANGE(my_bq_dataset.apache_access_, DATE_ADD(CURRENT_TIMESTAMP(), -2, 'DAY'), CURRENT_TIMESTAMP())) WHERE resource.type == 'gce_instance' AND resource.labels.instance_id == '1554300700000000000' ORDER BY time;
以下是部分示例输出行:
Row | Time | Log | Message --- | ----------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- 5 | 2020-02-21 03:40:14 UTC | projects/project-id/logs/syslog | Feb 21 03:40:14 my-gce-instance collectd[24281]: uc_update: Value too old: name = 15543007601548826368/df-tmpfs/df_complex-used; value time = 1424490014.269; last cache update = 1424490014.269; 6 | 2020-02-21 04:17:01 UTC | projects/project-id/logs/syslog | Feb 21 04:17:01 my-gce-instance /USR/SBIN/CRON[8082]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly) 7 | 2020-02-21 04:49:58 UTC | projects/project-id/logs/apache-access | 128.61.240.66 - - [21/Feb/2020:04:49:58 +0000] "GET / HTTP/1.0" 200 536 "-" "masscan/1.0 (https://github.com/robertdavidgraham/masscan)" 8 | 2020-02-21 05:17:01 UTC | projects/project-id/logs/syslog | Feb 21 05:17:01 my-gce-instance /USR/SBIN/CRON[9104]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly) 9 | 2020-02-21 05:30:50 UTC | projects/project-id/log/syslogapache-access | 92.254.50.61 - - [21/Feb/2020:05:30:50 +0000] "GET /tmUnblock.cgi HTTP/1.1" 400 541 "-" "-"
App Engine 查询示例
以下 BigQuery 查询可检索上个月失败的 App Engine 请求:
SELECT timestamp AS Time, protoPayload.host AS Host, protoPayload.status AS Status, protoPayload.resource AS Path FROM (TABLE_DATE_RANGE(my_bq_dataset.appengine_googleapis_com_request_log_, DATE_ADD(CURRENT_TIMESTAMP(), -1, 'MONTH'), CURRENT_TIMESTAMP())) WHERE protoPayload.status != 200 ORDER BY time
以下是部分结果:
Row | Time | Host | Status | Path --- | ----------------------- | ------------------------------------- | ------ | ------ 6 | 2020-02-12 19:35:02 UTC | default.my-gcp-project-id.appspot.com | 404 | /foo?thud=3 7 | 2020-02-12 19:35:21 UTC | default.my-gcp-project-id.appspot.com | 404 | /foo 8 | 2020-02-16 20:17:19 UTC | my-gcp-project-id.appspot.com | 404 | /favicon.ico 9 | 2020-02-16 20:17:34 UTC | my-gcp-project-id.appspot.com | 404 | /foo?thud=%22what???%22
路由日志的 BigQuery 架构
路由日志的 BigQuery 表架构基于 LogEntry
类型的结构和日志载荷的内容。Cloud Logging 还会应用规则来缩短审核日志和某些结构化载荷字段的 BigQuery 架构字段名称。您可以在 BigQuery 界面中选择包含路由日志条目的表,从而查看表架构。
字段命名惯例
将日志发送到 BigQuery 时,有以下几个命名惯例适用于日志条目字段:
日志条目字段名称不能超过 128 个字符。
日志条目字段名称只能由字母数字字符组成。所有不受支持的字符会从字段名称中移除,并替换为下划线字符。例如,
jsonPayload.foo%%
将转变成jsonPayload.foo__
。日志条目字段名称必须以字母数字字符开头,即使在转换后也是如此;任何前导下划线都会被移除。
对于属于
LogEntry
类型的日志条目字段,对应的 BigQuery 字段名称与日志条目字段完全相同。对于用户提供的任何日志条目字段,相应的 BigQuery 字段名称都会标准化为小写,但命名会保留下来。
对于结构化载荷中的字段,只要不存在
@type
说明符,相应的 BigQuery 字段名称就会标准化为小写,而命名则保留下来。如需了解存在
@type
说明符的结构化负载,请参阅本页面上的带有@type
的负载字段。
以下示例展示了这些命名惯例是如何应用的:
日志条目字段 | LogEntry 类型映射 |
BigQuery 字段名称 |
---|---|---|
insertId |
insertId |
insertId |
textPayload |
textPayload |
textPayload |
httpRequest.status |
httpRequest.status |
httpRequest.status |
httpRequest.requestMethod.GET |
httpRequest.requestMethod.[ABC] |
httpRequest.requestMethod.get |
resource.labels.moduleid |
resource.labels.[ABC] |
resource.labels.moduleid |
jsonPayload.MESSAGE |
jsonPayload.[ABC] |
jsonPayload.message |
jsonPayload.myField.mySubfield |
jsonPayload.[ABC].[XYZ] |
jsonPayload.myfield.mysubfield |
带有 @type
的载荷字段
本部分介绍了负载包含说明符 @type
的日志条目的特殊 BigQuery 架构字段名称。这包括路由到 BigQuery 的审核日志条目。
日志条目中的载荷可以包含结构化数据。任何结构化字段都可以包含以下格式的可选类型说明符:
@type: type.googleapis.com/[TYPE]
命名规则说明了审核日志条目的 protoPayload
字段可能对应于 BigQuery 架构字段 protopayload_auditlog
的原因。
@type
的命名规则
具有类型说明符的结构化字段通常被赋予 BigQuery 字段名称,其字段名称附加了 [TYPE]
。[TYPE]
的值可以是任何字符串。
@type
的命名规则仅适用于 jsonPayload
或 protoPayload
的顶级;忽略嵌套字段。在处理顶级结构化载荷字段时,Logging 会移除前缀 type.googleapis.com
。
例如,下表显示了顶级结构化负载字段到 BigQuery 字段名称的对应关系:
负载 | 负载 @type | 负载字段 | BigQuery 字段名称 |
---|---|---|---|
jsonPayload |
(无) | statusCode |
jsonPayload.statusCode |
jsonPayload |
type.googleapis.com/abc.Xyz |
statusCode |
jsonpayload_abc_xyz.statuscode |
protoPayload |
(无) | statusCode |
protoPayload.statuscode |
protoPayload |
type.googleapis.com/abc.Xyz |
statusCode |
protopayload_abc_xyz.statuscode |
对于具有类型说明符的字段,有一些例外情况适用于上述规则:
在 App Engine 请求日志中,路由到 BigQuery 的日志中的载荷名称为
protoPayload
,即使该载荷具有类型说明符也是如此。Cloud Logging 会应用一些特殊规则来缩短审核日志的 BigQuery 架构字段名称的长度。这种情况在本页面的审核日志字段部分进行了说明。
示例
下面的示例展示了结构化载荷字段在 BigQuery 接收后的命名方式和使用方式。
假设某个日志条目负载的结构如下:
jsonPayload: {
@type: "type.googleapis.com/google.cloud.v1.CustomType"
name_a: {
sub_a: "A value"
}
name_b: {
sub_b: 22
}
}
与 BigQuery 字段的对应关系如下所示:
顶级结构化字段
jsonPayload
包含@type
说明符。其 BigQuery 名称为jsonpayload_v1_customtype
。嵌套字段使用标准 BigQuery 命名规则进行处理,因为类型说明符规则不适用于嵌套字段。
因此,系统为该日志条目的载荷定义了以下 BigQuery 名称:
jsonpayload_v1_customtype
jsonpayload_v1_customtype._type
jsonpayload_v1_customtype.name_b
jsonpayload_v1_customtype.name_b.sub_b
jsonpayload_v1_customtype.name_a
jsonpayload_v1_customtype.name_a.sub_a
审核日志字段
如果您不使用已路由到 BigQuery 的审核日志,则可以跳过本部分。
审核日志负载字段 protoPayload.request
、protoPayload.response
和 protoPayload.metadata
具有 @type
说明符,但被视为 JSON 数据。也就是说,这些字段的 BigQuery 架构名称是附加了 Json
的字段名称,其中包含 JSON 格式的字符串数据。
下表列出了两组审核日志负载字段名称:
日志条目字段 | BigQuery 字段名称 |
---|---|
protoPayload |
protopayload_auditlog |
protopayload.metadata |
protopayload_auditlog.metadataJson |
protoPayload.serviceData |
protopayload_auditlog.servicedata_v1_bigquery 示例: protopayload_auditlog.servicedata_v1_bigquery.tableInsertRequest |
protoPayload.request |
protopayload_auditlog.requestJson |
protoPayload.response |
protopayload_auditlog.responseJson |
请注意,serviceData
命名惯例针对的是由 BigQuery 生成并随后从 Cloud Logging 路由到 BigQuery 的审核日志。这些审核日志条目包含 serviceData
字段,其 @type 说明符为 type.googleapis.com/google.cloud.bigquery.logging.v1.auditdata
。
示例
BigQuery 生成的审核日志条目有一个字段,名称如下:
protoPayload.serviceData.tableInsertRequest
如果随后此日志条目路由到 BigQuery,那么 tableInsertRequest
字段将被如何引用?在名称长度缩短之前,BigQuery 中的相应字段名称将如下所示:
protopayload_google_cloud_audit_auditlog.servicedata_google_cloud_bigquery_logging_v1_auditdata.tableInsertRequest
在名称长度缩短之后,BigQuery 表中会出现同一字段,如下所示:
protopayload_auditlog.servicedata_v1_bigquery.tableInsertRequest
整理表
本部分简要介绍了路由到 BigQuery 的日志的分区表。
将日志路由到 BigQuery 数据集时,Logging 会创建表来保存日志条目。BigQuery 收到的第一个日志条目决定了目标 BigQuery 表的架构。BigQuery 会创建一个表,该表的列基于第一个日志条目的字段和字段类型。后续的日志条目可能会导致架构不匹配。如需了解这些问题何时发生以及如何处理,请参阅架构中不匹配。
Logging 使用两种表类型整理其路由的数据,这两种类型分别为:日期分片表和分区表。这两种表类型都会根据日志条目的 timestamp
字段对日志数据进行分区。但是,这两种表类型之间存在两个主要区别,如下所示:
性能:分区表会将较大的表划分为较小的分区,以便提高查询性能,从而通过减少查询读取的字节数来更好地控制 BigQuery 费用。
表命名法:这些表类型采用不同的命名惯例,如以下部分所述。
整理表
日志条目被分片为 BigQuery 表,这些表的组织和名称基于条目的日志名称和时间戳。
表名称的后缀为日志条目的日历日期 [采用 ISO 8601 基本格式 (YYYYMMDD)]。
下表举例说明了日志名称和示例时间戳与 BigQuery 中表名称的对应关系:
日志名称 | 日志条目 timestamp 1 |
BigQuery 表名 (日期分片) |
BigQuery 表名 (分区) |
---|---|---|---|
syslog |
2017-05-23T18:19:22.135Z |
syslog_20170523 |
syslog |
apache-access |
2017-01-01T00:00:00.000Z |
apache_access_20170101 |
apache_access |
compute.googleapis.com/activity_log |
2017-12-31T23:59:59.999Z |
compute_googleapis_com_activity_log_20171231 |
compute_googleapis_com_activity_log |
1:日志条目时间戳以 UTC(世界协调时间)表示。
创建分区表
创建接收器以将日志路由到 BigQuery 时,您可以使用日期分片表或分区表。默认选项是日期分片表:
如需了解如何创建接收器,请参阅以下资源:
Google Cloud 控制台:将日志路由到支持的目的地。
架构不匹配
BigQuery 收到的第一个日志条目决定了目标 BigQuery 表的架构。BigQuery 会创建一个表,该表的列基于第一个日志条目的字段和字段类型。
当日志条目写入目标表以及发生以下任一错误时,会发生架构不匹配的情况:
后面的日志条目会更改表中现有字段的字段类型。
例如,如果初始日志条目的
jsonPayload.user_id
字段为string
,则该日志条目会生成一个表,其中包含该字段的字符串类型。如果您稍后开始将jsonPayload.user_id
记录为array
,则会导致架构不匹配。新的日志条目包含当前架构中不存在的字段,将该字段插入目标表将超出 BigQuery 列限制。
如果新字段不会导致超出列限制,则目标表可以接受新字段。
当 BigQuery 识别到架构不匹配时,会在相应的数据集中创建一个表来存储错误信息。表的类型决定了表的名称。对于日期分片表,命名格式为 export_errors_YYYYMMDD
。对于分区表,命名格式为 export_errors
。如需了解详情,请参阅整理表。
路由日志条目时,Logging 会将消息批量发送到 BigQuery。BigQuery 使用以下规则确定将当前消息批次中的日志条目写入哪个表:
当字段类型发生更改时,只有导致架构不匹配的日志条目才会写入错误表。当前消息批次中不会导致架构不匹配的日志条目会写入原始目标表。
超出列限制时,当前消息批次中的所有日志条目都会写入错误表。
错误表架构
错误表包含来自 LogEntry
的数据以及有关不匹配的信息:
logEntry
:包含完整的日志条目;但是,日志条目从 JSON 转换为字符串。schemaErrorDetail
:包含 BigQuery 返回的完整错误消息。sink
:包含日志接收器的完整资源路径。logName
:从LogEntry
中提取。timestamp
:从LogEntry
中提取。receiveTimestamp
:从LogEntry
中提取。severity
:从LogEntry
中提取。insertId
:从LogEntry
中提取。trace
:从LogEntry
中提取。resourceType
:从LogEntry
中提取。
Logging 通过以下方式向包含路由接收器的 Google Cloud 项目传达架构不匹配问题:
- 项目所有者会收到一封电子邮件。详细信息包括:Google Cloud 项目 ID、接收器名称和目标位置。
- Google Cloud 控制台“活动”页面会显示错误
Stackdriver Config error
。详细信息包括接收器名称和目标位置,以及指向导致错误的日志条目示例的链接。
避免日后出现字段类型不匹配的问题
如需更正后续日志条目的字段不匹配问题,请修复字段类型,使得它与当前架构匹配。如需了解如何修正字段类型,请参阅更改列的数据类型。
有时,字段类型无法更改,例如,您无法更改 Google Cloud 服务自动生成的日志的字段类型。为防止在您无法更改字段类型时出现架构不匹配,请重命名表或更改接收器的参数,以便 Logging 在其他数据集中重新创建该表。如需查看相关说明,请参阅管理接收器。
问题排查
如果接收器的目标位置缺少日志,或者您怀疑接收器未正确路由日志,请参阅排查日志路由问题。
价格
Cloud Logging 不会对将日志路由到受支持的目标位置收费;但目标位置可能会收费。除了 _Required
日志存储桶外,Cloud Logging 会对将日志流式传输到日志存储桶以及存储时间超过日志存储桶默认保留期限的部分收费。
Cloud Logging 不会对复制日志、定义日志范围或通过日志浏览器或 Log Analytics 页面发出的查询收费。
有关详情,请参阅以下文档:
- Cloud Logging 价格摘要
目标位置费用:
- 如果您在发送 Virtual Private Cloud 流日志后又从 Cloud Logging 中排除这些日志,则需支付 VPC 流日志生成费用。