本文目录导读:

- 方案一:Linux Shell 脚本 (最简单,无需额外库)
- 方案二:Python 脚本 (功能强大,支持 HTML、附件)
- 方案三:PowerShell 脚本 (Windows 环境)
- 注意事项与最佳实践
- 推荐选择
实现脚本通过邮件发送告警通知,通常采用两种主流方式:调用系统自带的邮件命令 (如 Linux 的 mail 或 sendmail) 或 在脚本中嵌入编程语言的邮件库。
以下是针对不同场景的几种具体实现方案:
Linux Shell 脚本 (最简单,无需额外库)
这是运维场景中最常用的方法,利用系统自带的 mail 或 sendmail 命令。
安装邮件客户端
大多数 Linux 系统需要先安装 mailutils(Debian/Ubuntu)或 mailx(CentOS/RHEL)。
# Debian/Ubuntu sudo apt-get install -y mailutils # CentOS/RHEL sudo yum install -y mailx
配置邮件服务(或使用外部 SMTP)
-
本地 MTA(简单但不稳定):安装
postfix并配置为本地发送,容易被反垃圾,适合内网测试。sudo apt-get install postfix -
使用外部 SMTP (推荐):通过配置
mailx使用 Gmail、QQ邮箱、企业微信邮箱等。编辑
/etc/mail.rc文件,在文件末尾添加(以 QQ邮箱为例):# QQ邮箱 发信配置 set smtp=smtps://smtp.qq.com:465 set smtp-auth=login set smtp-auth-user=你的QQ邮箱@qq.com set smtp-auth-password=你的授权码 # 注意:不是QQ密码,是邮箱的SMTP授权码 set ssl-verify=ignore set nss-config-dir=/etc/pki/nssdb/
不同邮箱服务器的参数不同(Gmail/163/Outlook 需对应修改
smtp地址和端口)。
告警脚本示例
创建一个 send_alert.sh 文件:
#!/bin/bash # 定义邮件参数 TO="admin@example.com" SUBJECT="[告警] 服务器磁盘空间不足" FROM="monitor@yourcompany.com" # 定义告警内容 (可以从命令结果获取) CONTENT="您好,服务器 $HOSTNAME 磁盘使用率已超过 90%,请及时处理。\n\n当前时间:$(date)" # 发送邮件 # 方法1: 使用 echo 管道 echo -e "$CONTENT" | mail -s "$SUBJECT" -r "$FROM" "$TO" # 方法2: 使用 sendmail (更底层) # echo -e "Subject: $SUBJECT\nFrom: $FROM\n$CONTENT" | sendmail -t "$TO" echo "告警邮件已发送至 $TO"
Python 脚本 (功能强大,支持 HTML、附件)
Python 的 smtplib 库是发送邮件的标准方案,可以发送纯文本或 HTML 内容,格式更美观。
准备 Python 环境 (内置库,无需额外安装)
告警脚本示例:send_alert.py
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import socket
# 邮件配置
smtp_server = "smtp.qq.com" # SMTP服务器
smtp_port = 465 # SSL端口
sender_email = "your_email@qq.com"
sender_password = "你的授权码" # 不是密码
receiver_email = ["admin@example.com", "ops@example.com"] # 收件人列表
# 构建邮件内容
subject = f"[告警] 服务器 {socket.gethostname()} 发生故障"
content = f"""
<h2>系统告警通知</h2>
<p>服务器: {socket.gethostname()}</p>
<p>时间: {__import__('datetime').datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
<p>级别: <span style='color:red;'>CRITICAL 严重</span></p>
<p>详情: Nginx 服务停止运行,响应超时。</p>
<hr>
<p>请相关人员及时排查。</p>
"""
# 发送纯文本邮件
# msg = MIMEText(content, 'plain', 'utf-8')
# 发送 HTML 格式邮件 (更美观)
msg = MIMEText(content, 'html', 'utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = sender_email
msg['To'] = ", ".join(receiver_email)
try:
# 建立 SSL 加密连接
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
server.login(sender_email, sender_password)
server.sendmail(sender_email, receiver_email, msg.as_string())
print("告警邮件发送成功")
except Exception as e:
print(f"邮件发送失败: {e}")
finally:
server.quit()
集成到监控脚本中
# 假设这是你的监控逻辑
import subprocess
# 检查服务状态
result = subprocess.run(['systemctl', 'is-active', 'nginx'], capture_output=True)
if result.stdout.decode().strip() != 'active':
# 调用上面的发送函数
send_alert()
PowerShell 脚本 (Windows 环境)
如果监控的是 Windows 服务器,可以使用内嵌的 Send-MailMessage 命令。
告警脚本示例:Send-Alert.ps1
$SmtpServer = "smtp.office365.com"
$SmtpPort = 587
$Username = "monitor@yourcompany.com"
$Password = "你的密码" # 或使用凭据对象
$To = "admin@yourcompany.com"
$Subject = "[告警] Windows 服务器 CPU 过高"
$Body = @"
服务器:$env:COMPUTERNAME
时间:$(Get-Date)
事件:CPU 使用率持续 5 分钟超过 95%
建议:检查异常进程或扩展资源。
"@
# 创建凭据
$SecurePass = ConvertTo-SecureString $Password -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential($Username, $SecurePass)
# 发送邮件
Send-MailMessage -From $Username -To $To -Subject $Subject -Body $Body `
-SmtpServer $SmtpServer -Port $SmtpPort -UseSsl `
-Credential $Credential
if ($?) {
echo "告警邮件发送成功"
}
注意事项与最佳实践
- 使用授权码,而非密码:所有主流邮箱 (QQ、163、Gmail) 都要求使用 SMTP 授权码,直接使用登录密码会失败且不安全。
- 邮件头处理:如果收件人或主题包含中文,务必指定编码 (
utf-8),否则会出现乱码。 - 限频与合并:如果脚本循环执行(如每 5 分钟检查一次),不要每个故障都发一封邮件,建议:
- 使用 “窗口期”:第一次发警告,如果在 1 小时内状态未恢复,不再重复发送相同警报。
- 使用 “合并告警”:将多个告警汇总到一封邮件中。
- 邮件不被视为垃圾邮件:设置合理的
From域名,避免使用noreply@localhost,外部 SMTP 比本地 MTA 更可靠。 - 日志与失败处理:邮件发送失败不要影响主监控脚本的执行,将要发送的内容先写入文件中,下次发送时尝试带出。
推荐选择
| 环境 | 推荐方式 |
|---|---|
| 简单 Linux 系统管理 | mail + /etc/mail.rc 配置 (方案一) |
| 复杂告警、格式化内容 | Python + smtplib (方案二) |
| Windows 环境 | PowerShell Send-MailMessage (方案三) |
| 容器/云原生环境 | 推荐使用 Webhook 发送到企业微信、钉钉或 Slack,而非直接发邮件,如果需要发,参考方案二。 |