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>
This commit is contained in:
LoganandClaude committed 2026-07-01 23:44:45 +08:00
1 parent 092d0e4b9e
commit 471353e3d7
190 files changed
+16640 -3484

No files matched your search

+59 -13
View File
@@ -7,6 +7,8 @@ import (
"ezops/model"
"ezops/service"
ezredis "ezops/pkg/redis"
"ezops/pkg/siteprobe"
"ezops/pkg/systask"
"ezops/pkg/toolinstaller"
"ezops/pkg/wshub"
"fmt"
@@ -189,6 +191,7 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
admin.POST("/users", authHandler.CreateUser)
admin.PUT("/users/:id", authHandler.UpdateUser)
admin.DELETE("/users/:id", authHandler.DeleteUser)
admin.POST("/users/batch-delete", authHandler.BatchDeleteUsers) // Logan.Li
admin.POST("/users/:id/reset-password", authHandler.ResetUserPassword)
admin.POST("/users/batch-import", authHandler.BatchImportUsers)
admin.GET("/users/import-template", authHandler.ImportTemplate)
@@ -211,6 +214,11 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
admin.GET("/users/:id/item-roles", itemRoleHandler.ListUserItemRoles)
admin.POST("/users/:id/item-roles", itemRoleHandler.AssignItemRole)
admin.DELETE("/users/:id/item-roles/:roleId", itemRoleHandler.RemoveItemRole)
// 审计策略(保留天数 + 立即清理) // Logan.Li
auditSettingsHandler := controller.NewAuditSettingsHandler(db)
admin.GET("/audit-settings", auditSettingsHandler.GetAuditSettings)
admin.PUT("/audit-settings", auditSettingsHandler.ApplyAuditSettings)
}
// LDAP 配置路由
@@ -566,12 +574,28 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
alerts.POST("/contact-groups", alertGroupV2.CreateGroup)
alerts.PUT("/contact-groups/:id", alertGroupV2.UpdateGroup)
alerts.DELETE("/contact-groups/:id", alertGroupV2.DeleteGroup)
// 告警集合通知策略 // Logan.Li
alerts.GET("/notify-policies", alertHandler.ListNotifyPolicies)
alerts.PUT("/notify-policies/:category", alertHandler.UpsertNotifyPolicy)
alerts.POST("/notify-policies/:category/test", alertHandler.TestNotifyPolicy)
alerts.GET("/notify-message-settings", alertHandler.GetNotifyMessageSettings)
alerts.PUT("/notify-message-settings", alertHandler.SaveNotifyMessageSettings)
// 告警静默规则
alerts.GET("/silences", alertHandler.ListSilences)
alerts.POST("/silences", alertHandler.CreateSilence)
alerts.PUT("/silences/:id", alertHandler.UpdateSilence)
alerts.DELETE("/silences/:id", alertHandler.DeleteSilence)
alerts.POST("/silences/:id/toggle", alertHandler.ToggleSilence)
// 监控指标目录 + 统一告警 + 中间件/站点规则 // Logan.Li
alerts.GET("/metric-catalog", alertHandler.GetMetricCatalog)
alerts.GET("/unified", alertHandler.ListUnifiedAlerts)
alerts.GET("/unified-rules", alertHandler.ListUnifiedAlertRules)
alerts.GET("/monitor-rules", alertHandler.ListMonitorAlertRules)
alerts.POST("/monitor-rules", alertHandler.CreateMonitorAlertRule)
alerts.PUT("/monitor-rules/:id", alertHandler.UpdateMonitorAlertRule)
alerts.DELETE("/monitor-rules/:id", alertHandler.DeleteMonitorAlertRule)
alerts.POST("/monitor-quick-setup", alertHandler.QuickSetupMonitorRules)
alerts.POST("/unified/:source/:id/resolve", alertHandler.ResolveUnifiedAlert)
// 告警引擎状态 — 查看当前 Leader 副本和分布式锁状态
alerts.GET("/engine/status", func(c *gin.Context) {
c.JSON(200, model.Response{Code: 200, Data: alertEngine.GetEngineStatus()})
@@ -672,27 +696,37 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
// 自动化运维路由
automationHandler := controller.NewAutomationHandler(db)
autoWrite := middleware.AutomationWrite(db)
cronJobs := authorized.Group("/cron-jobs")
{
cronJobs.GET("", automationHandler.ListCronJobs)
cronJobs.POST("", automationHandler.CreateCronJob)
cronJobs.POST("", autoWrite, automationHandler.CreateCronJob)
cronJobs.GET("/:id", automationHandler.GetCronJob)
cronJobs.PUT("/:id", automationHandler.UpdateCronJob)
cronJobs.DELETE("/batch-delete", automationHandler.BatchDeleteCronJobs)
cronJobs.DELETE("/:id", automationHandler.DeleteCronJob)
cronJobs.POST("/:id/toggle", automationHandler.ToggleCronJob)
cronJobs.POST("/:id/execute", automationHandler.ExecuteCronJob)
cronJobs.PUT("/:id", autoWrite, automationHandler.UpdateCronJob)
cronJobs.DELETE("/batch-delete", autoWrite, automationHandler.BatchDeleteCronJobs)
cronJobs.DELETE("/:id", autoWrite, automationHandler.DeleteCronJob)
cronJobs.POST("/:id/toggle", autoWrite, automationHandler.ToggleCronJob)
cronJobs.POST("/:id/execute", autoWrite, automationHandler.ExecuteCronJob)
}
// 内置系统任务(告警引擎 / 数据清理等) // Logan.Li
sysTaskHandler := controller.NewSystemTaskHandler(db, cfg.Database.Driver, alertEngine)
sysTasks := authorized.Group("/system-tasks")
{
sysTasks.GET("", sysTaskHandler.ListSystemTasks)
sysTasks.POST("/:code/run", autoWrite, sysTaskHandler.RunSystemTask)
}
scripts := authorized.Group("/scripts")
{
scripts.GET("/runtime", automationHandler.GetScriptRuntime)
scripts.GET("", automationHandler.ListScripts)
scripts.POST("", automationHandler.CreateScript)
scripts.POST("", autoWrite, automationHandler.CreateScript)
scripts.GET("/:id", automationHandler.GetScript)
scripts.PUT("/:id", automationHandler.UpdateScript)
scripts.POST("/batch-delete", automationHandler.BatchDeleteScripts)
scripts.DELETE("/:id", automationHandler.DeleteScript)
scripts.POST("/:id/execute", automationHandler.ExecuteScript)
scripts.POST("/batch-delete", autoWrite, automationHandler.BatchDeleteScripts)
scripts.DELETE("/:id", autoWrite, automationHandler.DeleteScript)
scripts.PUT("/:id", autoWrite, automationHandler.UpdateScript)
scripts.POST("/:id/execute", autoWrite, automationHandler.ExecuteScript)
}
// 远程执行路由 — Go 原生 SSH 批量执行替代 Ansible // Logan.Li
@@ -917,6 +951,7 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
mwGroup := authorized.Group("/middleware-monitors")
{
mwGroup.GET("", mwHandler.ListMiddlewareTargets)
mwGroup.POST("/seed-defaults", mwHandler.SeedDefaultMiddlewareTargetsAPI)
mwGroup.POST("", mwHandler.CreateMiddlewareTarget)
mwGroup.GET("/:id", mwHandler.GetMiddlewareTarget)
mwGroup.PUT("/:id", mwHandler.UpdateMiddlewareTarget)
@@ -939,7 +974,13 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
snmpGroup.GET("/templates", snmpHandler.ListTemplates)
snmpGroup.POST("/templates", snmpHandler.CreateTemplate)
snmpGroup.GET("/stats", snmpHandler.GetSNMPStats)
snmpGroup.POST("/devices/:id/collect", snmpHandler.CollectDeviceNow)
snmpGroup.GET("/devices/:id/metrics", snmpHandler.ListDeviceMetrics)
snmpGroup.GET("/devices/:id/metrics/series", snmpHandler.ListMetricSeries)
snmpGroup.GET("/devices/:id/metrics/history", snmpHandler.QueryMetricHistory)
snmpGroup.GET("/overview/metrics", snmpHandler.GetOverviewMetrics)
}
snmpHandler.StartCollector(300) // 每 5 分钟采集 SNMP 设备,指标保留 7 天 // Logan.Li
// Zabbix 代理 — 镜像 Zabbix API 为前端面板可用格式 // Logan.Li
zabbixHandler := controller.NewZabbixProxyHandler()
@@ -1032,7 +1073,8 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
authorized.POST("/servers/:id/assign-credential", credentialHandler.AssignCredential)
// 站点拨测 — HTTP/TCP/DNS/PING 主动监控 // Logan.Li
siteHandler := controller.NewSiteHandler(db)
siteProbeWorker := siteprobe.NewWorker(db)
siteHandler := controller.NewSiteHandler(db, siteProbeWorker)
siteGroup := authorized.Group("/site")
{
siteGroup.GET("/tasks", siteHandler.ListTasks)
@@ -1040,16 +1082,20 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
siteGroup.PUT("/tasks/:id", siteHandler.UpdateTask)
siteGroup.DELETE("/tasks/:id", siteHandler.DeleteTask)
siteGroup.DELETE("/tasks/batch-delete", siteHandler.BatchDeleteTasks)
siteGroup.POST("/tasks/:id/probe", siteHandler.ProbeNow)
siteGroup.GET("/results", siteHandler.ListResults)
siteGroup.GET("/stats", siteHandler.GetSiteStats)
}
siteProbeWorker.Start(10)
// 启动告警引擎(每 30 秒检查一次;alertEngine 在告警路由上方创建)
// 启动告警引擎(每 30 秒检查一次;alertEngine 在告警路由上方创建) // Logan.Li
go func() {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
for range ticker.C {
start := time.Now()
alertEngine.Check()
systask.Record("alert_engine", "success", "", time.Since(start))
}
}()
}