AWS 数据库监控告警到飞书(生产级操作指南)
-
方案概述与告警链路
本文档面向生产环境,介绍如何将 AWS 上的 RDS / Aurora MySQL****、ElastiCache(Redis)、MongoDB(自建或 Atlas) 的基础监控、数据库慢日志、审计日志告警统一推送到飞书群。整体链路为:采集(CloudWatch 指标 / CloudWatch Logs)→ 告警(CloudWatch Alarms)→ 转发(****SNS → Lambda)→ 通知(飞书自定义机器人)。生产建议按严重级别拆分 SNS 主题、开启 Webhook 签名校验,兼顾可靠性与安全。

暂时无法在飞书文档外展示此内容
生产级设计要点:
-
慢日志与审计日志先写入 CloudWatch Logs,再用 Metric Filter 转成指标后告警,避免逐条扫描日志。
-
告警按 critical / warning / info 三级拆分 SNS 主题,分别推送不同群或机器人。
-
Lambda 转发器保持无状态、幂等,只负责「解析 + 格式化 + 签名 + 推送」,可安全重试。
-
Webhook 开启签名校验;密钥存放于 Lambda 环境变量(KMS 加密),禁止入库入仓。
-
前置准备:飞书机器人 + Lambda 转发器
-
创建飞书自定义机器人
一步一步操作:
-
打开目标告警群,点击右上角「设置」→「群机器人」→「添加机器人」→「自定义机器人」。
-
给机器人命名(如「AWS 数据库告警」),点击「添加」。添加完成后复制 Webhook 地址,格式为 https://open.feishu.cn/open-apis/bot/v2/hook/xxx 。
-
回到机器人详情,在「安全设置」中勾选「签名校验」,点击「复制」保存生成的密钥(Secret)。生产环境建议同时勾选「IP 地址白名单」,仅放行 Lambda 的出口网段(如无固定出口可先不启用,依赖签名校验)。
-
点击「保存」。验证方法:按 2.4 测试方式向 Webhook 发一条测试消息,确认群内能收到。
官方接入说明见飞书自定义机器人使用指南。
Webhook 与 Secret 相当于告警群的「写权限」,禁止写入代码仓库、CI 变量或公开文档;统一放入 Lambda 环境变量或 AWS Secrets Manager,并启用 KMS 加密。
-
部署 Lambda 转发函数
函数接收 SNS 消息(内容为 CloudWatch 告警 JSON),解析后格式化文本、计算签名并 POST 到飞书。建议运行时 Python 3.12,内存 128 MB,超时 10 秒。代码只依赖 Python 标准库(urllib/hmac),无需打包任何第三方依赖。
import os, json, time, base64, hashlib, hmac, urllib.request
# 入口函数名必须与 Lambda 的「处理器」配置一致:默认 lambda_function.handler 对应下面的 lambda_handler
# 密钥用环境变量注入,勿在代码/文档中写死
WEBHOOK = os.environ.get("FEISHU_WEBHOOK_URL", "")
SECRET = os.environ.get("FEISHU_SECRET", "")
def gen_sign(timestamp, secret):
# 飞书签名算法:timestamp + "\n" + secret 作密钥,对 timestamp + "\n" + body 做 HMAC-SHA256,再 Base64
string_to_sign = "{}\n{}".format(timestamp, secret)
digest = hmac.new(string_to_sign.encode("utf-8"),
digestmod=hashlib.sha256).digest()
return base64.b64encode(digest).decode("utf-8")
def post_feishu(text):
ts = str(round(time.time()))
payload = {"timestamp": ts, "msg_type": "text",
"content": {"text": text}}
if SECRET:
payload["sign"] = gen_sign(ts, SECRET)
req = urllib.request.Request(
WEBHOOK,
data=json.dumps(payload).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST")
try:
with urllib.request.urlopen(req, timeout=5) as resp:
body = resp.read().decode("utf-8")
print("FEISHU_RESPONSE:", body) # 打印飞书返回值,便于在 CloudWatch Logs 排查
return body
except Exception as e:
print("FEISHU_SEND_ERROR:", repr(e)) # 打印网络/超时/HTTPError 异常
raise
def format_alarm(m):
state = m.get("NewStateValue", "UNKNOWN")
level = {"ALARM": "严重", "OK": "恢复",
"INSUFFICIENT_DATA": "数据不足"}.get(state, state)
trig = m.get("Trigger", {})
return "\n".join([
"【{}】AWS 数据库告警".format(level),
"告警名称: {}".format(m.get("AlarmName", "")),
"状态: {}(原状态 {})".format(state, m.get("OldStateValue", "")),
"指标: {} = {}(阈值 {} {})".format(
trig.get("MetricName", ""),
m.get("NewStateReason", ""),
trig.get("Threshold", ""),
trig.get("ComparisonOperator", "")),
"时间: {}".format(m.get("StateChangeTime", "")),
"详情: {}".format(m.get("AlarmArn", "")),
])
def lambda_handler(event, context):
for record in event.get("Records", []):
sns = record.get("Sns", {})
try:
msg = json.loads(sns.get("Message", "{}"))
except Exception:
msg = {"Raw": sns.get("Message", "")}
if "AlarmName" in msg:
post_feishu(format_alarm(msg))
else:
post_feishu("【AWS 事件】" + str(msg))
-
部署步骤(控制台)
-
创建 IAM 执行角色:IAM 控制台 → 角色 → 创建角色 → 选择 AWS 服务 / Lambda → 附加托管策略 AWSLambdaBasicExecutionRole → 命名 lambda-feishu-basic。该角色只允许函数写 CloudWatch Logs。
-
创建函数:Lambda 控制台 → 创建函数 → 从零开始 → 名称 feishu-alert-forwarder,运行时 Python 3.12,架构 x86_64,权限选择刚才的角色。
-
粘贴代码:在 lambda_function.py 文件中粘贴上面的完整代码,点击「Deploy(部署)」。处理器保持默认 lambda_function.handler——代码入口函数必须命名为 lambda_handler,二者才能对应上。
-
设置****环境变量:配置 → 环境变量 → 添加两项:FEISHU_WEBHOOK_URL(Webhook 地址)、FEISHU_SECRET(签名密钥);可勾选「KMS 密钥加密」。
-
调整基本设置:配置 → 常规配置 → 编辑:超时 10 秒、内存 128 MB。
-
验证函数可运行:先按 2.4 的测试方式一发送测试事件,确认飞书群收到消息后再继续 SNS 订阅。
若执行时报 Handler 'xxx' missing on module 'lambda_function'(Runtime.HandlerNotFound),说明函数入口名与「处理器」配置不一致:把代码函数名改为 lambda_handler(推荐,与默认配置对应),或把处理器改为 lambda_function.handler。
-
部署步骤(CLI 一键)
# 0) 将代码保存为 lambda_function.py,打包(纯标准库无需装依赖)
zip -j feishu-alert-forwarder.zip lambda_function.py
# 1) 创建 IAM 执行角色
aws iam create-role --role-name lambda-feishu-basic \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{"Effect": "Allow",
"Principal": {"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name lambda-feishu-basic \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
# 2) 创建函数并设置环境变量、超时与内存
aws lambda create-function \
--function-name feishu-alert-forwarder \
--runtime python3.12 --handler lambda_function.handler \
--role arn:aws:iam::815974599660:role/lambda-feishu-basic \
--zip-file fileb://feishu-alert-forwarder.zip \
--timeout 10 --memory-size 128 \
--environment 'Variables={
"FEISHU_WEBHOOK_URL": "https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
"FEISHU_SECRET": "你的签名密钥"}'
# 之后改代码 / 改配置
aws lambda update-function-code --function-name feishu-alert-forwarder \
--zip-file fileb://feishu-alert-forwarder.zip
aws lambda update-function-configuration --function-name feishu-alert-forwarder \
--environment 'Variables={...}' --timeout 10 --memory-size 128
若函数需要访问 VPC 内资源(如定时拉取 Redis SLOWLOG),需在函数配置中绑定 VPC 子网与安全组,并确保子网有 NAT 网关或公网出口,否则函数无法访问飞书 Webhook(公网)。
-
创建 SNS 主题并订阅 Lambda
一步一步操作:
# 1) 创建按级别拆分的主题
aws sns create-topic --name db-monitor-critical
aws sns create-topic --name db-monitor-warning
aws sns create-topic --name db-monitor-info
# 2) Lambda 订阅主题,并授权 SNS 调用该函数
aws sns subscribe \
--topic-arn arn:aws:sns:af-south-1:815974599660:db-monitor-critical \
--protocol lambda \
--notification-endpoint arn:aws:lambda:af-south-1:815974599660:function:feishu-alert-forwarder
aws lambda add-permission \
--function-name feishu-alert-forwarder \
--statement-id sns-db-monitor-critical \
--action lambda:InvokeFunction \
--principal sns.amazonaws.com \
--source-arn arn:aws:sns:af-south-1:815974599660:db-monitor-critical
# 3) 确认订阅与权限已生效
aws sns list-subscriptions-by-topic \
--topic-arn arn:aws:sns:af-south-1:815974599660:db-monitor-critical
订阅 Lambda 协议不需要「确认订阅」步骤,只要第 2 步 add-permission 的 source-arn 与主题一致即可触发。其余两个主题(warning / info)重复上述订阅与授权命令,替换主题 ARN 与 statement-id 即可。
示例中账号 815974599660 与区域 af-south-1 已按你的生产环境填写;若开发环境为 ap-southeast-1(新加坡),需在该区域重复创建主题、函数与权限。
-
测试 Lambda 转发函数
函数代码部署后、接入真实告警前,建议按「本地验证 → 控制台 Test → SNS 端到端」三层依次测试,任一层失败都容易定位。
测试方式一:本地直接运行 handler(改代码时最快)。在本地保存 lambda_function.py,并创建测试事件文件 test_event.json:
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"Sns": {
"Type": "Notification",
"MessageId": "test-message-id",
"TopicArn": "arn:aws:sns:af-south-1:815974599660:db-monitor-warning",
"Message": "{\"AlarmName\":\"rds-credit-prod-cpu\",\"AlarmDescription\":\"测试告警\",\"AWSAccountId\":\"815974599660\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 datapoint (82.0) was greater than or equal to the threshold (80.0).\",\"StateChangeTime\":\"2026-10-23T16:00:00.000+0000\",\"OldStateValue\":\"OK\",\"Trigger\":{\"MetricName\":\"CPUUtilization\",\"Namespace\":\"AWS/RDS\",\"ComparisonOperator\":\"GreaterThanThreshold\",\"Threshold\":80.0}}",
"Timestamp": "2026-10-23T16:00:00.000Z"
}
}
]
}
# 设置环境变量(对应 Lambda 中的两项)
export FEISHU_WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/xxx"
export FEISHU_SECRET="你的签名密钥"
# 直接调用 handler,并检查飞书群是否收到格式化告警
python3 -c "
import json, lambda_function
with open('test_event.json') as f:
event = json.load(f)
lambda_function.lambda_handler(event, None)
print('OK: 已发送,请检查飞书群')
"
测试方式二:控制台 Test 事件(验证线上函数)。
-
Lambda 控制台打开函数 feishu-alert-forwarder → 右上角「测试」→「配置测试事件」。
-
事件模板选择 SNS 通知(或直接自定义),把上面 test_event.json 的内容粘贴进去,命名 test-event,保存。
-
点击「测试」。执行结果区域应显示执行成功;若失败,展开日志流查看具体异常。
-
检查飞书告警群:应收到「【严重】AWS 数据库告警 / 告警名称: rds-credit-prod-cpu ...」的文本消息。
测试方式三:****SNS 端到端联调(验证订阅与权限链路)。向主题发布一条真实格式的消息:
aws sns publish \
--topic-arn arn:aws:sns:af-south-1:815974599660:db-monitor-warning \
--message '{"AlarmName":"e2e-test","NewStateValue":"ALARM","NewStateReason":"manual test","OldStateValue":"OK","StateChangeTime":"2026-10-23T16:00:00.000+0000","Trigger":{"MetricName":"CPUUtilization","Namespace":"AWS/RDS","ComparisonOperator":"GreaterThanThreshold","Threshold":80}}'
执行后查看函数日志与飞书群:
aws logs filter-log-events \
--log-group-name /aws/lambda/feishu-alert-forwarder \
--filter-pattern 'ERROR' --limit 20
SNS publish 已返回 MessageId、但飞书未收到告警:按以下顺序排查。
-
看函数日志:aws logs filter-log-events --log-group-name /aws/lambda/feishu-alert-forwarder --filter-pattern 'FEISHU' --limit 20。新版代码会打印 FEISHU_RESPONSE(飞书返回值)或 FEISHU_SEND_ERROR(异常);返回 code 19021 表示签名/密钥问题。
-
核对****环境变量:FEISHU_WEBHOOK_URL / FEISHU_SECRET 是否已配置;未配置时 WEBHOOK 为空,函数会直接报错。
-
核对订阅与权限:aws sns list-subscriptions-by-topic --topic-arn arn:aws:sns:af-south-1:815974599660:db-monitor-warning,确认存在 Lambda 订阅,且 add-permission 的 source-arn 与主题 ARN 一致。
-
确认区域一致:SNS 的 Lambda 订阅必须同区域;主题在 af-south-1,Lambda 也必须创建在 af-south-1。
-
用控制台 Test 事件复测:Test 能收到 → 问题在订阅/权限/区域链路;Test 仍收不到 → 问题在环境变量或飞书侧。
常见失败排查:
| 现象 / 报错 | 原因 | 处理 |
|---|---|---|
| 飞书返回 code 19021 sign match fail | 签名错误或时间戳偏差 | 核对 FEISHU_SECRET 与 gen_sign 算法;确认 timestamp 为当前时间 |
| 飞书返回 code 非 0(如 9499/19001) | Webhook 无效、被禁用或触发频率限制 | 重新复制 Webhook;检查机器人安全设置(关键词/IP 白名单) |
| Lambda 报 timeout / 无法解析域名 | 函数无公网出口(VPC 场景) | 函数配置绑定 NAT 网关或使用公网子网 |
| SNS 消息未触发函数 | 订阅未生效或缺少 lambda:InvokeFunction 权限 | aws sns list-subscriptions-by-topic 核对;补 add-permission(source-arn 必须一致) |
| 消息重复或丢失 | Lambda 重试 / 并发限制 | 生产改用 SNS → SQS → Lambda,消费侧按 AlarmArn + StateChangeTime 幂等去重 |
| Handler 'xxx' missing on module 'lambda_function' | 函数入口名与处理器配置不一致 | 入口函数命名为 lambda_handler(或把处理器改为 lambda_function.handler) |
| aws sns publish 返回 MessageId 但飞书无消息 | 环境变量未配置 / 订阅未生效 / 区域不一致 | 按上方 5 步顺序排查;日志看 FEISHU_RESPONSE 与 FEISHU_SEND_ERROR |
-
RDS / Aurora MySQL 监控告警
-
基础指标告警
RDS 指标位于命名空间 AWS****/RDS(Aurora 为集群维度),增强监控指标位于 rdsOS。增强监控开启步骤:实例详情 → 配置 → 增强监控 → 启用,监控粒度 60 秒,IAM 角色选 rds-monitoring-role;或创建实例时指定:
--monitoring-interval 60 \
--monitoring-role-arn arn:aws:iam::815974599660:role/rds-monitoring-role
推荐指标与阈值如下:
| 指标 | 推荐阈值 | 级别 | 说明 |
|---|---|---|---|
| CPUUtilization | > 80% 持续 10 分钟 | warning | Average 5 分钟聚合,连续 2 个周期 |
| FreeableMemory | < 200 MB 或 < 20% | warning | 内存压力,需排查慢查询与连接数 |
| FreeStorageSpace | < 10% 或 < 10 GB | critical | 维度 DBClusterIdentifier。指标为AuroraVolumeBytesLeftTotal 磁盘将满,尽快扩容或清理 |
| DatabaseConnections | > max_connections 的 80% | critical | 连接耗尽风险,应用会报连接失败 |
| WriteLatency / ReadLatency | > 50 ms(写)/ 100 ms(读) | warning | 存储 IO 性能下降信号 |
| DiskQueueDepth | 接近实例可用 IOPS 上限 | warning | IO 排队,通常伴随延迟升高 |
| BurstBalance | < 20% | warning | gp2/gp3 突发积分不足 |
| ReplicaLag(只读副本/Aurora) | > 30 秒 | warning | 主从延迟,影响读写分离一致性 |
| SwapUsage(rdsOS) | > 100 MB | warning | 内存不足导致 swap |
控制台创建告警步骤:
-
CloudWatch 控制台 → 告警 → 所有告警 → 创建告警。
-
选择指标:AWS/RDS → 按 DBInstanceIdentifier 找到 credit-prod → 勾选 CPUUtilization,周期 5 分钟,统计 Average。
-
条件:大于 80%,连续 2 个数据点(即持续 10 分钟)。
-
通知:选择现有 SNS 主题 db-monitor-warning(未创建则先建主题)。
-
缺失数据处理:选择「视为缺失(不触发)」notBreaching。
-
填写告警名称 rds-credit-prod-cpu,创建并确认状态显示「不足数据」或「正常」。
对应 CLI 命令(credit-prod,CPU):
aws cloudwatch put-metric-alarm \
--alarm-name rds-credit-prod-cpu \
--alarm-description "credit-prod CPU 超过 80% 且持续 10 分钟" \
--metric-name CPUUtilization \
--namespace AWS/RDS \
--statistic Average \
--dimensions Name=DBInstanceIdentifier,Value=credit-prod \
--period 300 \
--evaluation-periods 2 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--alarm-actions arn:aws:sns:af-south-1:815974599660:db-monitor-warning \
--ok-actions arn:aws:sns:af-south-1:815974599660:db-monitor-warning
-
慢查询日志告警
步骤 1:参数组开启慢日志。RDS 控制台 → 参数组 → 选择实例关联的参数组 → 编辑参数:slow_query_log = 1、long_query_time = 1(生产建议 1~2 秒)、log_output = FILE(必须 FILE 才能导出到 CloudWatch Logs)。保存后应用到实例并重启(部分参数需重启生效,RDS 控制台会提示)。
步骤 2:导出到 CloudWatch Logs。控制台「实例 → 配置 → 日志与事件 → 导出到 CloudWatch Logs → 勾选 slowquery」;或执行:
aws rds modify-db-instance --db-instance-identifier credit-prod \
--enable-cloudwatch-logs-exports '["slowquery"]' --apply-immediately
导出后日志组名称为 /aws/rds/credit-prod/slowquery,稍等几分钟即可在 CloudWatch → 日志组看到慢日志流入。
步骤 3:创建 Metric Filter****。控制台路径:CloudWatch → 日志组 → /aws/rds/credit-prod/slowquery → 指标筛选条件 → 创建指标筛选条件:筛选条件模式填 "Query_time",指标名称 SlowQueries,命名空间 DBLogMetrics,指标值 1。创建后在该筛选条件页直接点「创建告警」配置 SNS 通知。对应 CLI:
# 统计慢查询条数(slowquery 每行含 "Query_time")
aws logs put-metric-filter \
--log-group-name /aws/rds/credit-prod/slowquery \
--filter-name slowquery-count \
--filter-pattern '"Query_time"' \
--metric-transformations metricName=SlowQueries,metricNamespace=DBLogMetrics,metricValue=1
# 告警:10 分钟内慢查询超过 30 条
aws cloudwatch put-metric-alarm \
--alarm-name rds-credit-prod-slowquery-count \
--metric-name SlowQueries \
--namespace DBLogMetrics \
--statistic Sum \
--period 600 \
--evaluation-periods 1 \
--threshold 30 \
--comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--alarm-actions arn:aws:sns:af-south-1:815974599660:db-monitor-warning \
--ok-actions arn:aws:sns:af-south-1:815974599660:db-monitor-warning
需要「按慢查询耗时」告警时,可用 CloudWatch Logs Subscription Filter + Lambda 解析每条日志的 Query_time 数值再告警;计数告警已能覆盖大多数生产场景。排查慢 SQL 清单可用下面的 SQL(Aurora MySQL 亦可导出到 S3 分析)。
SELECT schema_name, SUBSTRING_INDEX(sql_text, '\n', 1) AS sql_head,
COUNT(*) AS cnt, ROUND(SUM(query_time), 2) AS total_ms
FROM mysql.slow_log
WHERE start_time > NOW() - INTERVAL 10 MINUTE
GROUP BY schema_name, sql_head
ORDER BY total_ms DESC LIMIT 20;
-
审计日志告警
控制台开启审计步骤:
-
RDS 控制台 → 参数组 → 选择实例关联的参数组(或新建后关联)→ 编辑参数。
-
MySQL 8.0 设置 audit_log = 1;MariaDB 设置 server_audit_logging = ON、server_audit_output_type = FILE、server_audit_events = CONNECT,****QUERY。
-
保存并应用到实例,重启生效(RDS 控制台会提示需要重启)。
-
实例 → 配置 → 日志与事件 → 导出到 CloudWatch Logs → 勾选 audit,日志组为 /aws/rds/credit-prod/audit。
相关实现参考AWS 博客:构建经济灵活的 RDS MySQL 审计日志系统与官方文档:将 MySQL 日志发布到 CloudWatch Logs。告警配置(CLI):
# 登录失败告警(审计日志含 "Access denied")
aws logs put-metric-filter \
--log-group-name /aws/rds/credit-prod/audit \
--filter-name audit-login-fail \
--filter-pattern '"Access denied"' \
--metric-transformations metricName=AuditLoginFailures,metricNamespace=DBLogMetrics,metricValue=1
# DDL 变更告警(审计日志 Query 行含 DROP / ALTER)
aws logs put-metric-filter \
--log-group-name /aws/rds/credit-prod/audit \
--filter-name audit-ddl \
--filter-pattern '"Query" "DROP"' \
--metric-transformations metricName=AuditDDL,metricNamespace=DBLogMetrics,metricValue=1
aws cloudwatch put-metric-alarm \
--alarm-name rds-credit-prod-audit-login-fail \
--metric-name AuditLoginFailures --namespace DBLogMetrics \
--statistic Sum --period 300 --evaluation-periods 1 \
--threshold 5 --comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--alarm-actions arn:aws:sns:af-south-1:815974599660:db-monitor-critical \
--ok-actions arn:aws:sns:af-south-1:815974599660:db-monitor-critical
审计日志量远大于慢日志,生产环境请设置日志组保留期(如 30 天)并关注 CloudWatch Logs 存储费用;建议只对 DROP/ALTER/登录失败等高风险事件告警,避免全量告警淹没群消息。
-
数据库实例事件通知
RDS 实例事件(故障、维护、配置变更等)可直发 SNS(控制台:实例 → 维护与事件 → 事件通知 → 创建事件通知):
aws rds create-event-subscription \
--subscription-name rds-prod-events \
--sns-topic-arn arn:aws:sns:af-south-1:815974599660:db-monitor-warning \
--source-type db-instance \
--event-categories '["failure","maintenance","notification"]'
-
ElastiCache(Redis)监控告警
-
基础指标告警
指标位于命名空间 AWS****/ElastiCache,按 CacheClusterId 维度区分节点。推荐指标与阈值:
| 指标 | 推荐阈值 | 级别 | 说明 |
|---|---|---|---|
| EngineCPUUtilization | > 90% 持续 10 分钟 | critical | Redis 引擎 CPU,1 核节点接近 100% 即需关注 |
| CPUUtilization | > 90% | warning | 节点整体 CPU |
| DatabaseMemoryUsagePercentage | > 90% | critical | 内存逼近 maxmemory,即将触发驱逐 |
| Evictions | > 0 持续 5 分钟 | critical | 正在淘汰 key,缓存数据可能失效 |
| CacheHitRate | 较基线下降 10% 以上 | warning | 命中率突降多为 key 过期/热点失效 |
| CurrConnections | > 80% 连接上限 | warning | 连接数高企,注意 maxclients |
| ReplicationLag | > 60 秒 | warning | 主从复制延迟 |
| SwapUsage | > 50 MB | warning | 内存压力导致交换 |
| NetworkBytesIn / Out | 接近实例带宽上限 | warning | 网络带宽瓶颈 |
| CurrItems | 突增/突减 30% 以上 | info | 键数量异常变化 |
控制台创建告警路径与 3.1 相同:CloudWatch → 告警 → 创建告警 → 选择指标 AWS/ElastiCache → CacheClusterId=redis-prod-001 → EngineCPUUtilization,条件、通知与缺失数据处理配置同前。对应 CLI:
aws cloudwatch put-metric-alarm \
--alarm-name elasticache-redis-prod-engine-cpu \
--metric-name EngineCPUUtilization \
--namespace AWS/ElastiCache \
--statistic Average \
--dimensions Name=CacheClusterId,Value=redis-prod-001 \
--period 300 --evaluation-periods 2 --threshold 90 \
--comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--alarm-actions arn:aws:sns:af-south-1:815974599660:db-monitor-critical \
--ok-actions arn:aws:sns:af-south-1:815974599660:db-monitor-critical
-
慢日志告警(Redis 7.0+ 原生投递)
ElastiCache 支持将 slow-log(SLOWLOG)与引擎日志 直接投递到 CloudWatch Logs 或 Kinesis Firehose(Redis 7.0+,JSON/TEXT 格式),官方说明见ElastiCache 日志投递文档。慢日志阈值由参数组 slowlog-log-slower-than(微秒)与 slowlog-max-len 控制,修改即时生效。
控制台开启日志投递步骤:
-
ElastiCache 控制台 → Redis → 选择集群 redis-prod → 操作 → 修改(创建时同样可配置)。
-
展开「高级设置 → 日志(Logs)」。勾选 Slow logs。
-
目标类型选择 CloudWatch Logs;日志组选择「新建」,命名为 /aws/elasticache/redis-prod/slowlog。
-
日志格式选择 JSON;保存。几分钟后 CloudWatch 日志组开始出现 slowlog 记录。
对应 CLI:
# 1) 参数组:慢日志阈值 10ms,保留最近 256 条
aws elasticache modify-cache-parameter-group \
--cache-parameter-group-name redis-prod-pg \
--parameter-name-values '[
{"ParameterName":"slowlog-log-slower-than","ParameterValue":"10000"},
{"ParameterName":"slowlog-max-len","ParameterValue":"256"}]'
# 2) 开启 slow-log 投递到 CloudWatch Logs
aws elasticache modify-replication-group \
--replication-group-id redis-prod \
--log-delivery-configurations '[
{
"LogType": "slow-log",
"DestinationType": "cloudwatch-logs",
"DestinationDetails": {
"CloudWatchLogsDetails": {
"LogGroupName": "/aws/elasticache/redis-prod/slowlog"
}
},
"LogFormat": "json"
}
]'
# 3) 指标化并告警:10 分钟内慢命令超过 50 条
aws logs put-metric-filter \
--log-group-name /aws/elasticache/redis-prod/slowlog \
--filter-name redis-slowlog-count \
--filter-pattern '"command"' \
--metric-transformations metricName=RedisSlowCommands,metricNamespace=RedisLogMetrics,metricValue=1
aws cloudwatch put-metric-alarm \
--alarm-name elasticache-redis-prod-slowlog \
--metric-name RedisSlowCommands --namespace RedisLogMetrics \
--statistic Sum --period 600 --evaluation-periods 1 \
--threshold 50 --comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--alarm-actions arn:aws:sns:af-south-1:815974599660:db-monitor-warning \
--ok-actions arn:aws:sns:af-south-1:815974599660:db-monitor-warning
Redis 6.x 及更早版本不支持原生日志投递,可部署一个定时 Lambda(如每 5 分钟)连接 ElastiCache 执行 SLOWLOG GET 20 解析慢命令并推送飞书;该方案会占用少量引擎连接,建议使用只读权限账号并设置较短超时。
-
集群事件通知
aws elasticache create-event-subscription \
--subscription-name elasticache-prod-events \
--sns-topic-arn arn:aws:sns:af-south-1:815974599660:db-monitor-warning \
--source-type cache-cluster \
--event-categories '["failover","availability","configuration-change"]'
-
MongoDB 监控告警
-
自建 MongoDB(EC2 / 容器)监控
自建 MongoDB(含 docker 部署)使用 CloudWatch Agent 采集主机指标与日志,链路与其他服务一致。若已部署 Prometheus(本司已有 OPS 监控机器),也可走 Alertmanager Webhook 推飞书,见本章 5.3 备选。
-
指标采集:安装 CloudWatch Agent
一步一步操作:
-
安装 agent:Amazon Linux 2 执行 sudo yum install -y amazon-cloudwatch-agent;Ubuntu 先下载 deb 包(sudo wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb )再 sudo dpkg -i amazon-cloudwatch-agent.deb。
-
写入配置文件:将下面的 JSON 保存到 /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json。
-
启动:sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json。
-
验证:CloudWatch → 日志组出现 /mongodb/mongo-prod/mongod 与 /mongodb/mongo-prod/audit;指标命名空间出现 CWAgent(CPU/内存/磁盘)。
{
"metrics": {
"append_dimensions": {"InstanceId": "${aws:InstanceId}"},
"metrics_collected": {
"cpu": {"measurement": ["cpu_usage_active"]},
"mem": {"measurement": ["mem_used_percent"]},
"disk": {"measurement": ["disk_used_percent"]},
"netstat": {"measurement": ["tcp_established"]}
}
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{"file_path": "/var/log/mongodb/mongod.log",
"log_group_name": "/mongodb/mongo-prod/mongod",
"log_stream_name": "{instance_id}",
"timestamp_format": "%Y-%m-%dT%H:%M:%S.%fZ"},
{"file_path": "/var/log/mongodb/audit.log",
"log_group_name": "/mongodb/mongo-prod/audit",
"log_stream_name": "{instance_id}"}
]
}
}
}
}
主机级指标(CPU/内存/磁盘/连接数)即可覆盖大多数故障场景;如需 mongod 内部指标(连接数、oplog 可用量、cache 命中率),可在容器内暴露 Prometheus 指标由 CloudWatch Agent 的 Prometheus 采集能力抓取。
-
慢查询日志告警
开启慢日志 profiling。mongod 配置示例(生产建议 slowOpThresholdMs 200ms,按业务调整):
operationProfiling:
mode: slowOp
slowOpThresholdMs: 200
已运行实例可用 mongosh 临时开启(重启后需重新执行,正式环境请写入配置文件):
mongosh "mongodb://USER:PASS@HOST:27017/admin?authSource=admin"
db.setProfilingLevel(1, { slowms: 200 })
db.getProfilingStatus()
开启后慢查询会以 "Slow query" 关键词写入 mongod.log。指标化并告警:
aws logs put-metric-filter \
--log-group-name /mongodb/mongo-prod/mongod \
--filter-name mongo-slowquery-count \
--filter-pattern '"Slow query"' \
--metric-transformations metricName=MongoSlowQueries,metricNamespace=MongoLogMetrics,metricValue=1
aws cloudwatch put-metric-alarm \
--alarm-name mongo-prod-slowquery \
--metric-name MongoSlowQueries --namespace MongoLogMetrics \
--statistic Sum --period 600 --evaluation-periods 1 \
--threshold 20 --comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--alarm-actions arn:aws:sns:af-south-1:815974599660:db-monitor-warning \
--ok-actions arn:aws:sns:af-south-1:815974599660:db-monitor-warning
-
审计日志告警
开启步骤:修改 mongod.conf 增加 auditLog 段(见下);重启 mongod(systemctl restart mongod 或 docker restart mongod 容器);确认 /var/log/mongodb/audit.log 开始写入 JSON 审计记录。
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.log
系统日志同时追加:
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
审计事件类型(atype)包括 authenticate、createCollection、dropCollection、dropDatabase、killop 等,默认记录所有可审计操作,可按 filter 仅保留认证与 DDL。告警认证失败与高危操作:
# 认证失败(审计 JSON 中 authenticate 事件带 error / UserNotFound)
aws logs put-metric-filter \
--log-group-name /mongodb/mongo-prod/audit \
--filter-name mongo-auth-fail \
--filter-pattern '"authenticate" "error"' \
--metric-transformations metricName=MongoAuthFailures,metricNamespace=MongoLogMetrics,metricValue=1
# 高危操作:删库 / 删表
aws logs put-metric-filter \
--log-group-name /mongodb/mongo-prod/audit \
--filter-name mongo-drop \
--filter-pattern '"dropCollection"' \
--metric-transformations metricName=MongoDrops,metricNamespace=MongoLogMetrics,metricValue=1
aws cloudwatch put-metric-alarm \
--alarm-name mongo-prod-auth-fail \
--metric-name MongoAuthFailures --namespace MongoLogMetrics \
--statistic Sum --period 300 --evaluation-periods 1 \
--threshold 5 --comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--alarm-actions arn:aws:sns:af-south-1:815974599660:db-monitor-critical \
--ok-actions arn:aws:sns:af-south-1:815974599660:db-monitor-critical
-
MongoDB Atlas 告警到飞书
若使用 MongoDB Atlas 托管:项目 → Alerts → Create Alert(集群可用性、CPU、内存、慢查询、oplog 等),通知方式选 Amazon SNS(Atlas 原生支持)或 Webhook:
-
SNS 路径(推荐):Atlas 通知选择 Amazon SNS,填入上面创建的 db-monitor-warning / db-monitor-critical 主题 ARN,复用 Lambda 转发器,链路与 AWS 原生一致。
-
Webhook 路径:Atlas Webhook 推送的是 Atlas 固定格式 JSON,与飞书机器人格式不一致,需要一个小中转(Lambda + API Gateway 或已有告警网关)把 Atlas 告警体转换成飞书 text/card 再 POST。
-
慢查询明细:Atlas Performance Advisor 提供慢查询分析;如需告警后附带明细,可由定时 Lambda 调用 Atlas API(slowQueryLogs 接口)拉取后一并推送。
-
备选:复用已有 Prometheus 链路
本司已有 Prometheus 监控(OPS 机器),若 MongoDB / Redis 自建实例已接入 Prometheus,可直接配置 Alertmanager Webhook receiver 指向一个轻量中转(或复用 Lambda + API Gateway),将告警转发到飞书。该路径与 CloudWatch 链路二选一,避免同一告警双发。
-
生产级告警运维实践
-
告警分级与主题规划
| 级别 | 场景示例 | 处置要求 |
|---|---|---|
| critical | 实例不可用、存储将满、连接耗尽、Redis 驱逐、审计登录失败、MongoDB 删库删表 | 立即响应(值班群 + @值班人),15 分钟内处置 |
| warning | CPU 高、内存压力、慢查询增多、副本延迟、带宽瓶颈 | 当天处理,滚动巡检,持续超时自动升级 |
| info | 维护事件、配置变更、容量通知、键数量异常 | 记录即可,不打扰值班 |
-
告警内容标准化
告警消息按统一模板(Lambda 中 format_alarm 已实现):告警级别 → 服务/实例 → 指标与当前值 → 阈值与比较符 → 状态变更时间 → CloudWatch 控制台链接。控制台链接模板:
https://console.aws.amazon.com/cloudwatch/home?region=af-south-1#alarmsV2:alarm/ALARM_NAME
-
抑制抖动与去重
-
告警使用较长的评估周期(5 分钟 × 2)天然抑制毛刺;不要在 Lambda 端对同一事件频繁重试。
-
CloudWatch 仅在状态变化时触发 SNS,天然去重;若接入 SQS,消费侧按 AlarmArn + StateChangeTime 做幂等去重。
-
treat-missing-data 统一用 notBreaching,避免实例维护/数据缺失期间误报 ALARM。
-
可靠性与成本控制
-
生产建议 SNS → SQS → Lambda(队列 + DLQ),防止 Lambda 并发限制或瞬时故障丢消息;Lambda 端开启重试与最大年龄告警。
-
密钥管理:Webhook Secret 用环境变量 + KMS 加密;轮换时只改环境变量,不重新部署代码。
-
成本:告警数量(约 $0.10/条/月)、CloudWatch Logs 存储(审计日志量大,建议 30 天保留期)、增强监控按实例收费,60 秒粒度即可;Performance Insights 按需开启。
-
多环境隔离:dev/prod 用不同 SNS 主题与飞书群,避免开发环境噪音淹没生产告警。
-
验收与故障演练
| 演练场景 | 操作 | 预期结果 |
|---|---|---|
| CPU 高负载 | 对 RDS/Redis 施加压测(sysbench / redis-benchmark) | 飞书群收到 warning 级 ALARM,负载恢复后收到 OK |
| 慢查询 | 测试环境执行 SELECT SLEEP(5); | 慢日志入 CloudWatch Logs,10 分钟内收到慢查询告警 |
| 审计事件 | 用错误密码连续登录 5 次;执行 DROP 测试表 | 收到审计登录失败 / DDL 告警 |
| Redis 驱逐 | 测试集群设置小 maxmemory 并写入大 key | Evictions 指标告警触发 |
| MongoDB 慢查询 | 执行带 $where / 全表扫描的慢查询 | mongod.log 出现 Slow query,收到慢查询告警 |
| 链路可用性 | 手动向 SNS 主题发布一条测试消息 | Lambda 正常解析并推送到飞书群 |
-
飞书机器人在告警群可用,签名校验生效
-
2.4 的三种测试方式(本地 / 控制台 Test / SNS 联调)均已跑通
-
Lambda 可接收 SNS 消息并成功 POST 飞书
-
RDS 慢日志/审计日志已导出到 CloudWatch Logs
-
ElastiCache Redis 7+ 慢日志投递到 CloudWatch Logs
-
MongoDB 审计日志开启并按认证失败/删库告警
-
所有告警均已配置 OK 恢复通知与 notBreaching
-
演练场景全部在测试/灰度环境验证通过
-
附录:常用参数与命令速查
| 服务 | 参数 / 配置 | 说明 |
|---|---|---|
| RDS MySQL 慢日志 | slow_query_log=1,long_query_time=1,log_output=FILE | 必须 FILE 才能导出 CloudWatch Logs |
| RDS MySQL 审计 | MySQL 8.0:audit_log=1;MariaDB:server_audit_logging=ON | 导出日志类型 audit |
| ElastiCache 慢日志 | slowlog-log-slower-than=10000(μs),slowlog-max-len=256 | Redis 7+ 投递 CloudWatch Logs |
| MongoDB 慢日志 | operationProfiling.mode=slowOp,slowOpThresholdMs=200 | 日志关键词 Slow query |
| MongoDB 审计 | auditLog.destination=file,format=JSON | atype 含 authenticate / dropCollection |
| 告警命名空间 | AWS/RDS · AWS/ElastiCache · rdsOS · 自建主机 · DBLogMetrics | 日志指标统一放 DBLogMetrics 便于管理 |
浙公网安备 33010602011771号