feat: 邮件告警与每日报告优化(HTML+UTF-8、阈值实时告警、支付卡单检测、重试与状态机)
Some checks failed
Deploy Backend / deploy (push) Has been cancelled

This commit is contained in:
2026-08-21 09:02:59 +08:00
parent 3cce81321f
commit a037ea3064
4 changed files with 570 additions and 68 deletions

70
scripts/mail-lib.sh Normal file
View File

@@ -0,0 +1,70 @@
#!/bin/bash
# ===========================================
# mail-lib.sh — 邮件发送共享库
# 供 daily-report.sh / alert.sh 复用:
# mail_send <主题> <HTML正文> (带重试 + 日志 + 轮转)
# ===========================================
# ---------- 可配置项(环境变量可覆盖) ----------
: "${MAIL_TO:=m943790568@163.com}" # 收件人,多个用逗号分隔
: "${MAIL_FROM:=ASD 监控 <m943790568@163.com>}" # 发件人显示名
: "${MAIL_ACCOUNT:=default}" # msmtp 账户(~/.msmtprc 中的 account
: "${MAIL_LOG_DIR:=/root/rust/scripts/logs}" # 日志目录
: "${MAIL_RETRY:=3}" # 发送重试次数
: "${MAIL_LOG_MAX_KB:=1024}" # mail.log 轮转阈值KB
mkdir -p "$MAIL_LOG_DIR" 2>/dev/null || true
# 写日志
mail_log() {
local level="$1"; shift
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [${level}] $*" >> "${MAIL_LOG_DIR}/mail.log" 2>/dev/null || true
}
# 日志轮转:超过阈值保留末尾 200 行
mail_rotate_log() {
local f="${MAIL_LOG_DIR}/mail.log"
[ -f "$f" ] || return 0
local size_kb=$(( $(stat -c %s "$f" 2>/dev/null || echo 0) / 1024 ))
if [ "$size_kb" -gt "$MAIL_LOG_MAX_KB" ]; then
tail -n 200 "$f" > "$f.tmp" 2>/dev/null && mv "$f.tmp" "$f" 2>/dev/null || true
mail_log INFO "mail.log 已轮转"
fi
}
# 发送 HTML 邮件UTF-8失败自动重试
# 用法: mail_send "主题" "HTML 正文"
mail_send() {
local subject="$1" body="$2"
mail_rotate_log
local recipients headers
recipients=$(echo "$MAIL_TO" | tr ',' ' ')
headers=$(cat <<EOF
From: ${MAIL_FROM}
To: ${MAIL_TO}
Subject: ${subject}
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit
EOF
)
local attempt=1 ok=0
while [ "$attempt" -le "$MAIL_RETRY" ]; do
if { echo "$headers"; echo; echo "$body"; } | msmtp -a "$MAIL_ACCOUNT" $recipients 2>>"${MAIL_LOG_DIR}/mail.log"; then
ok=1
mail_log INFO "邮件发送成功: ${subject}${MAIL_TO}(第 ${attempt} 次尝试)"
break
fi
mail_log WARN "邮件发送失败(第 ${attempt}/${MAIL_RETRY} 次): ${subject}"
attempt=$((attempt + 1))
[ "$attempt" -le "$MAIL_RETRY" ] && sleep $((attempt * 5))
done
if [ "$ok" -ne 1 ]; then
mail_log ERROR "邮件最终发送失败: ${subject}"
return 1
fi
return 0
}