สารบัญ
- ทำไม Alertmanager จึงโทรหาคุณเองไม่ได้
- สิ่งที่ต้องมี
- ขั้นที่ 1 — สร้างช่องที่โทรหาคุณ
- ขั้นที่ 2 — เพิ่ม webhook receiver
- ขั้นที่ 3 — ทำความเข้าใจสิ่งที่ส่งมาจริง ๆ
- ขั้นที่ 4 — ส่งการแจ้งเตือนตอนกลับมาปกติเป็นพุชเงียบ ๆ
- ขั้นที่ 5 — จัดเส้นทางตามระดับความรุนแรง ไม่ใช่ส่งทุกอย่าง
- ขั้นที่ 6 — กับดักของ Watchdog
- ปรับจูนไม่ให้กลายเป็นเด็กเลี้ยงแกะ
- ให้ดังเฉพาะนอกเวลาทำงาน
- รับมือกับปัญหา commonLabels ว่างเปล่า
- ทำให้ payload มีขนาดเล็ก
- แชร์การแจ้งเตือนให้ทีมของคุณ
- สิ่งที่การตั้งค่านี้ไม่ได้ให้คุณ
- การแก้ปัญหา
- คำถามที่พบบ่อย
- Prometheus Alertmanager โทรออกได้เองไหม
- สายโทรจะทะลุโหมดห้ามรบกวนได้ไหม
- ใช้ได้ไหมถ้า Alertmanager อยู่หลังไฟร์วอลล์หรืออยู่ใน Kubernetes
- จะหยุดไม่ให้โทรมาตอน alert คลี่คลายได้อย่างไร
- ทำไมโทรศัพท์ของฉันจึงดังทุกสี่ชั่วโมงสำหรับ alert เดียวกัน
- ให้หลายคนได้รับสายจาก alert เดียวกันได้ไหม
- ควรกรองระดับความรุนแรงใน Alertmanager หรือในเงื่อนไขของ Echobell
- สรุป
- บทความที่เกี่ยวข้อง
Alertmanager ไม่มี receiver แบบเสียง ถ้าอยากได้สายโทรเข้าเมื่อ alert ของ Prometheus ทำงาน ให้เพิ่ม receiver แบบ webhook_configs ที่ชี้ไปยังช่อง Echobell ซึ่งตั้งประเภทการติดตามเป็น โทรเข้า คู่มือนี้ครอบคลุมทั้ง YAML ที่ต้องใช้จริง เงื่อนไขที่กันไม่ให้ alert ที่คลี่คลายแล้วโทรหาคุณ การจัดเส้นทางตามระดับความรุนแรง และ alert ชื่อ Watchdog ที่จะโทรหาคุณทุกสี่ชั่วโมงไปตลอดกาลถ้าไม่จัดการ
Prometheus เป็นระบบเก็บ metric ตั้งต้นของโครงสร้างพื้นฐานส่วนใหญ่ที่สร้างในทศวรรษที่ผ่านมา และ Alertmanager ก็เก่งจริงในส่วนที่ยาก ทั้งการตัด alert ซ้ำ การจัดกลุ่ม การปิดเสียงระหว่างงานบำรุงรักษา และการระงับเสียงรบกวนปลายทางเมื่อต้นทางล้มเหลว
สิ่งที่มันทำไม่ได้คือปลุกใครสักคนให้ตื่น
ทำไม Alertmanager จึงโทรหาคุณเองไม่ได้
Alertmanager มี receiver มาให้สำหรับอีเมล Slack, PagerDuty, OpsGenie, Discord, Telegram, Pushover, Webex, MS Teams และอื่น ๆ อีกนับสิบ แต่ทุกตัวส่ง ข้อความ ออกไป และข้อความก็อยู่ใต้อำนาจของสวิตช์ปิดเสียง โหมดห้ามรบกวน และโหมดโฟกัสของ iOS ตอนตีสามนั่นแปลว่า alert มาถึงแล้วก็ไม่มีอะไรเกิดขึ้น
ไม่มี voice_configs ตัวเลือกที่คนมักลงเอยด้วยคือ:
- PagerDuty / OpsGenie / Splunk On-Call — พวกนี้โทรออกได้จริง และเป็นแพลตฟอร์มจัดการเหตุการณ์แบบเต็มรูปแบบพร้อมราคาต่อหัวที่สมน้ำสมเนื้อ เป็นคำตอบที่ถูกต้องถ้าคุณต้องการการหมุนเวรและผังการยกระดับ แต่หนักเกินไปถ้าคุณแค่อยากให้โทรศัพท์ดัง (โดยเฉพาะ OpsGenie ที่กำลังทยอยปิดตัว ซึ่งเป็นเหตุผลที่หลายทีมกำลังทบทวนชั้นนี้กันอยู่ตอนนี้)
- ตัวเชื่อม SMS อย่าง Sachet — คุณต้องรันบริการเพิ่มอีกตัว จ่ายค่าเกตเวย์ต่อข้อความ และ SMS ก็ยังมาถึงในรูปแบบข้อความอยู่ดี บน iOS ข้อความไม่ทะลุโหมดโฟกัส เว้นแต่ผู้ส่งจะอยู่ในรายชื่อที่คุณอนุญาต
- โค้ดเชื่อมกับ Twilio — เขียนตัวรับ webhook เล็ก ๆ ซื้อเบอร์ จ่ายค่าโทรต่อครั้ง แล้วตอนนี้คุณก็เป็นเจ้าของโครงสร้างพื้นฐานระดับโปรดักชันอีกชิ้นที่มีหน้าที่เดียวคือทำให้โทรศัพท์ดัง
webhook receiver แบบทั่วไปคือทางออก มันส่ง JSON payload ตามที่มีเอกสารกำกับไปยัง URL ใดก็ได้ ซึ่งเป็นทั้งหมดที่คุณต้องการ
สิ่งที่ต้องมี
- ระบบ Prometheus + Alertmanager ที่รันอยู่ และสิทธิ์แก้ไข
alertmanager.yml - ติดตั้ง Echobell แล้ว (App Store / Google Play)
- เวลาสิบนาที
คู่มือนี้เขียนขึ้นโดยอ้างอิง Alertmanager 0.31 ส่วน payload ของ webhook อยู่ที่ version: "4" มาหลายปีแล้ว รุ่น 0.2x จึงทำงานเหมือนกันทุกประการ
Alertmanager ของคุณต้องออก HTTPS ไปยัง hook.echobell.one ได้ แต่ไม่จำเป็นต้องเข้าถึงได้จากอินเทอร์เน็ต ดังนั้น Alertmanager ที่อยู่ในคลัสเตอร์ ใน VPC หรือในโฮมแล็บก็ใช้ได้สบาย
ขั้นที่ 1 — สร้างช่องที่โทรหาคุณ
ใน Echobell ให้สร้างช่องชื่อประมาณ Prometheus Critical แล้วตั้งประเภทการแจ้งเตือนของการติดตามเป็น โทรเข้า นี่คือการตั้งค่าที่สำคัญ เพราะการแจ้งเตือนแบบโทรเข้าจะมาถึงเป็นหน้าจอสายเรียกเข้าและดังทะลุโหมดโฟกัสกับโหมดห้ามรบกวนของ iOS ได้ ซึ่งการแจ้งเตือนแบบพุชทำไม่ได้
ตั้งเทมเพลตให้อ่าน payload ของ Alertmanager ได้โดยตรง:
Title: 🔴 {{commonLabels.alertname}} on {{commonLabels.instance}}
Body: {{commonAnnotations.summary}}
{{commonAnnotations.description}}
และในการตั้งค่าขั้นสูง ให้ตั้ง Link Template เพื่อให้บันทึกการแจ้งเตือนกระโดดไปที่กราฟได้ทันที:
{{alerts[0].generatorURL}}
จากนั้นคัดลอก Webhook URL ของช่อง:
https://hook.echobell.one/t/<channel-token>
ให้ถือว่า URL นั้นเป็นความลับ เพราะใครก็ตามที่ถือมันไว้ก็ทำให้โทรศัพท์ของคุณดังได้
ขั้นที่ 2 — เพิ่ม webhook receiver
ใน alertmanager.yml:
route:
group_by: ["alertname", "cluster", "service"]
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: echobell-critical
receivers:
- name: echobell-critical
webhook_configs:
- url: "https://hook.echobell.one/t/<channel-token>"
send_resolved: false
โหลดค่าใหม่ด้วย curl -X POST http://localhost:9093/-/reload หรือส่ง SIGHUP
สังเกต send_resolved: false ด้วย ค่าเริ่มต้นของ webhook receiver คือ true ซึ่งต่างจาก receiver ตัวอื่นของ Alertmanager ส่วนใหญ่ ถ้าไม่ใส่บรรทัดนี้ โทรศัพท์ของคุณจะดังทั้งตอนบริการพัง และ ดังอีกครั้งตอนมันกลับมาเอง สายที่สองนั่นแหละที่สอนให้คนเริ่มเมินสายแรก ขั้นที่ 4 จะแสดงวิธีรับการแจ้งเตือนตอนกลับมาปกติโดยไม่ต้องมีเสียงเรียก
ขั้นที่ 3 — ทำความเข้าใจสิ่งที่ส่งมาจริง ๆ
Alertmanager จัดกลุ่ม alert แล้ว POST ออกมาหนึ่ง payload ต่อหนึ่งกลุ่ม:
{
"version": "4",
"groupKey": "{}:{alertname=\"HighErrorRate\"}",
"truncatedAlerts": 0,
"status": "firing",
"receiver": "echobell-critical",
"groupLabels": { "alertname": "HighErrorRate" },
"commonLabels": { "alertname": "HighErrorRate", "severity": "critical" },
"commonAnnotations": { "summary": "Error rate above 5% for 10m" },
"externalURL": "http://alertmanager.internal:9093",
"alerts": [
{
"status": "firing",
"labels": { "alertname": "HighErrorRate", "instance": "api-7d9f:8080" },
"annotations": { "summary": "Error rate above 5% for 10m" },
"startsAt": "2026-09-04T02:41:07.351Z",
"endsAt": "0001-01-01T00:00:00Z",
"generatorURL": "http://prometheus:9090/graph?g0.expr=...",
"fingerprint": "a1b2c3d4e5f60718"
}
]
}
Echobell อ่านเนื้อหา JSON ตามที่ส่งมาเลย ทุกฟิลด์เหล่านั้นจึงใช้ได้ในเทมเพลตและเงื่อนไข การเข้าถึงค่าที่ซ้อนกันใช้ได้ทั้งสองรูปแบบ คือ {{commonLabels.severity}} หรือ {{alerts[0].labels["instance"]}}
payload นี้มีคุณสมบัติสองข้อที่เป็นตัวขับเคลื่อนทุกอย่างที่เหลือ:
status ระดับบนสุดจะเป็น firing ถ้ามี alert ตัวใดก็ตาม ในกลุ่มที่กำลังทำงานอยู่ มันจะกลายเป็น resolved ก็ต่อเมื่อ alert ทุกตัวในกลุ่มคลี่คลายแล้วเท่านั้น ทำให้เป็นสิ่งที่ใช้กรองได้อย่างสะอาด
commonLabels เก็บเฉพาะ label ที่ alert ทุกตัวในกลุ่มมีร่วมกัน นี่คือเรื่องที่คนประหลาดใจบ่อยที่สุด ถ้า group_by กว้างพอจน webhook หนึ่งตัวพา HighErrorRate จากสาม instance มาด้วยกัน commonLabels.instance ก็จะไม่มีอยู่ และ {{commonLabels.instance}} จะแสดงผลเป็นสตริงว่าง มีวิธีรับมือเรื่องนี้อยู่ด้านล่าง
ขั้นที่ 4 — ส่งการแจ้งเตือนตอนกลับมาปกติเป็นพุชเงียบ ๆ
คุณยังอยากรู้ว่าอะไรกลับมาปกติแล้ว เพียงแต่ไม่อยากให้โทรมาบอก ให้เพิ่มช่อง Echobell ช่องที่สองชื่อ Prometheus Recovered ตั้งประเภทการแจ้งเตือนเป็น มาตรฐาน แล้วใส่เทมเพลตเหล่านี้:
Title: ✅ {{commonLabels.alertname}} resolved
Body: {{commonAnnotations.summary}}
และในการตั้งค่าขั้นสูง ให้ใส่ เงื่อนไข นี้:
status == "resolved"
เงื่อนไขคือนิพจน์ที่ถูกประเมินก่อนจะมีการส่งอะไรออกไป ถ้านิพจน์เป็นเท็จ Echobell จะรับคำขอไว้แต่ไม่ส่งอะไรเลย
จากนั้นให้ receiver ตัวเดียวกันชี้ไปทั้งสองช่อง เพราะ receiver หนึ่งตัวมี webhook_configs ได้หลายรายการ:
receivers:
- name: echobell-critical
webhook_configs:
# โทรเข้าเครื่อง เฉพาะตอน firing เท่านั้น
- url: "https://hook.echobell.one/t/<calling-channel-token>"
send_resolved: false
# พุชเงียบ ๆ เงื่อนไขของช่องจะตัดฝั่ง firing ทิ้ง
- url: "https://hook.echobell.one/t/<recovery-channel-token>"
send_resolved: true
ช่องสำหรับการกลับมาปกติจะรับ payload ทั้งแบบ firing และ resolved แล้วทิ้งฝั่ง firing ไป ผลลัพธ์คือ ตอนระบบล่มโทรศัพท์ดัง ส่วนตอนกลับมาปกติมาถึงเป็นพุชที่คุณอ่านตอนเช้าได้
ขั้นที่ 5 — จัดเส้นทางตามระดับความรุนแรง ไม่ใช่ส่งทุกอย่าง
เส้นทางแบบเหมารวมที่ส่ง alert ทุกตัวไปยังช่องแบบโทรเข้า คือเครื่องจักรผลิตสายโทรที่ไม่มีใครสนใจ ให้แยกตามระดับความรุนแรงใน Alertmanager ซึ่งเป็นที่ที่ผังการจัดเส้นทางควรอยู่:
route:
group_by: ["alertname", "cluster", "service"]
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: echobell-warning
routes:
# Watchdog ไม่ควรไปถึงมนุษย์ ดูขั้นที่ 6
- matchers:
- alertname = "Watchdog"
receiver: "null"
- matchers:
- severity = "critical"
receiver: echobell-critical
group_wait: 10s
repeat_interval: 1h
receivers:
- name: "null"
- name: echobell-critical
webhook_configs:
- url: "https://hook.echobell.one/t/<calling-channel-token>"
send_resolved: false
- name: echobell-warning
webhook_configs:
- url: "https://hook.echobell.one/t/<normal-channel-token>"
send_resolved: true
เส้นทางถูกประเมินจากบนลงล่างและตัวที่ตรงเป็นตัวแรกชนะ เพราะ continue มีค่าเริ่มต้นเป็น false ลำดับจึงสำคัญ เส้นทางของ Watchdog ต้องอยู่เหนือทุกอย่างที่อาจกลืนมันไป
ถ้าคุณอยากใช้ช่องเดียวแล้วกรองที่ฝั่ง Echobell แทน เงื่อนไขที่เทียบเท่าคือ:
status == "firing" && commonLabels.severity == "critical"
การทำใน Alertmanager มักดีกว่า เพราะ severity จะเป็นตัวกำหนด group_wait และ repeat_interval ไปด้วย ส่วนการทำใน Echobell ดีกว่าเมื่อคุณไม่สามารถ merge การแก้ config ได้ในวันนี้
ขั้นที่ 6 — กับดักของ Watchdog
ถ้าคุณใช้ kube-prometheus-stack คุณจะมี alert ชื่อ Watchdog ที่มีนิพจน์เป็น vector(1) มันถูกออกแบบมาให้ทำงานตลอดเวลา เพราะมีไว้ให้ระบบภายนอกสังเกตได้ว่า Prometheus เองหยุดทำงานไปแล้ว config เริ่มต้นจะส่งมันไปยัง receiver ชื่อ null
ถ้าคุณชี้เส้นทางแบบเหมารวมไปยังช่องแบบโทรเข้าโดยไม่กันมันออก Watchdog จะโทรหาโทรศัพท์ของคุณทุก repeat_interval ไปตลอดกาล และเริ่มทันที นี่คือสาเหตุอันดับหนึ่งที่ทำให้คนสรุปว่าการแจ้งเตือนด้วยสายโทร "ใช้ไม่ได้"
คงเส้นทาง null จากขั้นที่ 5 ไว้ จากนั้นจะเลือกทำสิ่งที่มีประโยชน์กับมันก็ได้ คือเปลี่ยน Watchdog ให้เป็น dead man's switch จริง ๆ
- matchers:
- alertname = "Watchdog"
receiver: deadmansswitch
group_wait: 0s
group_interval: 1m
repeat_interval: 50s
receivers:
- name: deadmansswitch
webhook_configs:
- url: "https://hc-ping.com/<your-check-uuid>"
send_resolved: false
Echobell เป็น dead man's switch เองไม่ได้ เพราะมันแจ้งเตือนเมื่อมีคำขอมาถึง ไม่ใช่เมื่อคำขอหยุดมา ดังนั้นให้ส่ง ping ของ Watchdog ไปยังบริการที่สร้างมาเพื่อตรวจจับความเงียบโดยเฉพาะ (Healthchecks.io, Cronitor, Dead Man's Snitch) แล้วชี้ webhook แบบ "check went down" ของบริการนั้น มาที่ช่องแบบโทรเข้าของ Echobell ทีนี้สายโทรก็จะแปลว่า "ตัวระบบมอนิเตอร์เองตายแล้ว" ซึ่งเป็น alert ที่คุณอยากถูกปลุกด้วยมากที่สุดและเป็นตัวที่ไม่มีใครตั้งค่าไว้เลย
ปรับจูนไม่ให้กลายเป็นเด็กเลี้ยงแกะ
การตั้งค่าของ Alertmanager สามตัวทำงานส่วนใหญ่ บวกกับของ Prometheus อีกหนึ่งตัว:
| การตั้งค่า | อยู่ที่ไหน | ทำอะไร |
|---|---|---|
for: | Alert rule | เงื่อนไขต้องเป็นจริงนานแค่ไหนก่อนจะทำงาน เป็นด่านแรกที่กันอาการกระตุกสองวินาที |
group_wait | Route | รอ alert เพิ่มอีกนานแค่ไหนก่อนส่งการแจ้งเตือนครั้งแรก ค่าเริ่มต้น 30 วินาที ลดเหลือ 10s สำหรับเรื่องวิกฤต |
group_interval | Route | ระยะห่างขั้นต่ำก่อนแจ้งเตือนเรื่อง alert ใหม่ ในกลุ่มที่มีอยู่แล้ว ค่าเริ่มต้น 5 นาที |
repeat_interval | Route | alert ที่ยังไม่คลี่คลายจะแจ้งซ้ำบ่อยแค่ไหน ค่าเริ่มต้น 4 ชั่วโมง เหตุระบบล่มกลางดึกจึงโทรหาคุณตอนตีสาม แล้วโทรอีกทีตอนเจ็ดโมง |
repeat_interval คือตัวที่ควรคิดให้ดี สี่ชั่วโมงเป็นเวลานานเกินไปที่จะปล่อยให้อะไรพังอยู่ ส่วนยี่สิบนาทีก็เป็นเครื่องจักรที่จะทำให้คุณปิดช่องนั้นทิ้ง หนึ่งชั่วโมงสำหรับเรื่องวิกฤตเป็นจุดเริ่มต้นที่สมเหตุสมผล
ถ้าคุณอยากให้สายที่ไม่มีคนรับโทรซ้ำทันทีแทนที่จะรอ repeat_interval รอบถัดไป ให้เปิด โทรซ้ำเมื่อสายไม่ติด ในการตั้งค่าแอปของ Echobell
ให้ดังเฉพาะนอกเวลาทำงาน
ระหว่างวันทำงานคุณคงนั่งดูแดชบอร์ดอยู่แล้ว ตัวแปรเวลาของระบบใน Echobell (เป็น UTC ทั้งหมด) ทำให้ช่องหนึ่งมีพฤติกรรมต่างกันตามชั่วโมงได้ โดยไม่ต้องเพิ่มเส้นทางที่สองใน Alertmanager:
status == "firing" && (hour >= 17 || hour < 9)
แบบนั้นจะโทรหาคุณเฉพาะนอกช่วง 09:00-17:00 UTC จากนั้นให้ชี้ช่องที่สองแบบมาตรฐานไปที่เงื่อนไขตรงข้ามสำหรับพุชในเวลากลางวัน:
status == "firing" && hour >= 9 && hour < 17
เพิ่ม dayOfWeek >= 1 && dayOfWeek <= 5 เข้าไปเพื่อให้นับวันหยุดสุดสัปดาห์เป็นนอกเวลาทำงานด้วย อย่าลืมว่าค่าเหล่านี้คำนวณเป็น UTC เสมอ จึงต้องเผื่อส่วนต่างของเขตเวลาคุณเอง มีคำอธิบายที่ละเอียดกว่านี้อยู่ในการแจ้งเตือนตามกรอบเวลาด้วยเงื่อนไขแบบ UTC
รับมือกับปัญหา commonLabels ว่างเปล่า
เมื่อกลุ่มหนึ่งมี alert จากหลาย instance commonLabels.instance จะหายไป และหัวข้อการแจ้งเตือนของคุณจะอ่านได้ว่า 🔴 HighErrorRate on
มีทางออกสามทาง เรียงตามลำดับที่แนะนำ:
- ใส่ label นั้นลงใน
group_byถ้าgroup_byมีinstanceอยู่ด้วย alert ทุกตัวในกลุ่มก็จะมีค่านี้ร่วมกัน และcommonLabels.instanceจะมีอยู่เสมอ ต้นทุนคือการแจ้งเตือนจะมากขึ้น คือหนึ่งครั้งต่อ instance แทนที่จะเป็นหนึ่งครั้งต่อชื่อ alert - อ่านจาก alert ตัวแรกแทน
{{alerts[0].labels.instance}}มีค่าเสมอ แต่มันก็เป็นแค่หนึ่งในหลายตัวที่อาจมี จึงควรจับคู่กับจำนวนรวม เช่น{{alerts[0].labels.instance}} (+{{alerts.length}} alerts) - ออกแบบข้อความให้อ่านรู้เรื่องแม้ค่าจะว่าง Echobell ไม่มีตัวดำเนินการค่าเริ่มต้น เพราะ
{{a || "unknown"}}จะแสดงข้อความตรงตัวว่าtrueไม่ใช่ค่าสำรอง ดังนั้นให้เขียนInstance: {{commonLabels.instance}}ไว้บนบรรทัดของมันเอง ซึ่งค่าว่างจะเห็นชัดว่าว่าง แทนที่จะกลายเป็นประโยคที่ขาดวิ่น
ทำให้ payload มีขนาดเล็ก
กลุ่มที่ครอบคลุมพ็อดร้อยตัวจะสร้างเนื้อหา JSON ขนาดใหญ่ และ Echobell จะปฏิเสธเนื้อหาทริกเกอร์ที่เกิน 1 MiB ด้วย HTTP 413 ให้จำกัดขนาดใน Alertmanager:
- url: "https://hook.echobell.one/t/<channel-token>"
send_resolved: false
max_alerts: 20
จากนั้น Alertmanager จะส่ง alert ไม่เกินยี่สิบตัว และตั้งค่า truncatedAlerts เป็นจำนวนที่มันตัดทิ้ง ซึ่งคุณนำมาแสดงในเนื้อหาได้:
Body: {{commonAnnotations.summary}}
Alerts: {{alerts.length}} (+{{truncatedAlerts}} truncated)
แชร์การแจ้งเตือนให้ทีมของคุณ
ช่องของ Echobell แชร์ผ่านลิงก์ติดตามได้ และผู้ติดตามแต่ละคนเลือกประเภทการแจ้งเตือนของตัวเอง เส้นทางเดียวกันจึงโทรหาวิศวกรที่อยู่เวร on-call ได้ ขณะที่คนอื่นได้รับเป็นพุชปกติ โดยไม่มีค่าใช้จ่ายต่อหัวและไม่ต้องเพิ่มกฎการจัดเส้นทางใน Alertmanager
เรื่องนี้ยังเข้ากับเหตุผลที่หลายทีมโฮสต์ Prometheus เองตั้งแต่แรกด้วย คือ metric และ alert rule ของคุณยังอยู่บนโครงสร้างพื้นฐานของคุณ ส่วน Echobell ก็เก็บเนื้อหาและประวัติการแจ้งเตือนไว้บนเครื่อง ไม่ใช่บนเซิร์ฟเวอร์ของตน
สิ่งที่การตั้งค่านี้ไม่ได้ให้คุณ
การพูดถึงขอบเขตอย่างตรงไปตรงมาช่วยให้คุณไม่ต้องย้ายระบบผิดพลาดในภายหลัง Echobell เป็นชั้นการนำส่ง ไม่ใช่แพลตฟอร์มจัดการเหตุการณ์ มันไม่มี:
- ตารางหมุนเวร on-call หรือการส่งต่อเวรข้ามโซนเวลา
- ผังการยกระดับที่เรียกคนที่สองเมื่อคนแรกไม่รับสาย
- ไทม์ไลน์เหตุการณ์ การติดตามการรับทราบ หรือเครื่องมือทำ postmortem
ถ้าทีมของคุณต้องการสิ่งเหล่านี้ คุณต้องใช้ PagerDuty, Grafana Cloud IRM หรือระบบคล้ายกัน สิ่งที่คู่มือนี้ครอบคลุมคือช่องว่างเฉพาะที่ Alertmanager ทิ้งไว้ นั่นคือการเปลี่ยน alert ที่กำลังทำงานให้เป็นโทรศัพท์ที่ดังจริง ๆ สำหรับผู้ดูแลคนเดียว ทีมเล็ก และโฮมแล็บ นั่นมักเป็นความต้องการทั้งหมดแล้ว
การแก้ปัญหา
ไม่มีอะไรมาถึงเลย ให้ดูล็อกของ Alertmanager เองก่อน (level=error component=dispatcher) จากนั้นยืนยันว่าเส้นทางไปจบที่ receiver ของคุณจริง คำสั่ง amtool config routes test severity=critical alertname=HighErrorRate จะบอกว่า alert หนึ่งจะไปลงที่ receiver ตัวไหน โดยไม่ต้องรอให้มันทำงานจริง
Echobell คืนค่า HTTP 404 โทเคนของช่องผิด หรือช่องถูกลบไปแล้ว โทเคนที่ไม่รู้จักจะได้ 404 ไม่ใช่ความสำเร็จแบบเงียบ ๆ
Echobell คืนค่า 200 พร้อม "notificationTriggered": false เงื่อนไขของคุณประเมินได้เป็นเท็จ เนื้อหาผลตอบกลับยังมี "conditionsMet": false มาด้วย ซึ่งเป็นวิธีที่เร็วที่สุดในการแยกว่า "เงื่อนไขฉันผิด" ต่างจาก "webhook ของฉันไม่เคยมาถึง" ให้ตรวจสอบ status == "firing" เทียบกับสิ่งที่ Alertmanager ส่งมาจริง คือ status ระดับบนสุด ไม่ใช่ alerts[0].status
HTTP 413 payload เกิน 1 MiB ให้ตั้ง max_alerts ตามด้านบน
HTTP 405 ช่องเปิด POST Only ไว้แล้วมีอะไรบางอย่างส่ง GET เข้ามา ในเมื่อ Alertmanager ใช้ POST เรื่องนี้จึงมักแปลว่าคุณทดสอบ URL นั้นในเบราว์เซอร์
หัวข้อมีช่องว่างโหว่อยู่ commonLabels ไม่มี label นั้นสำหรับกลุ่มนี้ ดูหัวข้อด้านบน
ไม่มีเสียงเรียก แต่การแจ้งเตือนมาถึง ประเภทการแจ้งเตือนของการติดตามนั้นเป็นมาตรฐานหรือสำคัญตามเวลา ไม่ใช่โทรเข้า ประเภทการแจ้งเตือนเลือกได้ทีละผู้ติดตาม จึงต้องไปตรวจสอบบนเครื่องที่ไม่ส่งเสียงเรียก
ทดสอบโดยไม่ทำระบบโปรดักชันพัง เพิ่ม rule ที่มี expr: vector(1) ตั้ง alertname ให้ไม่ซ้ำใคร และ severity: critical ปล่อยให้มันทำงานหนึ่งครั้งแล้วลบทิ้ง หรือจะยิงด้วยมือก็ได้:
curl -X POST http://localhost:9093/api/v2/alerts -H 'Content-Type: application/json' -d '[
{"labels":{"alertname":"EchobellTest","severity":"critical"},
"annotations":{"summary":"Testing the phone call path"}}
]'
คำถามที่พบบ่อย
Prometheus Alertmanager โทรออกได้เองไหม
ไม่ได้ Alertmanager มี receiver สำหรับอีเมล Slack, PagerDuty, OpsGenie และอื่น ๆ อีกมาก แต่ไม่มี receiver แบบเสียงหรือ SMS การจะโทรออกได้ต้องส่งผ่าน webhook receiver แบบทั่วไปไปยังบริการที่โทรออกได้ เช่น Echobell หรือไม่ก็จ่ายเงินใช้แพลตฟอร์มจัดการเหตุการณ์
สายโทรจะทะลุโหมดห้ามรบกวนได้ไหม
ได้ การแจ้งเตือนประเภทโทรเข้าของ Echobell แสดงผลเป็นสายเรียกเข้า ซึ่งดังทะลุโหมดโฟกัสและโหมดห้ามรบกวนของ iOS ดูรายละเอียดและการตั้งค่าที่เกี่ยวข้องได้ที่การทะลุโหมดโฟกัสของ iOS สำหรับการแจ้งเตือนวิกฤต
ใช้ได้ไหมถ้า Alertmanager อยู่หลังไฟร์วอลล์หรืออยู่ใน Kubernetes
ได้ webhook เป็นคำขอ HTTPS ขาออกจาก Alertmanager จึงต้องการแค่ให้ไปถึง hook.echobell.one ได้เท่านั้น Alertmanager ของคุณไม่จำเป็นต้องมีที่อยู่สาธารณะหรือ ingress
จะหยุดไม่ให้โทรมาตอน alert คลี่คลายได้อย่างไร
ตั้ง send_resolved: false บน webhook config ที่ชี้ไปยังช่องแบบโทรเข้าของคุณ webhook receiver มีค่าเริ่มต้นเป็น true ซึ่งต่างจาก receiver ตัวอื่นของ Alertmanager ส่วนใหญ่ จึงต้องปิดเอง ไม่ใช่เปิดเอง ถ้ายังอยากรับการแจ้งเตือนตอนกลับมาปกติแบบเงียบ ๆ ให้เพิ่มช่องที่สองพร้อมเงื่อนไข status == "resolved"
ทำไมโทรศัพท์ของฉันจึงดังทุกสี่ชั่วโมงสำหรับ alert เดียวกัน
นั่นคือ repeat_interval ซึ่งมีค่าเริ่มต้นเป็น 4h Alertmanager จะแจ้งซ้ำเรื่อง alert ที่ยังทำงานอยู่ตามจังหวะนั้น ให้ตั้งค่าแยกตามเส้นทาง โดย 1h สำหรับเรื่องวิกฤตเป็นตัวเลือกที่นิยม แต่ถ้าสายเริ่มโทรมาทันทีหลังคุณเพิ่มเส้นทางแบบเหมารวม ตัวการก็น่าจะเป็น alert ชื่อ Watchdog ที่ทำงานตลอดเวลามากกว่า ดูขั้นที่ 6
ให้หลายคนได้รับสายจาก alert เดียวกันได้ไหม
ได้ แชร์ช่องให้เพื่อนร่วมทีม แล้วผู้ติดตามแต่ละคนเลือกประเภทการแจ้งเตือนของตัวเอง ทุกคนที่ติดตามช่องแบบโทรเข้าจะได้รับสาย โดยไม่มีค่าใช้จ่ายต่อหัว
ควรกรองระดับความรุนแรงใน Alertmanager หรือในเงื่อนไขของ Echobell
ควรเลือก Alertmanager เพราะการจัดเส้นทางที่นั่นทำให้คุณตั้ง group_wait และ repeat_interval แยกตามระดับความรุนแรงได้ด้วย และผังการจัดเส้นทางก็อยู่ใน version control ร่วมกับ config ส่วนที่เหลือ ให้ใช้เงื่อนไขของ Echobell เมื่อคุณแก้ config ของ Alertmanager ไม่ได้ หรือสำหรับตัวกรองที่ Alertmanager ไม่มีแนวคิดนั้นอยู่เลย เช่น การกรองตามช่วงเวลาของวัน
สรุป
การตั้งค่าทั้งหมดมีแค่ receiver หนึ่งตัว send_resolved: false หนึ่งบรรทัด และผังการจัดเส้นทางที่กันทุกอย่างที่ไม่ใช่ severity: critical ออกจากช่องแบบโทรเข้า มันปล่อยให้ alert rule การจัดกลุ่ม การปิดเสียง และการระงับของคุณเหมือนเดิมทุกประการ และปิดช่องว่างระหว่าง "Prometheus สังเกตเห็น" กับ "มนุษย์สังเกตเห็น"
ดาวน์โหลด Echobell สำหรับ iPhone หรือรับได้จาก Google Play แล้วลองยิง alert ชื่อ EchobellTest ข้างต้นก่อนจะไว้ใจเส้นทางนี้กับเรื่องจริง