line-notify-gateway
หลังจากลองใช้งาน monitoring stack ที่ประกอบด้วย Grafana Prometheus ซึ่งสามารถส่งการแจ้งเตือนผ่านทาง Alertmanager ของ Prometheus ได้ ก็เกิดความคิดว่าอยากจะลองส่งการแจ้งเตือนผ่านทาง Line ดู เพราะในกลุ่มของ Chat application คนไทยนิยมทำงานผ่าน Line เป็นหลัก
ถึงแม้ว่า Alertmanager เองสามารถเชื่อมต่อกับ platform ได้หลากหลายเช่น Email Slack HipChat และ WeChat แต่ Alertmanager ยังไม่ support การแจ้งเตือนผ่าน Line โดยตรง โชคดีที่ Alertmanager สามารถส่งการแจ้งเตือนผ่านทาง Webhook ได้ ผมเลยลอง search หาว่ามีใครทำระบบสำหรับส่งการแจ้งเตือนไปที่ Line บ้าง ไปเจอ project หนึ่งอยู่บน Github ชื่อ line-notify-gateway
การแจ้งเตือนผ่าน Line เราจะใช้ feature ของ Line ที่เรียกว่า LINE Notify โดยอธิบายง่ายๆคือเจ้า LINE Notify มันเหมือนเป็น Line account หนึ่งซึ่งคอยรับข้อมูลผ่านทาง REST API แล้วก็ส่งการแจ้งเตือนมาทาง Line นั่นเอง โดยเราสามารถ ดึงเจ้า LINE Notify นี้เข้าไปในกลุ่ม Line ใดๆเพื่อให้มันทำหน้าที่คอยแจ้งเตือนสำหรับเหตุการณ์ต่างๆได้
ตัว line-notify-gateway เองไม่ support การเชื่อมต่อจาก Alertmanager แต่ความน่าสนใจของ project นี้คือถูกพัฒนาโดยวิศวกรของ Line เอง และใช้ Spring Boot ซึ่งผมพอจะเข้าใจการทำงานอยู่บ้าง น่าจะสามารถต่อเติมได้ไม่ยาก และตัว project นี้น่าจะถูกพัฒนาเอาไว้ส่งการแจ้งเตือนสำหรับ event ต่างๆใน Github ผ่านทาง Line ดังนั้นสิ่งที่ผมต้องทำต่อก็คือเขียนโปรแกรมเพิ่มเติมให้ line-notify-gateway สามารถรับ HTTP POST จาก Alertmanager แล้วส่งส่งการแจ้งเตือนต่ออกไปทาง Line ได้
Message ของ Alertmanager อยู่ในรูปของ JSON มี format ตามด้านล่างนี้ สิ่งที่นึกในตอนแรกคือจะ Parse JSON นี้แล้วแปลงไปเป็นข้อความใน LINE Notify ได้ยังไง
{
"version": "4",
"groupKey": <string>, // key identifying the group of alerts
"status": "<resolved|firing>",
"receiver": <string>,
"groupLabels": <object>,
"commonLabels": <object>,
"commonAnnotations": <object>,
"externalURL": <string>, // backlink to the Alertmanager.
"alerts": [
{
"status": "<resolved|firing>",
"labels": <object>,
"annotations": <object>,
"startsAt": "<rfc3339>",
"endsAt": "<rfc3339>",
"generatorURL": <string>
},
...
]
}
เนื่องจาก line-notify-gateway ถูกออกแบบมาเป็นอย่างดี คือใช้ Mustache สำหรับทำ template ของ message ที่จะส่งออกไป ดังนั้นสิ่งที่ต้องทำก็มีแค่การเพิ่ม Alertmanager เป็น service ใหม่นอกจาก Github เข้าไป และออกแบบ message template ว่าอยากจะให้แสดงข้อมูลใน Line Notify ยังไง code ที่เปลี่ยนจากต้นฉบับมีนิดเดียวลองดูจาก Github ของผม
template สำหรับแจ้งเตือน
Alert {{groupLabels.alertname}} is {{status}}
Severity {{commonLabels.severity}}Affected nodes,
{{#alerts}}
- {{labels.instance}}
{{/alerts}}
template สำหรับแจ้งว่าปัญหาได้หมดไปแล้ว
Alert {{groupLabels.alertname}} for nodes below has been {{status}}
{{#alerts}}
- {{labels.instance}}
{{/alerts}}
สำหรับ Alert ที่ออกมาหน้าตาก็จะประมาณนี้
ส่วนที่เพิ่มเข้าไปอีกคือการทำให้ line-notify-gateway ทำงานใน Container ได้ หรือที่เราเรียกว่า Containerize นั่นล่ะ โดยผม public ไว้บน dockerhub แล้วเช่นกัน เอาไว้ blog หน้าผมมาเล่าให้ฟังว่าเอาไปใช้ยังไงต่อนะครับ สำหรับใครพอเดาออกลองเข้าไปดูได้ที่ Github ครับ ผมเขียนวิธีใช้คร่าวๆไว้แล้ว