Files
aiops/backend/controller/alert_notify_message.go
T
LoganandClaude 471353e3d7 feat: 监控告警体系统一重构 + 自动化任务调度引擎 + 监控大屏拆分
告警中心
- 新增统一告警(alert_unified)、监控告警规则(monitor_alert_rule)、指标目录(alert_metric_catalog)
- 通知策略与消息分发(alert_notify_policy/dispatch/message)、静默规则
- 告警引擎按阈值/SNMP 拆分(alert_engine_monitor/snmp)

监控采集
- SNMP 常量/模板与历史指标(snmp templates/constants、snmp_metrics_history、snmp_collect)
- 中间件监控 Redis 采集与种子(middleware_monitor_redis/seed)
- 站点探测 pkg(siteprobe) + 站点视图(site_view)

自动化任务
- cron 调度器(cronscheduler)、脚本运行器(scriptrunner)、系统任务(systask)及运行记录(cron_job_run、system_task)

审计与凭证
- 审计设置(audit_setting) + 历史清理(auditcleaner)

前端
- 监控页面(host/middleware/site/snmp)拆分为子模块并大屏化
- 告警中心多 Tab(规则/指标目录/通知策略/静默)、任务管理组件重构、Agent CLI Markdown 渲染
- 移除旧脚本卡片/详情/日志组件,统一为 ScriptTable/ScriptCodeEditor/TerminalOutput

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-01 23:44:45 +08:00

137 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package controller
import (
"fmt"
"net/http"
"strings"
"time"
"ezops/model"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
const (
defaultNotifyTitleTemplate = "[{{severity_label}}] {{rule_name}} — {{hostname}} ({{metric}})"
defaultNotifyFooterTemplate = "{{time}} | {{platform}}"
defaultNotifyPlatformName = "AIOps 智能运维平台"
)
// ensureNotifySettings 确保全局消息模版存在 // Logan.Li
func ensureNotifySettings(db *gorm.DB) model.AlertNotifySettings {
var s model.AlertNotifySettings
if err := db.First(&s).Error; err != nil {
s = model.AlertNotifySettings{
TitleTemplate: defaultNotifyTitleTemplate,
FooterTemplate: defaultNotifyFooterTemplate,
PlatformName: defaultNotifyPlatformName,
}
db.Create(&s)
}
if s.PlatformName == "" {
s.PlatformName = defaultNotifyPlatformName
}
return s
}
// GetNotifyMessageSettings GET /alerts/notify-message-settings // Logan.Li
func (h *AlertHandler) GetNotifyMessageSettings(c *gin.Context) {
s := ensureNotifySettings(h.db)
c.JSON(http.StatusOK, model.Response{Code: 200, Data: s})
}
// SaveNotifyMessageSettings PUT /alerts/notify-message-settings // Logan.Li
func (h *AlertHandler) SaveNotifyMessageSettings(c *gin.Context) {
var req struct {
TitleTemplate string `json:"title_template"`
FooterTemplate string `json:"footer_template"`
PlatformName string `json:"platform_name"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, model.Response{Code: 400, Message: "请求参数错误: " + err.Error()})
return
}
s := ensureNotifySettings(h.db)
updates := map[string]interface{}{
"title_template": strings.TrimSpace(req.TitleTemplate),
"footer_template": strings.TrimSpace(req.FooterTemplate),
"platform_name": strings.TrimSpace(req.PlatformName),
}
if updates["platform_name"] == "" {
updates["platform_name"] = defaultNotifyPlatformName
}
h.db.Model(&s).Updates(updates)
h.db.First(&s, s.ID)
c.JSON(http.StatusOK, model.Response{Code: 200, Data: s, Message: "消息模版已保存"})
}
// notifyTemplateVars 告警通知模版变量 // Logan.Li
func notifyTemplateVars(ruleName, hostname, metric, severity, message string, value, threshold float64, platform string) map[string]string {
sevLabel := "严重告警"
switch severity {
case "warning":
sevLabel = "警告"
case "info":
sevLabel = "信息"
}
if platform == "" {
platform = defaultNotifyPlatformName
}
return map[string]string{
"time": time.Now().Format("2006-01-02 15:04:05"),
"platform": platform,
"rule_name": ruleName,
"hostname": hostname,
"metric": metric,
"severity": severity,
"severity_label": sevLabel,
"message": message,
"value": fmt.Sprintf("%.2f", value),
"threshold": fmt.Sprintf("%.2f", threshold),
}
}
// renderNotifyTemplate 简单变量替换 {{key}} // Logan.Li
func renderNotifyTemplate(tpl string, vars map[string]string) string {
out := tpl
for k, v := range vars {
out = strings.ReplaceAll(out, "{{"+k+"}}", v)
}
return out
}
// buildNotifyTitle 按全局模版生成通知标题 // Logan.Li
func buildNotifyTitle(db *gorm.DB, ruleName, hostname, metric, severity string) string {
s := ensureNotifySettings(db)
tpl := s.TitleTemplate
if tpl == "" {
tpl = defaultNotifyTitleTemplate
}
return renderNotifyTemplate(tpl, notifyTemplateVars(ruleName, hostname, metric, severity, "", 0, 0, s.PlatformName))
}
// buildNotifyFooter 按全局模版生成卡片底部 // Logan.Li
func buildNotifyFooter(db *gorm.DB) string {
s := ensureNotifySettings(db)
tpl := s.FooterTemplate
if tpl == "" {
tpl = defaultNotifyFooterTemplate
}
vars := map[string]string{
"time": time.Now().Format("2006-01-02 15:04:05"),
"platform": s.PlatformName,
}
if vars["platform"] == "" {
vars["platform"] = defaultNotifyPlatformName
}
return renderNotifyTemplate(tpl, vars)
}
// buildAlertContent 生成告警正文(字段列表,供飞书卡片解析) // Logan.Li
func buildAlertContent(ruleName, hostname, metric, severity, message string, value, threshold float64) string {
return fmt.Sprintf(
"**规则名称:** %s\\n**目标主机:** %s\\n**指标类型:** %s\\n**告警级别:** %s\\n**当前值:** %.2f\\n**阈值:** %.2f\\n**详细信息:** %s\\n**触发时间:** %s",
ruleName, hostname, metric, severity, value, threshold, message, time.Now().Format("2006-01-02 15:04:05"),
)
}