mcpField
C
cloud-logging-finops

cloud-logging-finops

github.com/google云与 DevOps21.6k234 次安装今天更新
代码仓库

关于 cloud-logging-finops

cloud-logging-finops 是一项指导 Google Cloud Logging 成本与用量审计的技能,面向需要分析日志支出的项目负责人。它结合账单导出、监控指标和日志样本,并要求报告说明估算依据及安全的节省措施。

主要功能

  1. 01采集日志用量与成本数据
  2. 02支持账单导出查询或估算
  3. 03分析服务、日志流与严重性
  4. 04生成成本优化行动报告

适用场景

  1. 01核查 Google Cloud 日志支出来源
  2. 02查看支出趋势并预测成本
  3. 03定位可减少的日志开销
  4. 04检查严重性分布与审计日志状况

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/google/skills --skill cloud-logging-finops

安装后在 Claude Code 中输入/cloud-logging-finops确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
report_template.html
references/
executive_summary_authoring.md
scripts/
actions.py
aggregations.py
analytics.py
attribution.py
billing.py
build_report.py
collect_logging_data.py
constants.py
enable_log_analytics.py
exclusion_rules.py
inventory.py
messages.py
monitoring.py
output.py
perf.py
pricing.py
provenance.py
requirements.txt
telemetry_integrity.py
verify_claim.py
waste.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 导出位于何处吗?

  1. 知道 — 在这里 (BigQuery 表 ID project.dataset.table,或仅提供项目和数据集)
  2. 此项目没有账单导出
  3. 不知道 / 不确定 — 搜索 (小型项目只需几秒;大型账单账号可能需要很长时间)
答案标志成本数据
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 中)。

  1. 报告为下限(≥ X%),绝不能报告为点估计或“最高可达”。
  2. 如果 status 为 insufficient_data,不要给出任何数字——不能猜测、不能给出基准值,也不能给出 $0。
  3. 逐字引用任何操作的 flag;它是为读者编写的。
  4. 可以将未计入的操作和 uncounted_total_pct 作为潜在额外收益提及,但绝不能加到标题数字中。
  5. 如果 headline.exceeds_sanity_ceiling,说明标题数字不可靠,指出计入的最大操作,并标记为需人工审核。不要提供任何数字。
  6. 如果 inventory_unavailable 非空,说明日志接收器、排除项和流日志操作均未经过检查;绝不能说这些项目不存在。
  7. 每当提到 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 会一并重新检查。

有人要求验证某个数据时:

  1. 现在,从磁盘读取: 根据输入逐步说明公式;列出每个来源及其 Google Cloud 控制台链接、原样记录的查询和步骤;然后列出 differences。
  2. 同一轮中,在后台运行: 运行 /tmp/finops_venv/bin/python scripts/verify_claim.py --summary <summary> --claim "<id>";无需等待。
  3. 完成后: 提供一个表格(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 角色。

评论

支持 Markdown