สารบัญ
สิ่งที่อันตรายที่สุดของ cron job ที่ล้มเหลวคือ ไม่มีอะไรเกิดขึ้นเลย ไม่มีหน้าแจ้ง error ไม่มีระบบพัง ไม่มีผู้ใช้โวยวาย มีเพียงงานสำรองข้อมูลที่หยุดทำงานไปเงียบ ๆ ตั้งแต่สามสัปดาห์ก่อน รายงานที่ไม่เคยถูกส่งออกไป หรือสคริปต์ล้างข้อมูลที่ปล่อยให้ดิสก์เต็มจนระบบโปรดักชันล่ม
ตัว cron เองไม่มีระบบแจ้งเตือนในตัว ถ้างานจบด้วย error cron ก็ไม่สนใจ และถ้าเซิร์ฟเวอร์ทั้งเครื่องล่มในเวลาที่กำหนดไว้ งานนั้นก็ไม่ถูกรันเลย โดยไม่ทิ้งร่องรอยใด ๆ ให้คุณรู้ว่ามันไม่ได้รัน กรณีหลังนี่แหละที่ระบบมอนิเตอร์ส่วนใหญ่มองข้าม
คู่มือนี้อธิบายสามรูปแบบที่ช่วยจับความล้มเหลวทั้งสองแบบ พร้อมวิธีทำให้การแจ้งเตือนพลาดไม่ได้ ด้วยการยกระดับเป็นสายโทรเข้าจริง ๆ ด้วย Echobell
รูปแบบที่ 1: แจ้งเตือนเมื่อล้มเหลวด้วย hook จาก exit code
วิธีที่ง่ายที่สุดคือยิง webhook ทุกครั้งที่งานจบด้วยสถานะที่ไม่ใช่ศูนย์
ก่อนอื่นให้สร้างช่องใน Echobell แล้วคัดลอก URL ของ webhook จากนั้นครอบคำสั่ง cron ของคุณ:
0 3 * * * /opt/scripts/backup.sh || curl -s "https://hook.echobell.one/t/<channel-token>?title=Backup+failed&host=$(hostname)"
ถ้า backup.sh ทำงานสำเร็จ จะไม่มีอะไรเกิดขึ้น แต่ถ้าล้มเหลว Echobell จะส่งการแจ้งเตือนถึงมือถือคุณภายในไม่กี่วินาที พารามิเตอร์ใน query จะกลายเป็นตัวแปรของเทมเพลต ทำให้การแจ้งเตือนบอกได้ชัดเจนว่าโฮสต์ไหนและงานใดล้มเหลว
สำหรับสคริปต์ที่ยาวขึ้น การใช้ trap จะให้บริบทที่ละเอียดกว่า:
#!/usr/bin/env bash
set -euo pipefail
notify_failure() {
curl -s -X POST "https://hook.echobell.one/t/<channel-token>" \
-H "Content-Type: application/json" \
-d "{\"job\":\"nightly-backup\",\"host\":\"$(hostname)\",\"line\":\"$1\"}"
}
trap 'notify_failure $LINENO' ERR
# ... ตรรกะการทำงานของคุณ ...
ข้อจำกัดคือ วิธีนี้ได้ผลเฉพาะเมื่อสคริปต์ถูกรันจริงแล้วล้มเหลวเท่านั้น ถ้าเซิร์ฟเวอร์ล่ม cron ตั้งค่าผิด หรือมีใครคอมเมนต์บรรทัดนั้นทิ้งไว้ตอนไล่แก้บั๊ก ก็จะไม่มีการแจ้งเตือนเกิดขึ้นเลย นั่นคือเหตุผลที่คุณต้องมีรูปแบบที่ 2 ด้วย
รูปแบบที่ 2: dead man's switch สำหรับงานที่ไม่ได้รัน
dead man's switch พลิกตรรกะกลับด้าน คืองานจะส่ง ping ไปยังตัวมอนิเตอร์เมื่อสำเร็จ และตัวมอนิเตอร์จะแจ้งเตือนคุณเมื่อ ping ไม่มาตามกำหนด วิธีนี้ครอบคลุมความล้มเหลวทุกรูปแบบ ทั้ง error งานค้าง เซิร์ฟเวอร์ล่ม และรายการใน crontab ที่ถูกลบทิ้ง
มีสองตัวเลือกยอดนิยมที่โฮสต์เองได้และทำงานร่วมกับ Echobell ได้ดี:
- Healthchecks.io ถูกสร้างมาเพื่อเรื่องนี้โดยเฉพาะ สร้าง check ด้วยตารางเวลา cron ของคุณพร้อมช่วงผ่อนผัน แล้วเติม
&& curl -s https://hc-ping.com/YOUR_UUIDต่อท้ายบรรทัด cron เมื่อ ping มาช้า Healthchecks จะส่ง webhook ออกมา ชี้ไปที่ช่อง Echobell ของคุณเพื่อเปลี่ยนงานสำรองข้อมูลที่หายไปให้กลายเป็นเสียงโทรศัพท์ดัง - Uptime Kuma มี monitor ประเภท "Push" ที่ทำงานแบบเดียวกัน คืองานของคุณเรียก push URL แล้ว Uptime Kuma จะแจ้งเตือนผ่านช่องทางที่เชื่อมไว้เมื่อ heartbeat หยุดส่งมา
ทั้งสองกรณีลำดับการทำงานคือ cron job → ping เมื่อสำเร็จ → ตัวมอนิเตอร์สังเกตว่าเงียบไป → ยิง webhook ไปยัง Echobell → การแจ้งเตือนแบบพุชหรือสายโทรเข้า
รูปแบบที่ 3: ตรวจสอบตามกรอบเวลาสำหรับงานที่ผลิตข้อมูล
บางงานตรวจสอบจากผลลัพธ์ได้ดีกว่าจาก exit code ถ้างาน ETL ประจำคืนของคุณควรเพิ่มแถวข้อมูลให้เสร็จก่อนตี 4 งานตรวจสอบเล็ก ๆ ชิ้นหนึ่งก็เช็กจำนวนแถวได้ แล้วเรียก webhook ของ Echobell เมื่อตัวเลขดูผิดปกติ
เงื่อนไขของ Echobell ช่วยตรงนี้ได้ คุณส่ง webhook แจ้งสถานะทุกครั้งที่งานรันจบ แล้วปล่อยให้ช่องเป็นผู้ตัดสินว่าจะแจ้งเตือนเมื่อไร เงื่อนไขอย่าง status != "ok" จะทำให้การรันที่สำเร็จเงียบไว้ และตัวแปรเวลา UTC ที่มีมาให้ช่วยจำกัดการแจ้งเตือนไว้เฉพาะช่วงเวลาที่งานควรจะเสร็จแล้ว
ทำให้การแจ้งเตือนพลาดไม่ได้
การตรวจจับเป็นแค่ครึ่งเดียวของปัญหา การแจ้งเตือนว่าสำรองข้อมูลล้มเหลวที่โผล่มาเป็นแบนเนอร์เงียบ ๆ ตอนตีสาม มีค่าเท่ากับไม่แจ้งเตือนเลย
Echobell ให้แต่ละช่องเลือกระดับความเร่งด่วนได้:
- มาตรฐาน — การแจ้งเตือนแบบพุชปกติ เหมาะกับงานที่แจ้งให้ทราบเฉย ๆ
- สำคัญตามเวลา — ทะลุโหมดโฟกัสของ iOS เหมาะกับงานที่ควรมีคนมาดูในเร็ววัน
- โทรเข้า — โทรศัพท์ของคุณดังเหมือนมีสายเข้าจริง ๆ จนกว่าคุณจะรู้ตัว
สำหรับงานที่ความล้มเหลวแบบเงียบ ๆ ทำให้เสียเงินจริง เช่น การสำรองฐานข้อมูล การรันรอบเรียกเก็บเงิน หรือการต่ออายุใบรับรอง ให้ตั้งช่องเป็น โทรเข้า ความต่างระหว่าง "เห็นตอนตีสาม" กับ "เห็นตอนเก้าโมง" ก็คือความต่างที่การแจ้งเตือนด้วยสายโทรเข้าสร้างขึ้นนั่นเอง
ถ้ามีหลายคนรับผิดชอบงานเดียวกัน ให้แชร์ลิงก์ติดตามของช่องให้ทั้งทีม ทุกคนที่ติดตามจะได้รับการแจ้งเตือนเดียวกันในเวลาเดียวกัน
ควรใช้รูปแบบไหนดี
- hook จาก exit code: ตั้งค่าเสร็จในห้านาที จับความล้มเหลวที่แสดงออกชัดเจน เริ่มจากตรงนี้
- dead man's switch: จับงานที่ไม่ได้รันและงานที่ค้างได้ด้วย เพิ่มให้กับทุกงานที่คุณจะเดือดร้อนจริงถ้าพลาด
- ตรวจสอบข้อมูลตามกรอบเวลา: สำหรับ pipeline ที่ "รันสำเร็จแต่ได้ข้อมูลเสีย" เป็นความเสี่ยงจริง
ทั้งสามรูปแบบเสริมกันได้ดี hook จาก exit code บอกคุณว่างานล้มเหลวและล้มเพราะอะไร ส่วน dead man's switch รับประกันว่าคุณจะได้รู้ถึงความล้มเหลวที่ไม่มีโอกาสได้รายงานตัวเองด้วยซ้ำ
ตั้งค่าการแจ้งเตือน cron ตัวแรกของคุณได้ในไม่กี่นาที: ดาวน์โหลด Echobell สร้างช่อง แล้วเพิ่ม curl หนึ่งบรรทัดลงใน crontab ครั้งหน้าที่งานตามกำหนดเวลาหยุดทำงานตอนตีสาม โทรศัพท์ของคุณจะดัง และไฟล์สำรองที่คุณต้องกู้คืนในไตรมาสหน้าก็จะมีอยู่จริง