Appearance
Release Monitoring
對應主管要求 ⑤ release monitoring。 目的:把每一次 release 的執行狀況從個別 issue 抽離,成為可量測的指標。
概念對應
| 指標 | 從哪來 |
|---|---|
| 變更密度 | plan / issue 的時間分佈 |
| 失敗率 | task_run.state = FAILED 比例 |
| 重試率 | 同 task 的 attempt > 1 比例 |
| 回滾率 | type = Rollback 的 plan 比例 |
| 平均審批時長 | bb.issue.create → bb.issue.approve audit log 差值 |
| 平均執行時長 | task_run.finished_at - task_run.started_at |
| 凍結期違規 | bb.setting.update(MaintenanceWindow override)+ bb.taskrun.start 在凍結期 |
內建畫面
Projects → <p> → Releases → Health:
- 最近 30 release 的失敗 / 成功 / 重試比例(堆疊柱狀)
- 平均審批時長 / 執行時長(趨勢線)
- 高風險變更次數(drop / truncate / large DML)
- 凍結期變更次數(理應為 0)
- 各 environment 的「落後 release 數」
此畫面需要
bb.releases.list+bb.taskRuns.list。secondaryBusinessOps/readOnlyAuditor預設可看(IAM)。
自訂儀表
1. 直接 metrics(Prometheus)
Argus server 暴露 /metrics,含內建 release 相關指標:
| Metric | 型別 | 標籤 |
|---|---|---|
argus_task_run_total | counter | state (done / failed / canceled) |
argus_task_run_duration_seconds | histogram | engine, task_type |
argus_plan_check_run_total | counter | state, severity |
argus_plan_check_run_duration_seconds | histogram | check_type |
argus_issue_approval_duration_seconds | histogram | environment |
argus_rollout_total | counter | environment, state |
互動 SQL 治理(A2 PR-1 之後可用):
| Metric | 型別 | 標籤 | 含意 |
|---|---|---|---|
argus_sql_advisor_violation_total | counter | rule_type, severity, query_path | 互動 path(Query / AdminExecute / Export)一次違規一次 +1。query_path 拆 fleet 分布 |
argus_sql_advisor_run_error_total | counter | query_path, reason | advisor 跑失敗計數。非零代表該 workspace 的 soak 數據不完整 |
argus_sql_advisor_run_duration_seconds | histogram | query_path | advisor 跑多久,sized 5s sync wait budget 之用 |
審批治理(R2 PR-1 之後可用):
| Metric | 型別 | 標籤 | 含意 |
|---|---|---|---|
argus_iam_allusers_binding_skipped_total | counter | role, workspace | 某 role 帶 AllUsers binding 但被 approval-role resolver 跳過。非零代表 workspace 還有 legacy AllUsers binding;R2 PR-2 soak 期間用此值決策該 workspace 是否需要 migrate |
Risk Rule(P0-3 之後可用):
| Metric | 型別 | 標籤 | 含意 |
|---|---|---|---|
argus_risk_rule_eval_error_total | counter | rule_id, kind (compile / eval) | risk rule CEL 預判表達式失敗 — 該 rule 實質沒生效。fail-open 而非 fail-close,需要 ops 主動修 |
Schema Drift Detection(概念):
| Metric | 型別 | 標籤 | 含意 |
|---|---|---|---|
argus_schema_drift_runner_tick_total | counter | — | runner 每 10 分鐘 tick 一次。flat-line = runner 死了 — 即使 0 件 drift 也應該每 10 分鐘 +1 |
argus_schema_drift_runner_databases_scanned_total | counter | — | runner 每個 tick 處理多少 db。除以 tick 數可知平均每 tick 掃幾 db |
argus_schema_drift_checks_total | counter | outcome (bootstrap / no_drift / drift / baseline_error / event_error / audit_error) | 每個 db 每次 check 的結果。drift 是真正寫了 event 的;*_error 非零代表 runner 內部錯誤 |
argus_schema_drift_events_total | counter | severity (info / warning / error) | 寫進 schema_drift_event 的事件總數。這個 counter 上升 = 真的有未授權變更被偵測到 |
argus_schema_drift_blessing_total | counter | outcome (skipped / blessed / schema_missing / baseline_error) | TaskRun 完成後 blessing 結果。baseline_error 非零是嚴重的接線 regression — Plan-driven 變更會在下次 tick 被誤判為 drift |
Grafana panel 範例(PromQL):
promql
# Prod task 失敗率 (7d)
sum(rate(argus_task_run_total{state="failed"}[7d])) by (engine)
/
sum(rate(argus_task_run_total[7d])) by (engine)
# Prod issue 平均審批時長 (1d)
histogram_quantile(0.5,
sum(rate(argus_issue_approval_duration_seconds_bucket{environment="prod"}[1d])) by (le)
)
# Schema drift event 速率(24h 滑窗)
sum(rate(argus_schema_drift_events_total[24h])) by (severity)
# Drift runner 健康度(必非零,否則 runner 卡了)
rate(argus_schema_drift_runner_tick_total[10m])
# Blessing 失敗率 — 預警「下次 tick 會大規模誤報」
rate(argus_schema_drift_blessing_total{outcome="baseline_error"}[5m])2. 直接從 metastore SQL
sql
-- 過去 30 天,按 environment 拆分的 task 失敗率
SELECT
e.resource_id AS environment,
sum(case when tr.state = 'FAILED' then 1 else 0 end)::float / count(*)::float AS failure_rate,
count(*) AS total
FROM task_run tr
JOIN task t ON (t.project = tr.project AND t.id = tr.task AND t.pipeline = tr.pipeline)
JOIN environment e ON (e.id = t.environment)
WHERE tr.started_at >= now() - interval '30 days'
GROUP BY e.resource_id
ORDER BY failure_rate DESC;
-- 重試率
SELECT
count(distinct (project, task)) FILTER (WHERE max_attempt > 1)::float
/ count(distinct (project, task))::float AS retry_rate
FROM (
SELECT project, task, max(attempt) AS max_attempt
FROM task_run
WHERE started_at >= now() - interval '7 days'
GROUP BY project, task
) t;
-- 凍結期變更(理應為 0)
SELECT al.*
FROM audit_log al
WHERE al.action = 'bb.taskrun.start'
AND al.ts >= now() - interval '30 days'
AND EXISTS (
SELECT 1 FROM maintenance_window mw
WHERE mw.kind = 'FREEZE'
AND al.ts BETWEEN mw.start_at AND mw.end_at
);⚠️ 表名 / 欄位請以 LATEST.sql 為準;以上為示意。直連 metastore 屬於 二線運維 SOP 涵蓋的高權限存取。
3. 接 BI / 數倉
灌進 BigQuery / Snowflake / 自家數倉的常見管道:
| 來源 | 工具 |
|---|---|
| metastore(OLTP) | CDC(Debezium) → Kafka → 數倉 |
| audit log(append-only) | bb.auditlog.export 排程 → S3 → 數倉 ETL |
| metrics | Prometheus remote-write → Mimir / Thanos |
不要直接讓 BI 查 metastore — 會干擾 Argus 自身運行。走 read replica 或 CDC。
健康度警報
建議的常駐警報(按嚴重度):
| 警報 | 條件 | 嚴重度 |
|---|---|---|
| Prod task 失敗率 spike | 1h 失敗率 > 過去 30d 平均的 3 倍 | warning |
| 凍結期變更 | 任何 taskrun 在 FREEZE 窗口內啟動 | critical |
| Audit log 寫入停止 | 5 分鐘無新 entry | critical |
| 平均審批時長 > 4 小時 | 過去 24h 中位數 | info(流程問題訊號) |
| Plan check error override 比例 > 5% | 過去 7d | warning(標準下降訊號) |
Argus server /healthz 異常 | 任何 5xx | critical |
| Metastore lag(HA replica) > 30s | 任何時刻 | warning |
週 / 月報
建議的固定報表:
週報(dev / 平台團隊)
- 本週 release 數量 / 失敗 / 重試 / 回滾
- Top 3 失敗最多的 project / DB
- 平均審批時長 / 執行時長變化趨勢
- 新發現的 high-risk pattern(plan check warning 統計)
月報(管理層 / 稽核)
- 各 environment 變更分佈
- 凍結期違規(理應 0;任何 > 0 都要說明)
- Audit log 完整性驗證(hash chain)
- IAM 變更摘要(誰被新增 / 撤銷 / 升級)
- 高風險變更清單 + 結果
月報建議由
readOnlyAuditor角色匯出 audit log,避免 reporter 與 actor 角色衝突。
反模式
| 反模式 | 為什麼 |
|---|---|
| 只看「失敗 / 成功」二元指標 | 看不見「執行時間爆長」「重試很多次最後成功」這種隱性問題 |
| 把 monitoring dashboard 鎖在 admin role | 二線運維 / 業務 owner 應該能自助查;用 secondaryBusinessOps 開放 |
| 警報訊息只說「failed」 | 沒有 actor / resource / link 的警報沒人想處理 |
| 直接讀 metastore 跑 BI report | 干擾 Argus;走 read replica 或 CDC |