Mục lục
- Vì sao đường SNS thông thường lại vướng víu
- Bạn cần những gì
- Bước 1 — Tạo một kênh biết đổ chuông
- Bước 2 — Tạo connection và API destination
- Bước 3 — Tạo quy tắc và input transformer
- Bước 4 — Biết sự kiện thực sự trông ra sao
- Bước 5 — Lọc xuống những gì xứng đáng một cuộc gọi
- Bước 6 — Cho thông báo khôi phục một cánh cửa yên tĩnh hơn
- Hãy thử trước khi tin tưởng
- Còn SNS và email-tới-cuộc-gọi thì sao?
- Các giới hạn quan trọng khi có sự cố
- Những gì thiết lập này không cho bạn
- Khắc phục sự cố
- Câu hỏi thường gặp
- CloudWatch có gọi thẳng tới số điện thoại được không?
- Tôi có cần topic SNS không?
- Alarm CloudWatch có xuyên qua Không làm phiền không?
- Sao không đăng ký thẳng URL webhook vào SNS?
- Việc này có tốn phí trên AWS không?
- Tôi có thể gọi những người khác nhau cho các alarm khác nhau không?
- Còn alarm ở nhiều region hoặc nhiều tài khoản thì sao?
- Tổng kết
- Bài liên quan
Một alarm CloudWatch không thể gọi điện cho bạn. Các hành động tích hợp sẵn của nó chỉ có SNS, Auto Scaling, EC2 và Systems Manager, còn SNS thì kết thúc ở email, SMS hoặc một hàng đợi mà bạn phải đang theo dõi. Những hướng dẫn giúp điện thoại reo thật thường dựng một hàm Lambda cùng một tài khoản Twilio. Bạn có thể bỏ cả hai: để EventBridge nhận sự kiện đổi trạng thái của alarm, định dạng lại thành một thân JSON nhỏ, rồi POST tới kênh cuộc gọi của Echobell.
Bài này đi hết cả đường dẫn — kênh, quy tắc EventBridge, input transformer, các bộ lọc giữ cho tiếng chuông còn ý nghĩa, và lý do việc trỏ SNS thẳng vào webhook trông như sẽ chạy nhưng phần lớn là không.
Vì sao đường SNS thông thường lại vướng víu
Lời khuyên mặc định là "alarm → topic SNS → subscriber". Với cuộc gọi điện thoại, có ba vấn đề:
- SNS không có giao thức thoại. Các loại subscriber gồm email, SMS, push di động, SQS, Lambda, Firehose và HTTP(S). SMS dễ bị bỏ lỡ và bị chặn bởi Không làm phiền; một cuộc gọi thoại cần thứ gì đó bạn tự xây.
- Thông điệp HTTPS là chuỗi nằm trong chuỗi. SNS gửi phong bì của nó với
Content-Type: text/plain, còn bản thân alarm là một tài liệu JSON được tuần tự hóa vào trườngMessagecủa phong bì. Bộ nhận webhook đọc theo trường —AlarmName,NewStateValue— chỉ thấy một cục mờ đục. - Phong bì rất lớn. Với chữ ký, URL chứng chỉ ký và liên kết hủy đăng ký, phong bì thêm hơn một kilobyte trước khi nội dung alarm của bạn bắt đầu. Echobell cắt phần nội dung thông báo ở 1500 byte, nên một template kiểu "đổ nguyên cả thân" bị cắt đúng chỗ phần hữu ích bắt đầu.
Bạn có thể làm SNS chạy được bằng một Lambda bóc thông điệp ra rồi chuyển tiếp. Nhưng CloudWatch vốn đã xuất bản mọi lần đổi trạng thái alarm lên EventBridge dưới dạng một sự kiện JSON sạch — không cần cấu hình hành động nào — và EventBridge có thể tự định dạng lại rồi gọi một endpoint HTTPS.
Bạn cần những gì
- Một tài khoản AWS và quyền tạo quy tắc EventBridge, connection và API destination
- Đã cài Echobell (App Store / Google Play)
- Ít nhất một alarm CloudWatch sẵn có
- Mười phút
Phía bạn không cần chấp nhận lưu lượng đi vào. EventBridge là bên gửi yêu cầu đi.
Bước 1 — Tạo một kênh biết đổ chuông
Trong Echobell, tạo một kênh và đặt loại thông báo là Cuộc gọi. Kênh cuộc gọi hành xử như một cuộc gọi đến chứ không phải thông báo đẩy, nên nó xuyên qua chế độ Tập trung và Không làm phiền của iOS.
Transformer ở Bước 3 gửi một thân phẳng với các trường alarm, state, reason, region và link, nên template vẫn ngắn:
Tiêu đề: {{state}}: {{alarm}}
Nội dung: {{reason}}
Đặt template liên kết trong phần cài đặt nâng cao để chạm vào thông báo là mở alarm trong console:
{{link}}
Sao chép URL webhook của kênh trong màn hình chi tiết kênh:
https://hook.echobell.one/t/<channel-token>
Bước 2 — Tạo connection và API destination
EventBridge gọi các endpoint HTTPS bên ngoài qua một API destination, thứ này cần một connection mang thông tin xác thực. Echobell xác thực bằng token bí mật trong URL, nên connection chỉ là thủ tục — nhưng EventBridge không cho tạo destination nếu thiếu nó.
- Vào EventBridge → Integration → API destinations → Connections → Create connection
- Name:
echobell - Authorization type: API key
- API key name:
x-source, Value:eventbridge - Tạo xong, vào API destinations → Create API destination
- Name:
echobell-calling - API destination endpoint: URL kênh Echobell của bạn ở Bước 1
- HTTP method:
POST - Invocation rate limit:
1mỗi giây là thừa đủ và đóng vai van an toàn - Connection:
echobell
Header API key được gửi trong mọi yêu cầu. Bạn có thể kiểm tra nó trong điều kiện kênh Echobell nếu muốn thêm một cổng thứ hai phía trước token:
header["x-source"] == "eventbridge"
Bước 3 — Tạo quy tắc và input transformer
Vào EventBridge → Rules → Create rule trong cùng region với các alarm của bạn. Quy tắc theo từng region; alarm ở eu-west-1 vô hình với quy tắc ở us-east-1.
Dùng event bus default và quy tắc event pattern. Mẫu này khớp mọi alarm chuyển sang ALARM:
{
"source": ["aws.cloudwatch"],
"detail-type": ["CloudWatch Alarm State Change"],
"detail": {
"state": { "value": ["ALARM"] }
}
}
Với target, chọn EventBridge API destination và chọn echobell-calling. Cứ để console tạo execution role mới — nó cấp events:InvokeApiDestination cho destination này và không gì khác.
Sau đó mở Additional settings → Configure target input → Input transformer:
Input path
{
"alarm": "$.detail.alarmName",
"state": "$.detail.state.value",
"reason": "$.detail.state.reason",
"region": "$.region",
"time": "$.time"
}
Template
{
"alarm": "<alarm>",
"state": "<state>",
"reason": "<reason>",
"region": "<region>",
"time": "<time>",
"link": "https://console.aws.amazon.com/cloudwatch/home?region=<region>#alarmsV2:alarm/<alarm>"
}
EventBridge gửi kết quả dưới dạng application/json, nhờ vậy Echobell đọc được trực tiếp {{alarm}} và {{state}}.
Bước 4 — Biết sự kiện thực sự trông ra sao
Input path đọc từ sự kiện mà CloudWatch xuất bản. Rút gọn lại, nó như sau:
{
"version": "0",
"id": "c4c1c1c9-6542-e61b-6ef0-8c4d36933a92",
"detail-type": "CloudWatch Alarm State Change",
"source": "aws.cloudwatch",
"account": "123456789012",
"time": "2026-10-16T03:12:44Z",
"region": "us-east-1",
"resources": ["arn:aws:cloudwatch:us-east-1:123456789012:alarm:prod-api-5xx"],
"detail": {
"alarmName": "prod-api-5xx",
"state": {
"value": "ALARM",
"reason": "Threshold Crossed: 1 out of the last 1 datapoints [42.0] was greater than the threshold (10.0).",
"timestamp": "2026-10-16T03:12:44.000+0000"
},
"previousState": { "value": "OK" },
"configuration": { "description": "API 5xx errors on the prod load balancer" }
}
}
Những điều nên biết trước khi sửa template:
- Alarm nằm dưới
detail.$.alarmNamekhông khớp gì cả;$.detail.alarmNamethì khớp. state.reasonlà văn bản do hệ thống sinh ra. Nó nêu datapoint và ngưỡng, đúng thứ bạn muốn nghe lúc 3 giờ sáng.- Tên alarm được chèn nguyên văn. Một dấu nháy kép trong tên alarm hoặc reason sẽ làm hỏng JSON mà transformer tạo ra. Hãy chỉ dùng chữ cái, chữ số, dấu gạch ngang và gạch dưới trong tên alarm — vốn là thói quen tốt — nếu không cuộc gọi sẽ thất bại với lỗi 400.
- Liên kết cần một cái tên đơn giản. Tên có dấu cách hoặc
#sẽ không dẫn thẳng tới alarm đúng cách; tìm kiếm trong console vẫn tìm ra.
Bước 5 — Lọc xuống những gì xứng đáng một cuộc gọi
Một kênh alarm reo với mọi ALARM là cách nhanh nhất để tự tập cho mình thói quen phớt lờ nó. Hãy lọc ở hai nơi.
Trong mẫu EventBridge, chạy trước khi bất cứ thứ gì được gửi:
| Mục tiêu | Thay đổi mẫu |
|---|---|
| Chỉ alarm production | "alarmName": [{ "prefix": "prod-" }] bên trong detail |
| Bỏ qua những alarm không gấp | Đặt tên warn-… và dùng "alarmName": [{ "anything-but": { "prefix": "warn-" } }] |
| Chỉ một số alarm nhất định | "alarmName": ["prod-api-5xx", "prod-db-cpu"] |
| Chỉ alarm thật, không phải trạng thái thử | Giữ "state": { "value": ["ALARM"] } — sự kiện INSUFFICIENT_DATA không bao giờ khớp |
| Chỉ một tài khoản hoặc region | Thêm "account": ["123456789012"] hoặc "region": ["us-east-1"] ở cấp cao nhất |
Trong Echobell, dùng điều kiện kênh cho những gì mẫu không diễn đạt được, như khung giờ:
state == "ALARM" && (hour >= 17 || hour < 9)
Các biến thời gian của Echobell theo UTC, nên hãy quy đổi từ múi giờ của bạn trước. Tài liệu tham khảo điều kiện có danh sách biến đầy đủ.
Bước 6 — Cho thông báo khôi phục một cánh cửa yên tĩnh hơn
Một quy tắc thứ hai với "value": ["OK"] có thể báo rằng sự cố đã qua mà không đổ chuông. Tạo kênh Echobell thứ hai loại Nhạy thời gian (Time Sensitive) (hoặc thường), một API destination thứ hai trỏ tới nó, và dùng lại cùng input transformer. Template tiêu đề {{state}}: {{alarm}} đã đọc ra "OK: prod-api-5xx".
| Quy tắc | Trạng thái | Loại kênh | Hành vi |
|---|---|---|---|
alarms-to-call | ALARM, tiền tố prod- | Cuộc gọi | Reo xuyên chế độ Tập trung |
alarms-warn | ALARM, tiền tố warn- | Nhạy thời gian | Màn hình khóa, không reo |
alarms-recovered | OK | Thường | Thông báo đẩy bình thường |
Hãy thử trước khi tin tưởng
Đừng chờ production hỏng. Ép một alarm sang trạng thái bạn muốn:
aws cloudwatch set-alarm-state \
--alarm-name prod-api-5xx \
--state-value ALARM \
--state-reason "Manual test of the Echobell path"
Alarm trở về trạng thái thật ở lần đánh giá kế tiếp, nhưng sự kiện đổi trạng thái là thật và đi qua quy tắc của bạn. Để chỉ thử phía Echobell, hãy kích hoạt kênh trực tiếp:
curl -X POST https://hook.echobell.one/t/<channel-token> \
-H 'Content-Type: application/json' \
-d '{"alarm":"prod-api-5xx","state":"ALARM","reason":"Manual test","region":"us-east-1","link":"https://console.aws.amazon.com/cloudwatch/"}'
Nếu curl reo mà thử alarm thì không, vấn đề nằm ở quy tắc, transformer hoặc destination — không phải kênh.
Còn SNS và email-tới-cuộc-gọi thì sao?
Nếu bạn đã có topic SNS khắp nơi và không muốn đụng tới EventBridge, còn hai đường khác:
- SNS → Lambda → webhook. Vài dòng mã phân tích
Message, rồi POST một thân phẳng tới cùng URL Echobell. Chạy được, nhưng giờ bạn phải sở hữu một hàm, một role và log của nó. - SNS → email → trigger email của Echobell. Đăng ký địa chỉ trigger email của kênh vào topic. Alarm đến dưới dạng email, và
{{subject}}cùng{{text}}trong template của bạn trở thành thông báo. Đây là cách ít cấu hình nhất, với lưu ý là đăng ký email của SNS cần một lần bấm xác nhận và nội dung không được định dạng lại.
Đăng ký thẳng URL webhook của Echobell vào topic như một endpoint HTTPS là đường nên tránh: yêu cầu xác nhận sẽ đến như một thông báo, và mọi alarm sau đó là cái phong bì dài đã mô tả ở trên.
Các giới hạn quan trọng khi có sự cố
- Thân yêu cầu 1 MiB. Echobell từ chối thân yêu cầu kích hoạt lớn hơn 1 MiB bằng HTTP 413. Một alarm sau khi biến đổi chỉ vài trăm byte, nên bạn sẽ không chạm tới ngưỡng này ở đây.
- 120 yêu cầu mỗi phút cho mỗi token. Vượt qua đó, trigger trả về
429kèmRATE_LIMIT_EXCEEDEDvà mộtRetry-After. Giới hạn 1 mỗi giây của destination giữ bạn dưới ngưỡng, và EventBridge thử lại các sự kiện chưa gửi được. - 1500 byte nội dung thông báo. Bản dựng dài hơn bị cắt.
state.reasonchỉ một hai câu và vừa đủ chỗ.
Những gì thiết lập này không cho bạn
- Không có xác nhận (ack). Bắt máy không báo gì cho CloudWatch và không làm im các subscriber khác.
- Không có leo thang hay ca trực. Mọi người đăng ký kênh đều bị gọi; không có ai được gọi tiếp theo.
- Không khử trùng lặp ngoài phần của alarm. Một alarm chập chờn chuyển
OK → ALARMvài phút một lần sẽ reo mỗi lần. Hãy sửa bằng chu kỳ đánh giá dài hơn hoặcDatapointsToAlarmtrên chính alarm. - Không đồng bộ hai chiều. Sửa xong nguyên nhân không xóa gì trên điện thoại bạn.
Nếu những điểm đó là không chấp nhận được, bạn cần một nền tảng on-call đầy đủ. Còn nếu thứ bạn cần là "gọi tôi khi alarm production kích hoạt", thì đây chỉ là vài màn hình console.
Khắc phục sự cố
Alarm đã kích hoạt nhưng không có gì tới. Mở tab Monitoring của quy tắc: Invocations cho biết mẫu có khớp không, FailedInvocations cho biết việc gửi có thất bại không. Quy tắc ở region khác với alarm thì không bao giờ khớp.
Quy tắc khớp nhưng cuộc gọi thất bại với lỗi 400. Transformer tạo ra JSON không hợp lệ. Hãy tìm dấu nháy hoặc dấu gạch chéo ngược trong tên alarm hoặc reason.
Thông báo trống trơn. Template đang đọc một trường mà transformer không gửi. Thân là phẳng: {{alarm}}, không phải {{detail.alarmName}}.
Reo đi reo lại vì một alarm. Alarm đang chập chờn. Hãy kéo dài chu kỳ đánh giá hoặc yêu cầu nhiều datapoint hơn; đây là cài đặt của CloudWatch, không phải của Echobell.
Reo vì một alarm bạn không ngờ. Kiểm tra mẫu xem có thiếu bộ lọc prefix không, và nhớ rằng composite alarm cùng các alarm do công cụ khác tạo (ví dụ chính sách Auto Scaling) cũng phát sự kiện đổi trạng thái.
Câu hỏi thường gặp
CloudWatch có gọi thẳng tới số điện thoại được không?
Không. Các hành động của alarm CloudWatch là thông báo SNS, Auto Scaling, hành động EC2 và Systems Manager. Cuộc gọi thoại cần dịch vụ bên ngoài: một Lambda quay số qua nhà cung cấp, một nền tảng on-call, hoặc một webhook cuộc gọi như Echobell.
Tôi có cần topic SNS không?
Không. CloudWatch tự phát sự kiện đổi trạng thái alarm lên EventBridge, dù alarm có hành động nào hay không. Bạn có thể để trống danh sách hành động của alarm.
Alarm CloudWatch có xuyên qua Không làm phiền không?
Chỉ khi nó tới dưới dạng cảnh báo kiểu cuộc gọi. Kênh Echobell loại cuộc gọi hành xử như một cuộc gọi đến, và chế độ Tập trung cùng Không làm phiền của iOS cho loại đó đi qua. SMS hay thông báo đẩy thường thì không.
Sao không đăng ký thẳng URL webhook vào SNS?
SNS gửi text/plain với alarm được tuần tự hóa bên trong chuỗi Message, nên template không đọc được từng trường, và phong bì đủ dài để bị cắt. SNS cũng gửi yêu cầu xác nhận đăng ký trước, và nó sẽ đến như một thông báo.
Việc này có tốn phí trên AWS không?
Sự kiện đổi trạng thái alarm đến event bus default không mất phí; các lần gọi API destination tính phí theo yêu cầu. Với lưu lượng của một bộ alarm khỏe mạnh, đó là khoản không đáng kể, nhưng hãy xem giá EventBridge hiện hành cho region của bạn.
Tôi có thể gọi những người khác nhau cho các alarm khác nhau không?
Có. Tạo mỗi đối tượng một kênh, mỗi kênh một quy tắc, và để mỗi người đăng ký với loại thông báo họ muốn. Không có xác nhận, nên mọi người đăng ký bằng "cuộc gọi" đều được gọi.
Còn alarm ở nhiều region hoặc nhiều tài khoản thì sao?
Quy tắc theo từng region, nên hãy tạo quy tắc ở mỗi region bạn dùng (cùng định nghĩa API destination được lặp lại cho từng region). Với nhiều tài khoản, hãy gửi sự kiện tới một bus trung tâm ở một tài khoản và đặt quy tắc ở đó.
Tổng kết
Đường dẫn gồm năm phần: một kênh cuộc gọi, một connection và API destination trỏ tới nó, một quy tắc chỉ khớp những alarm đáng để đánh thức ai đó, một input transformer làm phẳng sự kiện, và một lần thử set-alarm-state cưỡng bức trước khi bạn dựa vào bất cứ thứ gì. Mọi thứ còn lại ở đây là để giữ nó đủ hẹp, sao cho một tháng nữa tiếng chuông ấy vẫn còn ý nghĩa.
Tải Echobell cho iPhone hoặc lấy trên Google Play, rồi chạy thử set-alarm-state.