3. Cloud Logging日志采集与查询

Cloud Logging 的核心工作可以概括为一条“采集—路由—存储—查询—保留”的链路。理解这条链路,才能在生产故障诊断中快速定位日志、控制成本,并保证关键日志不被误删。本节围绕日志路由、日志接收器、日志浏览器、LQL 查询语法以及日志排除与保留策略展开,重点说明它们之间的数据流关系与实际操作方式。

日志从哪里来:采集入口与日志桶

在 Google Cloud 中,日志首先由各服务写入 Cloud Logging。常见的日志来源包括 Compute Engine 的串行控制台输出与 Ops Agent 采集的系统/应用日志、GKE 的容器标准输出、Cloud Run 的请求日志、VPC Flow Logs、Cloud Audit Logs 以及各类托管服务的运行日志。这些日志进入 Logging 后,会先落入一个默认的 _Default 日志桶,同时审计日志还会进入 _Required 桶。日志桶是日志的存储单元,也是保留策略和排除策略的作用对象。

需要区分两个概念:日志路由器(Log Router)负责决定日志“去哪里”,日志桶负责日志“存多久、是否被排除”。默认情况下,所有日志都会进入 _Default 桶,但并非所有日志都值得长期保留。因此,实际生产中通常先通过排除策略过滤噪声,再通过接收器把有价值的日志分流到不同目的地。

日志接收器:把日志路由到正确的位置

日志接收器(Log Sink)是日志路由的核心对象。一个接收器由三部分组成:包含过滤器(决定哪些日志进入该接收器)、排除过滤器(在包含基础上进一步剔除)、目的地(日志最终写入哪里)。常见目的地包括 Cloud Logging 日志桶、BigQuery 数据集、Cloud Storage 存储桶和 Pub/Sub 主题。

例如,要把 GKE 中 namespace=prod 的错误日志长期保存到 BigQuery 供分析,可以创建如下接收器:

gcloud logging sinks create prod-error-to-bq \
  bigquery.googleapis.com/projects/my-proj/datasets/prod_logs \
  --log-filter='resource.type="k8s_container"
    resource.labels.namespace_name="prod"
    severity>=ERROR'

创建后,接收器会生成一个服务账号,需要为该账号授予目标数据集的写入权限,否则日志无法真正写入。这是实际配置中最容易遗漏的一步。接收器的过滤条件使用与 LQL 相同的语法,因此掌握 LQL 是配置接收器的前提。

Cloud Logging 日志采集与路由数据流 日志来源 Compute Engine GKE 容器日志 Cloud Run / VPC Flow Audit Logs 日志路由器 Log Router 包含过滤器 排除过滤器 目的地选择 日志接收器 Log Sink _Default 桶 BigQuery 数据集 Cloud Storage Pub/Sub 主题 查询与分析 日志浏览器 LQL 查询 告警 / 图表 排除与保留策略 排除过滤器:丢弃低价值日志,降低费用 保留策略:按桶设置 30 / 90 / 365 天 关键关系: 日志先进入 _Default 桶 → 接收器按过滤条件分流 → 排除策略在写入前丢弃噪声 → 保留策略决定各桶日志存活时长。 查询时通过日志浏览器或 LQL 在已保留的日志中检索,接收器目的地决定日志能否被 BigQuery / Pub/Sub 进一步消费。

日志浏览器与 LQL 查询语法

日志浏览器(Logs Explorer)是日常排查的主要界面。它提供资源、严重级别、时间范围等筛选器,但真正灵活的是查询栏中的 LQL(Logging Query Language)。LQL 的基本形式是“字段 运算符 值”,多个条件之间用 AND、OR、NOT 组合,并可用括号控制优先级。

常用字段包括 resource.type、resource.labels.*、severity、logName、timestamp、jsonPayload.*、textPayload 等。例如,查找生产命名空间中最近一小时的错误日志:

resource.type="k8s_container"
resource.labels.namespace_name="prod"
severity>=ERROR
timestamp>="2025-01-15T10:00:00Z"

LQL 还支持全局搜索、子串匹配和正则表达式。全局搜索直接写关键词即可,例如 "connection refused";子串匹配使用 :,如 jsonPayload.message:"timeout";正则使用 =~,如 jsonPayload.path=~"/api/v[12]/.*"。需要注意,severity>=ERROR 中的比较是按严重级别枚举顺序进行的,而不是字符串比较。

在排查时,一个高效的做法是先用宽条件缩小资源与时间范围,再逐步叠加字段条件。例如先查 resource.type="k8s_container",确认日志存在后,再加入 severity>=ERROR 和具体 jsonPayload 字段。这样既能避免查询超时,也能快速判断是“没有日志”还是“过滤条件写错”。

日志排除与保留策略

日志量增长会直接推高费用,因此排除策略是成本控制的关键。排除策略可以设置在日志桶上,也可以设置在接收器上。桶级排除会影响该桶内所有日志,接收器级排除只影响该接收器分流的部分。常见做法是排除健康检查、调试级别日志和已知噪声:

resource.type="http_load_balancer"
httpRequest.requestUrl:"/healthz"

保留策略决定日志在桶中保存多久。默认桶通常保留 30 天,_Required 桶中的审计日志保留 400 天且不可修改。对于需要长期合规保留的日志,可以创建自定义日志桶并设置更长保留期,例如 365 天,同时把接收器指向该桶。需要特别注意的是,排除策略一旦生效,被排除的日志不会写入桶,也无法通过查询找回;而保留策略到期后日志会被删除。因此,在配置排除前应先确认该日志是否用于审计、计费或故障复盘。

排除策略是不可逆的:被排除的日志不会进入日志桶,也不会出现在日志浏览器中。建议先在测试项目验证过滤条件,再应用到生产环境。

一个可复用的排查流程

结合以上机制,生产故障排查可以按以下顺序进行:第一,确认日志是否被排除策略丢弃,检查桶级和接收器级排除规则;第二,在日志浏览器中用资源类型和时间范围定位日志;第三,用 LQL 叠加严重级别和关键字段缩小范围;第四,若日志已分流到 BigQuery,可用 SQL 做聚合分析;第五,检查保留策略是否导致历史日志缺失。这个顺序能避免在错误的方向上浪费时间。

机制 作用对象 典型配置 对排查的影响
日志接收器 日志路由器 过滤条件 + 目的地 决定日志能否被 BigQuery / Pub/Sub 消费
排除策略 桶或接收器 排除过滤器 被排除日志无法查询,需提前确认
保留策略 日志桶 30 / 90 / 365 天 到期删除,影响历史回溯范围
LQL 查询与接收器过滤 字段 + 运算符 + 值 决定检索精度与查询性能