关于 cloud-logging-finops
cloud-logging-finops 是一项指导 Google Cloud Logging 成本与用量审计的技能,面向需要分析日志支出的项目负责人。它结合账单导出、监控指标和日志样本,并要求报告说明估算依据及安全的节省措施。
主要功能
- 01采集日志用量与成本数据
- 02支持账单导出查询或估算
- 03分析服务、日志流与严重性
- 04生成成本优化行动报告
适用场景
- 01核查 Google Cloud 日志支出来源
- 02查看支出趋势并预测成本
- 03定位可减少的日志开销
- 04检查严重性分布与审计日志状况
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ google/ skills --skill cloud-logging-finops安装后在 Claude Code 中输入/cloud-logging-finops确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/report_template.htmlreferences/executive_summary_authoring.mdscripts/actions.pyaggregations.pyanalytics.pyattribution.pybilling.pybuild_report.pycollect_logging_data.pyconstants.pyenable_log_analytics.pyexclusion_rules.pyinventory.pymessages.pymonitoring.pyoutput.pyperf.pypricing.pyprovenance.pyrequirements.txttelemetry_integrity.pyverify_claim.pywaste.py详细介绍
Cloud Logging Finops
非交互式运行。 如果没有用户可以回答问题(例如定时或自动运行),不要提问:审计请求中指定的项目,或当前活动的 gcloud 项目;使用 --billing-mode=search;涵盖全部五个报告主题(步骤 2.5);绝不要启用 API 或升级日志存储桶。将任何需要用户处理的事项(API 已停用、缺少角色、升级建议)写入报告。
步骤 0:查找 Cloud Billing 导出
审计涵盖一个 Google Cloud 项目 {project_id}:用户指定的项目;若用户未指定,则为当前活动的 gcloud 项目(gcloud config get project),并需向用户确认。
其他所有信息(日志存储桶、Observability Analytics、接收器、排除项、指标)都由你自行发现;绝不要询问用户。账单导出是例外:若要自行查找,可能需要扫描账单账号中的每个项目,因此请在运行任何操作前询问一次,并且在用户选择答案 3(单选;如果宿主提供问题工具,则使用该工具)之前,不要开始搜索:
你知道
{project_id}的 Cloud Billing 导出位于何处吗?
- 知道 — 在这里 (BigQuery 表 ID
project.dataset.table,或仅提供项目和数据集)- 此项目没有账单导出
- 不知道 / 不确定 — 搜索 (小型项目只需几秒;大型账单账号可能需要很长时间)
| 答案 | 标志 | 成本数据 |
|---|---|---|
| 1 | --billing-mode=explicit 加上 --billing-table(或 --billing-project/--billing-dataset) | 已开票 |
| 2 | --billing-mode=none | 标价估算 |
| 3 | --billing-mode=search (默认值) | 找到时为已开票,否则为估算 |
答案 3 的搜索没有时间限制:先检查 {project_id}(通常不到 10 s;表很多时需 1–2 min),然后检查其账单账号中的每个项目(可能需要许多分钟;每 30 s 打印一次进度)。启动搜索前,请将此情况告知用户。如果等待时间无法接受,可提出改选答案 1(由用户查找表)或答案 2(跳过导出并使用标价估算)。不要建议设置导出以加快搜索。
如果搜索找到了导出,请告知用户:"下次传入 --billing-table=<table>,发现过程就只需约两秒。"
步骤 1:环境设置
在执行步骤 2 前检查以下先决条件;只修复缺少的项目:
- gcloud: 如果尚未安装
gcloud,请按照 https://docs.cloud.google.com/sdk/docs/install-sdk.md.txt 操作。 - 项目: 运行
gcloud config get project;如果结果不是{project_id}(来自步骤 0),请运行gcloud config set project {project_id}。 - 凭据: 脚本使用应用默认凭据。运行
gcloud auth application-default login,或将GOOGLE_APPLICATION_CREDENTIALS设置为服务账号密钥的路径。 - 结算: 项目必须关联有效的结算账号。
- API: 不要预先启用 API;新项目默认已启用 Logging、Monitoring、BigQuery 和
Observability API。只有当收集器报告某个 API 已停用(
SERVICE_DISABLED、“has not been used in project”)时,才告知用户 API 名称并征求其同意;获得批准后运行gcloud services enable {api} --project={project_id}(按下文说明添加标记):logging、monitoring:必需;缺少它们就无法进行审计。bigquery:用于获取结算导出中的开票费用。observability:用于解析项目的默认日志范围,使日志样本与 Logs Explorer 中显示的内容一致。cloudasset、cloudbilling:仅用于答案 3 中跨结算账号的搜索。
执行审计的身份所需的 IAM 角色。此技能绝不会授予角色:脚本使用用户自己的凭据运行,只能读取这些凭据允许访问的内容。如果某个步骤因权限不足而失败,其提示会指出对应步骤;请告知用户该步骤所需的以下角色:
| 角色 | 用途 |
|---|---|
roles/logging.viewer、roles/monitoring.viewer | 每次审计:日志存储桶、接收器、日志样本、用量指标 |
roles/bigquery.jobUser、roles/bigquery.dataViewer(应用于导出数据集) | 获取结算导出中的开票费用 |
roles/logging.viewAccessor(应用于其他项目中的日志视图) | 通过包含这些日志视图的默认日志范围读取样本 |
roles/cloudasset.viewer、roles/billing.viewer(结算账号) | 使用 --billing-mode=search 跨结算账号搜索 |
roles/logging.configWriter | 仅用于可选的 Observability Analytics 升级(步骤 3B) |
[ -f /tmp/finops_venv/bin/python ] || (uv venv /tmp/finops_venv && uv pip install -r scripts/requirements.txt --python /tmp/finops_venv/bin/python)
随附脚本会为 Google Cloud API 请求添加标记。你自行运行的命令也必须在每条命令中内联添加标记:
- gcloud:
CLOUDSDK_METRICS_ENVIRONMENT="google-skills google-skills/1.0 (skill:cloud-logging-finops)" gcloud ... - HTTP:
curl -H "User-Agent: google-skills/1.0 (skill:cloud-logging-finops)" ...
步骤 2:数据收集
在后台启动下方的收集器(耗时从几秒到许多分钟不等),然后趁其运行时继续执行步骤 2.5:
/tmp/finops_venv/bin/python scripts/collect_logging_data.py \
--project-id {project_id} --billing-mode={none|explicit|search}
可选参数:--billing-project、--billing-dataset、--billing-table(例如
billing-proj.ds.gcp_billing_export_v1_XXXX 或精选的 FinOps 视图)。
输出:logging_usage_summary.json、monthly_details/、service_details/
以及 [FINOPS ADVISORY] 行(见步骤 3)。收集器的输出末尾包含一个
[COLLECTION PROFILE] 表,列出各阶段耗时;如果运行时间超过步骤 0 中的时长,或者用户询问审计为何耗时这么久,请先查看该表,再作判断。
步骤 2.5:询问报告的用途
始终在采集器运行时询问此问题(多选)。如果用户跳过, 请涵盖全部五个主题:
这份报告应该回答什么问题?
- 钱花到哪里去了——按服务和数据流归因
- 支出是否在增长——趋势和预测
- 哪些内容可以安全关闭——具体的节省措施
- 这些日志实际上在说什么——最常见的模式和示例
- 严重性和审计日志状况
用户的选择决定你要深入阅读哪些输出,以及摘要的重点;不会改变采集器 收集的内容:
| 关注点 | 深入阅读 |
|---|---|
| 归因 | service_details/*.json、daily_services |
| 增长 | monthly_details/*.json、mom_patterns、cost_projection |
| 节省措施 | reduction_actions、extraneous_spend |
| 日志内容 | severity_summary.samples_by_service、granular_analytics.top_signatures(仅限 Observability Analytics) |
| 严重性/审计 | severity_summary、规则未纳入的原因 |
将你的叙述写入 insights/executive_summary.html(参见
执行摘要撰写指南)。
不要编写节省措施:生成的报告会在 Cost Optimizer 标签页中
根据 reduction_actions 列出这些措施。
注意
切勿编辑
assets/report_template.html。
步骤 3:遵循建议
A. 告知用户成本数字的依据
重要
除非数字来自发票(
billing_metadata.invoiced),否则请用 通俗易懂的语言告诉用户你查阅了哪里、发现了什么,以及这些数字的依据。 内部信息(阶段编号、模式名称、HTTP 代码、 “quota project”、“Cloud Asset Inventory”)应保留在日志和billing_metadata.fallback_chain中。
- 回答 1,指定位置未提供费用(
explicit_table或explicit_scope步骤的状态不是found):采集器不会搜索用户指定范围以外的内容。请根据该步骤的detail告知用户问题所在(此项目没有记录、该位置没有导出表,或查询失败),说明费用是按标价估算的,并提出使用修正后的位置或选择回答 3 重新运行。 - 回答 2(
user_declared_no_export):“我没有搜索——你告诉我没有账单导出——因此费用是按标价估算的,而非发票金额。”绝不要把跳过的搜索说成已查尽。 - 回答 3,未找到任何内容(
billing_account状态为not_found):“我搜索了此项目和你的账单账号,但没有找到账单导出。费用是按过去 30 天内各 SKU 的标价和免费额度估算的(请引用pricing.skus)。”只有这种情况才可以建议设置导出。请引用官方定价页面 (https://cloud.google.com/products/observability/pricing)作为标价来源。 - 回答 3,因权限问题导致搜索失败(任一步骤状态为
inconclusive):告知用户查询未能完成,因此费用为估算值。绝不要告诉用户不存在账单导出;搜索尚未完成。 - 回答 3,此项目的表被拒绝(
local_project状态为no_project_records):“此项目有账单导出,但其中没有此项目的记录,因此我搜索了账单账号的其余部分。” 然后按上述方式报告更广范围搜索的结果。 - **历史记录不完整:**月份会标记为
actual_bq_billing或usage_estimated;请在执行摘要中说明确切的日期分界。
如果使用标价,请建议启用导出以提高准确性:今后的审计将使用实际发票数据,涵盖多个月份并包含折扣。
B. 可观测性分析
可观测性分析以前称为日志分析;脚本中的提示和字段名称仍使用旧名称。
- 已停用: 提示用户相关情况,包括升级日志存储桶不可撤销,然后以直接提问结束回复,例如:“你要将
_Default日志存储桶升级为可观测性分析吗?此操作无法撤销。” 告诉用户如何自行运行不算提问。只有在用户批准升级该日志存储桶后,才能运行/tmp/finops_venv/bin/python scripts/enable_log_analytics.py --project-id {project_id}。无论是否升级,审计都会继续在 Cloud Monitoring 上进行。
注意
提出提示的同一轮中,或在用户仅授予一般权限(如“你需要做什么就做什么”)时,绝不要运行
enable_log_analytics.py或gcloud logging buckets update --enable-analytics。
- 创建时间不到 24 小时: 在样本累积(约 1–2 小时)之前,使用 Cloud Monitoring 的 14 天基线。
- 1–13 天: 在报告中注明样本时间窗口。
- ≥ 14 天: 使用完整 SQL 分析。
Representative logs unavailable提示: 缺少样本是因为你的环境无法读取日志条目(需要roles/logging.viewer),而不是因为流为空。转述错误和所需角色;各流详情见severity_summary.sample_errors。- 样本为空但流有数据量: 样本通过项目的默认日志范围读取,与 Logs Explorer 一致(
analytics_metadata.log_read_scope)。如果其source为project且有note,则表示无法解析该范围,因此未读取存储在此项目日志存储桶之外的日志。请说明这一点并转述note;绝不要说该流没有日志。
C. 测量完整性
注意
绝不要引用根据可观测性分析负载字节总和得出的成本或数据量;这会使计费数据量高估约 2 倍。
| 问题 | 来源 |
|---|---|
| 成本、摄取的 GiB | 结算导出(billing.query_logging_billing_costs、daily_gib、monthly_costs) |
| 服务构成 | logging.googleapis.com/billing/bytes_ingested(resource_type) |
| 日志流/严重性数据量 | logging.googleapis.com/byte_count(log、severity) |
| 严重性构成、条目内容 | 可观测性分析 SQL(constants.PAYLOAD_BYTES_SQL) |
- 有账单时,总量以账单为准;指标仅用于提供占比。绝不要将指标得出的总量与账单总量并列。
byte_count(接收量)与billing/bytes_ingested(计费量)相差约 1.5 倍或更多;绝不要用其中一个除以另一个。- 如果
telemetry_integrity.status为degraded,请说明所列日期的下降看起来是指标缺陷,且不会自行纠正,并重复telemetry_integrity.note中的限制。绝不要断言肯定没有任何变化。 is_partial: true的月份表示当月至今的数据。请明确标注这一点,绝不要称其为完整月份或“上个月”。
D. 额外支出
extraneous_spend.headline 是保守的下限:将 reduction_actions.actions 中 counted: true 的操作(重复存储桶路由、流日志采样、DEBUG 日志、过时排除项)相加,并且每项只按其补救措施实际移除的内容计价。其他所有内容都会展示,但绝不计入:超额保留(未量化)、采样排除规则(估算值)和 Data Access 审计日志(列于 withheld 中)。
- 报告为下限(
≥ X%),绝不能报告为点估计或“最高可达”。 - 如果
status为insufficient_data,不要给出任何数字——不能猜测、不能给出基准值,也不能给出 $0。 - 逐字引用任何操作的
flag;它是为读者编写的。 - 可以将未计入的操作和
uncounted_total_pct作为潜在额外收益提及,但绝不能加到标题数字中。 - 如果
headline.exceeds_sanity_ceiling,说明标题数字不可靠,指出计入的最大操作,并标记为需人工审核。不要提供任何数字。 - 如果
inventory_unavailable非空,说明日志接收器、排除项和流日志操作均未经过检查;绝不能说这些项目不存在。 - 每当提到 Data Access 审计日志(无论是
withheld条目,还是用户主动提及),都要说明它们未计入数字,因为需要合规决策:禁用或排除这些日志经常违反合规或安全政策,因此所有者必须先确认再采取行动。
E. 排除过滤器和操作
- 只有 Cost Optimizer 操作才包含过滤器和节省金额;Service Details 中的用量不代表节省。报告
sample_coverage.shown_pct。 - 引用操作的月度数值(
monthly_gib、monthly_usd),绝不能引用规则的采样窗口 GiB(granular_analytics.exclusion_candidates)。 rule_scope: stream会丢弃该流中该严重级别的每一条日志;请明确说明这一点。- 如果
refused_claims非空,请指出安全门控机制移除的流。
绝不能作为操作建议的项目:CRITICAL/ALERT/EMERGENCY(事件信号)、免费的 _Required 流($0,审计保留)、Data Access 审计日志(通常是合规强制要求;可以报告,绝不能计入)以及没有测量用量的流。
注意
手写排除过滤器必须:包含严重级别谓词(对于 DEFAULT 使用
severity = "DEFAULT";省略它会匹配所有内容);使用经过 URL 编码的日志 ID(compute.googleapis.com%2Ffirewall);绝不能在正则表达式中嵌入未转义的日志文本或轮换令牌(UUID、IP、长整数、时间);并遵守上面的列表。
第 4 步:构建并交付报告
/tmp/finops_venv/bin/python scripts/build_report.py --summary logging_usage_summary.json --insights-dir insights/ --output log_usage_report.html
除非你提供 insights/executive_summary.html,否则 build_report.py 会生成一份执行摘要。
只向用户提供一个链接,点击后即可打开完整呈现的报告——不是原始 HTML,也不是缺失的文件——无论用户当前身处何处都能打开。在发布链接之前,先确认这一点确实可行。
然后列出用户可以查看的内容(图表、服务明细、带可复制过滤器的操作排名、✓ Prove It 抽屉),并从本项目的数据中挑选 3–4 个后续问题,建议用户直接照原样提问。
如果用户提出了具体问题,请直接回答,并同时提供 GiB 和 USD 数值。数据来源可以是 monthly_aggregations(latest_complete_month 表示最新的完整月份;每个月的 top_service 是该月的 Top Cost Driver)、mom_patterns、cost_projection、trailing_30d_summary(其中的 top_driver 是报告中的 Top Cost Driver,且不含账单数据)、granular_analytics(仅在运行了 Observability Analytics 时提供),或按服务/月划分的明细文件。
步骤 5:后续问题
阶段 1(默认): 根据磁盘上的 JSON,用几句话或一张小表作答,指出数据无法确定的内容,然后停止并提供 3–4 种深入探究的方式。不要重新运行采集或重新查询数据源。
| 问题涉及 | 查看内容 |
|---|---|
| 某个严重程度 | severity_summary,该严重程度对应的 granular_analytics.top_signatures |
| 某项服务 | service_details/{service}.json,以及该服务对应的 top_signatures 和 top_log_names |
| 某项优化操作 | reduction_actions.actions 中对应的条目(claims、refused_claims、flag、counted) |
阶段 2(仅在用户选择方向后): 按需深入分析。针对 analytics_metadata.table_name(采集器测量的 _AllLogs 视图)运行 Observability Analytics SQL。步骤 3 仍然适用。
步骤 6:验证
provenance.claims[<id>] 记录了每个核心数据的 formula、sources(精确查询、Google Cloud 控制台链接、步骤;每项操作仅包含最大的 10 个数据流)、已知的控制台 differences,以及可运行的 checks(涵盖每个数据流)。ID 包括 latest_complete_spend、mtd_run_rate、trailing_30d_volume、estimated_run_rate、top_cost_driver、extraneous_spend、severity_costs、service_mix、action::<action id>。基于其他数据构建的声明会在 see_also 中列出这些数据(extraneous_spend → 其计入的操作);也要验证这些数据,verify_claim.py 会一并重新检查。
有人要求验证某个数据时:
- 现在,从磁盘读取: 根据输入逐步说明公式;列出每个来源及其 Google Cloud 控制台链接、原样记录的查询和步骤;然后列出
differences。 - 同一轮中,在后台运行: 运行
/tmp/finops_venv/bin/python scripts/verify_claim.py --summary <summary> --claim "<id>";无需等待。 - 完成后: 提供一个表格(check | report | live | Δ | ✓/△/✗)和一行结论。根据记录的
differences解释 △;每个 ✗ 的原因各用一行说明。
注意
只有验证请求可以重新查询数据源,而且只能通过
verify_claim.py。不要重新运行采集,也不要更改已记录的查询。
必要时说明:声明是否采用了定价(pricing.mode),定价方式是 per_sku(各 SKU 的价格和免费额度见 pricing.skus)还是 blended(原因见 pricing.notes);服务和严重程度数据不包括抵扣额;若为 cross_project_billing,复现结果需要对账单导出数据集具备 roles/bigquery.dataViewer 角色,并具备 roles/bigquery.jobUser 角色。