kenneth-lin

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

AWS 数据库监控告警到飞书(生产级操作指南)

  1. 方案概述与告警链路

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

暂时无法在飞书文档外展示此内容

生产级设计要点:

  • 慢日志与审计日志先写入 CloudWatch Logs,再用 Metric Filter 转成指标后告警,避免逐条扫描日志。

  • 告警按 critical / warning / info 三级拆分 SNS 主题,分别推送不同群或机器人。

  • Lambda 转发器保持无状态、幂等,只负责「解析 + 格式化 + 签名 + 推送」,可安全重试。

  • Webhook 开启签名校验;密钥存放于 Lambda 环境变量(KMS 加密),禁止入库入仓。

  1. 前置准备:飞书机器人 + Lambda 转发器

  2. 创建飞书自定义机器人

一步一步操作:

  1. 打开目标告警群,点击右上角「设置」→「群机器人」→「添加机器人」→「自定义机器人」。

  2. 给机器人命名(如「AWS 数据库告警」),点击「添加」。添加完成后复制 Webhook 地址,格式为 https://open.feishu.cn/open-apis/bot/v2/hook/xxx 。

  3. 回到机器人详情,在「安全设置」中勾选「签名校验」,点击「复制」保存生成的密钥(Secret)。生产环境建议同时勾选「IP 地址白名单」,仅放行 Lambda 的出口网段(如无固定出口可先不启用,依赖签名校验)。

  4. 点击「保存」。验证方法:按 2.4 测试方式向 Webhook 发一条测试消息,确认群内能收到。

官方接入说明见飞书自定义机器人使用指南。

Webhook 与 Secret 相当于告警群的「写权限」,禁止写入代码仓库、CI 变量或公开文档;统一放入 Lambda 环境变量或 AWS Secrets Manager,并启用 KMS 加密。

  1. 部署 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))
  1. 部署步骤(控制台)

  2. 创建 IAM 执行角色:IAM 控制台 → 角色 → 创建角色 → 选择 AWS 服务 / Lambda → 附加托管策略 AWSLambdaBasicExecutionRole → 命名 lambda-feishu-basic。该角色只允许函数写 CloudWatch Logs。

  3. 创建函数:Lambda 控制台 → 创建函数 → 从零开始 → 名称 feishu-alert-forwarder,运行时 Python 3.12,架构 x86_64,权限选择刚才的角色。

  4. 粘贴代码:在 lambda_function.py 文件中粘贴上面的完整代码,点击「Deploy(部署)」。处理器保持默认 lambda_function.handler——代码入口函数必须命名为 lambda_handler,二者才能对应上。

  5. 设置****环境变量:配置 → 环境变量 → 添加两项:FEISHU_WEBHOOK_URL(Webhook 地址)、FEISHU_SECRET(签名密钥);可勾选「KMS 密钥加密」。

  6. 调整基本设置:配置 → 常规配置 → 编辑:超时 10 秒、内存 128 MB。

  7. 验证函数可运行:先按 2.4 的测试方式一发送测试事件,确认飞书群收到消息后再继续 SNS 订阅。

若执行时报 Handler 'xxx' missing on module 'lambda_function'(Runtime.HandlerNotFound),说明函数入口名与「处理器」配置不一致:把代码函数名改为 lambda_handler(推荐,与默认配置对应),或把处理器改为 lambda_function.handler。

  1. 部署步骤(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(公网)。

  1. 创建 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(新加坡),需在该区域重复创建主题、函数与权限。

  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 事件(验证线上函数)。

  1. Lambda 控制台打开函数 feishu-alert-forwarder → 右上角「测试」→「配置测试事件」。

  2. 事件模板选择 SNS 通知(或直接自定义),把上面 test_event.json 的内容粘贴进去,命名 test-event,保存。

  3. 点击「测试」。执行结果区域应显示执行成功;若失败,展开日志流查看具体异常。

  4. 检查飞书告警群:应收到「【严重】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、但飞书未收到告警:按以下顺序排查。

  1. 看函数日志: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 表示签名/密钥问题。

  2. 核对****环境变量:FEISHU_WEBHOOK_URL / FEISHU_SECRET 是否已配置;未配置时 WEBHOOK 为空,函数会直接报错。

  3. 核对订阅与权限:aws sns list-subscriptions-by-topic --topic-arn arn:aws:sns:af-south-1:815974599660:db-monitor-warning,确认存在 Lambda 订阅,且 add-permission 的 source-arn 与主题 ARN 一致。

  4. 确认区域一致:SNS 的 Lambda 订阅必须同区域;主题在 af-south-1,Lambda 也必须创建在 af-south-1。

  5. 用控制台 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
  1. RDS / Aurora MySQL 监控告警

  2. 基础指标告警

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

控制台创建告警步骤:

  1. CloudWatch 控制台 → 告警 → 所有告警 → 创建告警。

  2. 选择指标:AWS/RDS → 按 DBInstanceIdentifier 找到 credit-prod → 勾选 CPUUtilization,周期 5 分钟,统计 Average。

  3. 条件:大于 80%,连续 2 个数据点(即持续 10 分钟)。

  4. 通知:选择现有 SNS 主题 db-monitor-warning(未创建则先建主题)。

  5. 缺失数据处理:选择「视为缺失(不触发)」notBreaching。

  6. 填写告警名称 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. 慢查询日志告警

步骤 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;
  1. 审计日志告警

控制台开启审计步骤:

  1. RDS 控制台 → 参数组 → 选择实例关联的参数组(或新建后关联)→ 编辑参数。

  2. MySQL 8.0 设置 audit_log = 1;MariaDB 设置 server_audit_logging = ON、server_audit_output_type = FILE、server_audit_events = CONNECT,****QUERY。

  3. 保存并应用到实例,重启生效(RDS 控制台会提示需要重启)。

  4. 实例 → 配置 → 日志与事件 → 导出到 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/登录失败等高风险事件告警,避免全量告警淹没群消息。

  1. 数据库实例事件通知

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"]'
  1. ElastiCache(Redis)监控告警

  2. 基础指标告警

指标位于命名空间 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
  1. 慢日志告警(Redis 7.0+ 原生投递)

ElastiCache 支持将 slow-log(SLOWLOG)与引擎日志 直接投递到 CloudWatch Logs 或 Kinesis Firehose(Redis 7.0+,JSON/TEXT 格式),官方说明见ElastiCache 日志投递文档。慢日志阈值由参数组 slowlog-log-slower-than(微秒)与 slowlog-max-len 控制,修改即时生效。

控制台开启日志投递步骤:

  1. ElastiCache 控制台 → Redis → 选择集群 redis-prod → 操作 → 修改(创建时同样可配置)。

  2. 展开「高级设置 → 日志(Logs)」。勾选 Slow logs。

  3. 目标类型选择 CloudWatch Logs;日志组选择「新建」,命名为 /aws/elasticache/redis-prod/slowlog。

  4. 日志格式选择 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 解析慢命令并推送飞书;该方案会占用少量引擎连接,建议使用只读权限账号并设置较短超时。

  1. 集群事件通知

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"]'
  1. MongoDB 监控告警

  2. 自建 MongoDB(EC2 / 容器)监控

自建 MongoDB(含 docker 部署)使用 CloudWatch Agent 采集主机指标与日志,链路与其他服务一致。若已部署 Prometheus(本司已有 OPS 监控机器),也可走 Alertmanager Webhook 推飞书,见本章 5.3 备选。

  1. 指标采集:安装 CloudWatch Agent

一步一步操作:

  1. 安装 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。

  2. 写入配置文件:将下面的 JSON 保存到 /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json。

  3. 启动: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。

  4. 验证: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 采集能力抓取。

  1. 慢查询日志告警

开启慢日志 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
  1. 审计日志告警

开启步骤:修改 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
  1. MongoDB Atlas 告警到飞书

若使用 MongoDB Atlas 托管:项目 → Alerts → Create Alert(集群可用性、CPU、内存、慢查询、oplog 等),通知方式选 Amazon SNS(Atlas 原生支持)或 Webhook:

  1. SNS 路径(推荐):Atlas 通知选择 Amazon SNS,填入上面创建的 db-monitor-warning / db-monitor-critical 主题 ARN,复用 Lambda 转发器,链路与 AWS 原生一致。

  2. Webhook 路径:Atlas Webhook 推送的是 Atlas 固定格式 JSON,与飞书机器人格式不一致,需要一个小中转(Lambda + API Gateway 或已有告警网关)把 Atlas 告警体转换成飞书 text/card 再 POST。

  3. 慢查询明细:Atlas Performance Advisor 提供慢查询分析;如需告警后附带明细,可由定时 Lambda 调用 Atlas API(slowQueryLogs 接口)拉取后一并推送。

  4. 备选:复用已有 Prometheus 链路

本司已有 Prometheus 监控(OPS 机器),若 MongoDB / Redis 自建实例已接入 Prometheus,可直接配置 Alertmanager Webhook receiver 指向一个轻量中转(或复用 Lambda + API Gateway),将告警转发到飞书。该路径与 CloudWatch 链路二选一,避免同一告警双发。

  1. 生产级告警运维实践

  2. 告警分级与主题规划

级别 场景示例 处置要求
critical 实例不可用、存储将满、连接耗尽、Redis 驱逐、审计登录失败、MongoDB 删库删表 立即响应(值班群 + @值班人),15 分钟内处置
warning CPU 高、内存压力、慢查询增多、副本延迟、带宽瓶颈 当天处理,滚动巡检,持续超时自动升级
info 维护事件、配置变更、容量通知、键数量异常 记录即可,不打扰值班
  1. 告警内容标准化

告警消息按统一模板(Lambda 中 format_alarm 已实现):告警级别 → 服务/实例 → 指标与当前值 → 阈值与比较符 → 状态变更时间 → CloudWatch 控制台链接。控制台链接模板:

https://console.aws.amazon.com/cloudwatch/home?region=af-south-1#alarmsV2:alarm/ALARM_NAME
  1. 抑制抖动与去重

  • 告警使用较长的评估周期(5 分钟 × 2)天然抑制毛刺;不要在 Lambda 端对同一事件频繁重试。

  • CloudWatch 仅在状态变化时触发 SNS,天然去重;若接入 SQS,消费侧按 AlarmArn + StateChangeTime 做幂等去重。

  • treat-missing-data 统一用 notBreaching,避免实例维护/数据缺失期间误报 ALARM。

  1. 可靠性与成本控制

  • 生产建议 SNS → SQS → Lambda(队列 + DLQ),防止 Lambda 并发限制或瞬时故障丢消息;Lambda 端开启重试与最大年龄告警。

  • 密钥管理:Webhook Secret 用环境变量 + KMS 加密;轮换时只改环境变量,不重新部署代码。

  • 成本:告警数量(约 $0.10/条/月)、CloudWatch Logs 存储(审计日志量大,建议 30 天保留期)、增强监控按实例收费,60 秒粒度即可;Performance Insights 按需开启。

  • 多环境隔离:dev/prod 用不同 SNS 主题与飞书群,避免开发环境噪音淹没生产告警。

  1. 验收与故障演练

演练场景 操作 预期结果
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

  • 演练场景全部在测试/灰度环境验证通过

  1. 附录:常用参数与命令速查

服务 参数 / 配置 说明
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 便于管理

官方参考:RDS 日志发布到 CloudWatch Logs、ElastiCache 日志投递、飞书自定义机器人接入。

posted on 2026-10-28 09:39  kenneth-lin  阅读(7)  评论(0)    收藏  举报