温馨提示×

CentOS系统消息推送策略

小樊
41
2025-12-09 17:11:37
栏目: 智能运维

CentOS 系统消息推送策略

一 目标与总体架构

  • 明确推送目标:面向本机登录用户本地/集中日志系统邮件收件人企业IM/Webhook桌面环境
  • 分层设计:
    • 采集层:用 rsyslog/journald 统一采集与转发。
    • 触发层:用 cron/systemd 定时器日志监控脚本 触发通知。
    • 通道层:用 wall、mailx、curl(Webhook)、Pushover 等发送。
    • 控制层:用 频率限制、去重、告警分级 避免风暴。

二 推送通道选型与配置要点

  • 本机广播:使用 wall 向所有登录终端推送,适合维护窗口、紧急通告。
  • 邮件通知:配置 mailx/postfix 发送告警邮件,适合运维与值班人员。
  • 企业IM/Webhook:用 curl 调用 Slack/Telegram/Pushover 等 Webhook,适合即时协同。
  • 自建消息平台:部署 Gotify 提供站内消息与 API,前端可配 Nginx 反向代理与 WebSocket。
  • 桌面通知:在 GNOME 等桌面用 notify-send(需 D-Bus/libnotify),适合有 GUI 的运维终端。
  • 日志集中:用 rsyslog 将日志转发到远程 Syslog 服务器,便于审计与统一告警接入。

三 定时与频率控制

  • cron:适合固定频率推送,如“每天 08:00 广播”。示例:0 8 * * * /usr/bin/wall "..."
  • systemd 定时器:更现代的定时方式,支持日历表达式与持久化。示例:OnCalendar=*-*-* 08:00:00Persistent=true
  • 频率限制与去重:
    • 在脚本内记录上次发送时间告警指纹(如错误摘要的哈希),超过阈值(如 15 分钟)才发送。
    • 对相同告警使用指数退避最大重试次数,避免告警风暴。
    • 将“恢复通知”与“触发通知”配对,避免只报一次不报恢复。

四 日志驱动的高可靠推送

  • 远程日志:在客户端 /etc/rsyslog.conf 添加 *.* @192.0.2.10:514(UDP)或 *.* @@192.0.2.10:514(TCP);重启 systemctl restart rsyslog。服务器端启用 UDP/TCP 监听并配置存储模板。
  • 日志级别与筛选:利用 syslog 8 级(0 EMERG~7 DEBUG)做分级;仅将 WARNING/ERR/CRIT 等高级别事件推送至 IM/邮件,其余写入日志。
  • 本地实时扫描:用 journalctl -f -u nginxjournalctl --since "5 min ago" 结合 grep 捕获关键字,触发 Webhook/邮件。
  • 发送可靠性:Webhook 使用重试+退避超时;邮件启用队列与重投;关键告警同时走IM+邮件双通道。

五 实战最小配置示例

  • 场景:当系统出现 ERROR 时,向 Slack 推送,并每 15 分钟最多推送一次;每天 08:00 对本机用户做一次例行广播。
  • 步骤
    1. 准备 Slack Webhook:在 Slack 创建 Incoming Webhook,保存 URL
    2. 告警脚本 /usr/local/bin/alert.sh
      #!/usr/bin/env bash
      set -euo pipefail
      WEBHOOK="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
      STATE_FILE="/var/run/last_alert.err"
      THROTTLE=900  # 15 minutes
      
      ts() { date +%s; }
      now() { ts; }
      read last_ts < "$STATE_FILE" 2>/dev/null || last_ts=0
      if (( now() - last_ts < THROTTLE )); then
        exit 0
      fi
      
      if journalctl -b --since "5 min ago" -p err --no-pager | grep -q .; then
        msg="[$(hostname)] $(date): ERROR found:\n$(journalctl -b --since "5 min ago" -p err --no-pager -q | tail -20)"
        curl -s -X POST -H 'Content-type: application/json' \
          --data "{\"text\":\"$msg\"}" "$WEBHOOK"
        echo "$(now)" > "$STATE_FILE"
      fi
      
      chmod +x /usr/local/bin/alert.sh
    3. 定时执行(cron):每 5 分钟检查一次
      */5 * * * * /usr/local/bin/alert.sh
      
    4. 每日广播(systemd 定时器):
      • 服务 /etc/systemd/system/daily-broadcast.service
        [Unit]
        Description=Daily broadcast message
        [Service]
        Type=oneshot
        ExecStart=/usr/bin/wall "【运维通告】今日巡检完成,系统运行正常。"
        
      • 定时器 /etc/systemd/system/daily-broadcast.timer
        [Unit]
        Description=Run daily broadcast at 08:00
        [Timer]
        OnCalendar=*-*-* 08:00:00
        Persistent=true
        Unit=daily-broadcast.service
        [Install]
        WantedBy=timers.target
        
      • 启用
        systemctl daemon-reload
        systemctl enable --now daily-broadcast.timer
        
    5. 可选:将 ERROR 同时邮件通知
      echo "$(journalctl -b --since "5 min ago" -p err --no-pager -q | tail -50)" \
        | mail -s "[$(hostname)] ERROR 告警" ops@example.com
      

0