第 4 回キャンペーン(2026-10-08)の 3 つの穴を塞ぐ。
- ハーネス: 同じアラート名が ALERT_DEDUPE_S(既定 300 秒)以内に再着したら
/diagnose を送らず note(dedupe) に記録する。Grafana は Pod ごとに 1 件ずつ
出し 30 秒後にグループを再送するため、1 障害が診断 4 件・提案 4 件になっていた。
全件 resolved になれば窓をリセットする。
- ハーネス: GET /proposals/{token} で承認・実行状態を返す。
- hitl: 60 秒ごとに未決の提案をハーネスへ照会し、API で承認された件は
メッセージを「ハーネス API で承認」に書き換えてタイマーを外す。期限切れ処理の
直前にも同じ照会を行う。
- AI: Jev 選別の now に alert_condition_now / alert_condition_clear /
recovered_now を追加し、recovering は recovered_now を読む。SLO に触れない
障害(replay 停止、メモリ圧迫)で 0.98 を返していた。now の p95 と 5xx 比率に
route フィルタを付け、判定と同じ式にそろえる。
47 lines
1.5 KiB
Go
47 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// one fault, several alerts with the same name (per-pod label sets, group resend): one diagnosis inside the window
|
|
func TestDedupeSameAlertName(t *testing.T) {
|
|
r := NewAlertRouter(&App{cfg: Config{AlertDedupeS: 300}})
|
|
sid := "C-G2"
|
|
if _, dup := r.dedupe("ApiMemoryPressure", &sid); dup {
|
|
t.Fatal("first alert must be diagnosed")
|
|
}
|
|
if _, dup := r.dedupe("ApiMemoryPressure", &sid); !dup {
|
|
t.Fatal("second alert inside the window must be skipped")
|
|
}
|
|
other := "V-G1"
|
|
if _, dup := r.dedupe("ApiMemoryPressure", &other); dup {
|
|
t.Fatal("another scenario is a new fault")
|
|
}
|
|
// all alerts of that name resolved -> the next firing starts a new diagnosis
|
|
r.setFiring("fp1", "ApiMemoryPressure", true)
|
|
r.clearDedupe("ApiMemoryPressure", &sid) // still firing: keep
|
|
if _, dup := r.dedupe("ApiMemoryPressure", &sid); !dup {
|
|
t.Fatal("still firing: keep the window")
|
|
}
|
|
r.setFiring("fp1", "ApiMemoryPressure", false)
|
|
r.clearDedupe("ApiMemoryPressure", &sid)
|
|
if _, dup := r.dedupe("ApiMemoryPressure", &sid); dup {
|
|
t.Fatal("after resolve the next firing is a new fault")
|
|
}
|
|
// window expiry
|
|
r.lastDiag["ApiMemoryPressure|"+sid] = time.Now().Add(-301 * time.Second)
|
|
if _, dup := r.dedupe("ApiMemoryPressure", &sid); dup {
|
|
t.Fatal("outside the window a new diagnosis is allowed")
|
|
}
|
|
// off
|
|
r2 := NewAlertRouter(&App{cfg: Config{AlertDedupeS: 0}})
|
|
if _, dup := r2.dedupe("X", nil); dup {
|
|
t.Fatal("dedupe off")
|
|
}
|
|
if _, dup := r2.dedupe("X", nil); dup {
|
|
t.Fatal("dedupe off")
|
|
}
|
|
}
|