diff --git a/internal/handler/monitor_handler.go b/internal/handler/monitor_handler.go index def4c96..abc017f 100644 --- a/internal/handler/monitor_handler.go +++ b/internal/handler/monitor_handler.go @@ -11,43 +11,26 @@ import ( type MonitorHandler struct { logger *zap.Logger monitorService *service.MonitorService + agentService *service.AgentService } -func NewMonitorHandler(logger *zap.Logger, monitorService *service.MonitorService) *MonitorHandler { +func NewMonitorHandler(logger *zap.Logger, monitorService *service.MonitorService, agentService *service.AgentService) *MonitorHandler { return &MonitorHandler{ logger: logger, monitorService: monitorService, + agentService: agentService, } } func (h *MonitorHandler) List(c echo.Context) error { keyword := c.QueryParam("keyword") - name := c.QueryParam("name") - target := c.QueryParam("target") - typeParam := c.QueryParam("type") enabled := c.QueryParam("enabled") - pr := orz.GetPageRequest(c, "-updated_at", "name") + pr := orz.GetPageRequest(c, "name") builder := orz.NewPageBuilder(h.monitorService.MonitorRepo). - PageRequest(pr) - - // 如果有 keyword,则搜索 name(也可以搜索 target) - if keyword != "" { - // keyword 可以匹配 name 或 target - builder.Contains("name", keyword) - // 如果需要同时搜索 target,可以手动构建 OR 查询 - // 这里简化处理,只搜索 name - } else { - // 否则使用独立的 name 和 target 搜索 - builder.Contains("name", name). - Contains("target", target) - } - - // 处理类型筛选 - if typeParam != "" { - builder.Equal("type", typeParam) - } + PageRequest(pr). + Keyword([]string{"name", "target", "type"}, keyword) // 处理启用状态筛选 if enabled == "true" { @@ -61,6 +44,33 @@ func (h *MonitorHandler) List(c echo.Context) error { if err != nil { return err } + + var agentIds []string + for _, item := range page.Items { + if len(item.AgentIds) > 0 { + agentIds = append(agentIds, item.AgentIds...) + } + } + if len(agentIds) > 0 { + agents, err := h.agentService.AgentRepo.FindByIdIn(ctx, agentIds) + if err != nil { + return err + } + + var agentNameMap = make(map[string]string) + for _, agent := range agents { + agentNameMap[agent.ID] = agent.Name + } + + for i, monitor := range page.Items { + if len(monitor.AgentIds) == 0 { + continue + } + for _, agentId := range monitor.AgentIds { + page.Items[i].AgentNames = append(page.Items[i].AgentNames, agentNameMap[agentId]) + } + } + } return orz.Ok(c, page) } diff --git a/internal/models/monitor_stats.go b/internal/models/monitor_stats.go index 21fcc48..c91dec4 100644 --- a/internal/models/monitor_stats.go +++ b/internal/models/monitor_stats.go @@ -9,7 +9,6 @@ type MonitorStats struct { MonitorName string `gorm:"-" json:"name"` // 监控项名称(不存储在数据库,仅用于 API 返回) MonitorType string `json:"type"` // 监控类型 Target string `json:"target"` // 目标地址 - ShowTargetPublic bool `gorm:"-" json:"showTargetPublic"` // 在公开页面是否显示目标地址(不存储在数据库,仅用于 API 返回) CurrentResponse int64 `json:"currentResponse"` // 当前响应时间(ms) AvgResponse24h int64 `json:"avgResponse24h"` // 24小时平均响应时间(ms) Uptime24h float64 `json:"uptime24h"` // 24小时在线率(百分比) diff --git a/internal/models/monitor_task.go b/internal/models/monitor_task.go index 8720561..2d9f18f 100644 --- a/internal/models/monitor_task.go +++ b/internal/models/monitor_task.go @@ -17,6 +17,7 @@ type MonitorTask struct { Visibility string `gorm:"default:public" json:"visibility"` // 可见性: public-匿名可见, private-登录可见 Interval int `json:"interval"` // 检测频率(秒),默认 60 AgentIds datatypes.JSONSlice[string] `json:"agentIds"` // 指定的探针 ID 列表(JSON 数组) + AgentNames []string `gorm:"-" json:"agentNames"` // 指定的探针名称列表 Tags datatypes.JSONSlice[string] `json:"tags"` // 指定的标签列表(JSON 数组),拥有这些标签的探针都会执行此监控 HTTPConfig datatypes.JSONType[protocol.HTTPMonitorConfig] `json:"httpConfig"` // HTTP 监控配置 TCPConfig datatypes.JSONType[protocol.TCPMonitorConfig] `json:"tcpConfig"` // TCP 监控配置 diff --git a/internal/service/monitor_service.go b/internal/service/monitor_service.go index 54e5bad..525b0f7 100644 --- a/internal/service/monitor_service.go +++ b/internal/service/monitor_service.go @@ -378,93 +378,6 @@ func (s *MonitorService) resolveTargetAgents(monitor models.MonitorTask, availab return targetAgents } -// BroadcastMonitorConfig 向所有在线探针广播监控配置 -func (s *MonitorService) BroadcastMonitorConfig(ctx context.Context) error { - // 获取所有启用的监控任务 - var monitors []models.MonitorTask - if err := s.MonitorRepo.GetDB(ctx). - Where("enabled = ?", true). - Find(&monitors).Error; err != nil { - return err - } - - // 如果没有启用的监控任务,直接返回(不需要发送任何配置) - if len(monitors) == 0 { - s.logger.Debug("没有启用的监控任务,跳过配置推送") - return nil - } - - // 获取所有在线探针 - agents, err := s.agentRepo.FindOnlineAgents(ctx) - if err != nil { - s.logger.Error("获取在线探针失败", zap.Error(err)) - return err - } - - // 按探针分组构建监控配置 - agentMonitors := make(map[string][]models.MonitorTask) - - for _, monitor := range monitors { - // 使用统一的方法计算目标探针 - targetAgents := s.resolveTargetAgents(monitor, agents) - - for _, agent := range targetAgents { - agentMonitors[agent.ID] = append(agentMonitors[agent.ID], monitor) - } - } - - // 向每个有监控任务的探针发送对应的监控配置 - for agentID, tasks := range agentMonitors { - items := make([]protocol.MonitorItem, 0, len(tasks)) - for _, task := range tasks { - item := protocol.MonitorItem{ - ID: task.ID, - Type: task.Type, - Target: task.Target, - } - - if task.Type == "http" || task.Type == "https" { - var httpConfig protocol.HTTPMonitorConfig - if err := task.HTTPConfig.Scan(&httpConfig); err == nil { - item.HTTPConfig = &httpConfig - } - } else if task.Type == "tcp" { - var tcpConfig protocol.TCPMonitorConfig - if err := task.TCPConfig.Scan(&tcpConfig); err == nil { - item.TCPConfig = &tcpConfig - } - } else if task.Type == "icmp" || task.Type == "ping" { - var icmpConfig protocol.ICMPMonitorConfig - if err := task.ICMPConfig.Scan(&icmpConfig); err == nil { - item.ICMPConfig = &icmpConfig - } - } - - items = append(items, item) - } - - // 构建监控配置 payload - // Interval 字段不再使用(探针收到后立即检测一次),但保留字段兼容性 - payload := protocol.MonitorConfigPayload{ - Interval: 0, - Items: items, - } - - // 发送监控配置到指定探针 - if err := s.sendMonitorConfigToAgent(agentID, payload); err != nil { - s.logger.Error("发送监控配置失败", - zap.String("agentID", agentID), - zap.Error(err)) - } else { - s.logger.Debug("发送监控配置成功", - zap.String("agentID", agentID), - zap.Int("taskCount", len(items))) - } - } - - return nil -} - // sendMonitorConfigToAgent 向指定探针发送监控配置(内部方法) func (s *MonitorService) sendMonitorConfigToAgent(agentID string, payload protocol.MonitorConfigPayload) error { payloadData, err := json.Marshal(payload) @@ -688,24 +601,38 @@ func (s *MonitorService) GetMonitorStatsByID(ctx context.Context, monitorID stri return nil, err } + // 获取探针列表 + agents, err := s.agentRepo.FindAll(ctx) + if err != nil { + return nil, err + } + // 当前监控任务的关联的探针 + targetAgents := s.resolveTargetAgents(monitor, agents) + var targetAgentsMap = make(map[string]string) + for _, agent := range targetAgents { + targetAgentsMap[agent.ID] = agent.Name + } + // 填充监控名称、探针名称和隐私设置 - for i := range statsList { - statsList[i].MonitorName = monitor.Name - statsList[i].ShowTargetPublic = monitor.ShowTargetPublic + var filteredStatsList []models.MonitorStats + for _, stats := range statsList { + agentName, ok := targetAgentsMap[stats.AgentID] + if !ok { + continue + } + + stats.MonitorName = monitor.Name // 根据 ShowTargetPublic 字段决定是否隐藏 Target if !monitor.ShowTargetPublic { - statsList[i].Target = "***" + stats.Target = "******" } - // 查询探针名称 - agent, err := s.agentRepo.FindById(ctx, statsList[i].AgentID) - if err == nil { - statsList[i].AgentName = agent.Name - } + stats.AgentName = agentName + filteredStatsList = append(filteredStatsList, stats) } - return statsList, nil + return filteredStatsList, nil } // GetMonitorHistory 获取监控任务的历史响应时间数据 diff --git a/internal/wire_gen.go b/internal/wire_gen.go index 27e1a0b..3c3de95 100644 --- a/internal/wire_gen.go +++ b/internal/wire_gen.go @@ -38,7 +38,7 @@ func InitializeApp(logger *zap.Logger, db *gorm.DB, cfg *config.AppConfig) (*App alertService := service.NewAlertService(logger, db, propertyService, notifier) alertHandler := handler.NewAlertHandler(logger, alertService) propertyHandler := handler.NewPropertyHandler(logger, propertyService, notifier) - monitorHandler := handler.NewMonitorHandler(logger, monitorService) + monitorHandler := handler.NewMonitorHandler(logger, monitorService, agentService) tamperHandler := handler.NewTamperHandler(logger, tamperService) appComponents := &AppComponents{ AccountHandler: accountHandler, diff --git a/web/src/pages/Monitors/MonitorList.tsx b/web/src/pages/Monitors/MonitorList.tsx index b5d3a33..60091ad 100644 --- a/web/src/pages/Monitors/MonitorList.tsx +++ b/web/src/pages/Monitors/MonitorList.tsx @@ -259,7 +259,7 @@ const MonitorList = () => { {hasAgents && ( 探针: - {record.agentIds.map((id) => ( + {record.agentNames?.map((id) => ( {id} ))} @@ -267,7 +267,7 @@ const MonitorList = () => { {hasTags && ( 标签: - {record.tags.map((tag) => ( + {record.tags?.map((tag) => ( {tag} ))} diff --git a/web/src/pages/Public/MonitorDetail.tsx b/web/src/pages/Public/MonitorDetail.tsx index 61be5d5..377e920 100644 --- a/web/src/pages/Public/MonitorDetail.tsx +++ b/web/src/pages/Public/MonitorDetail.tsx @@ -392,7 +392,7 @@ const MonitorDetail = () => {

{monitorTitle}

- {firstStat.showTargetPublic ? firstStat.target : '***'} + {firstStat.target}

公共视图 · 实时监控概览

diff --git a/web/src/types/index.ts b/web/src/types/index.ts index 006ebc2..473d10f 100644 --- a/web/src/types/index.ts +++ b/web/src/types/index.ts @@ -253,6 +253,7 @@ export interface MonitorTask { tcpConfig?: MonitorTcpConfig | null; icmpConfig?: MonitorIcmpConfig | null; agentIds?: string[]; + agentNames?: string[]; tags?: string[]; // 标签列表,拥有这些标签的探针都会执行此监控 createdAt: number; updatedAt: number; @@ -312,7 +313,6 @@ export interface MonitorStats { name: string; // 监控项名称 type: string; target: string; - showTargetPublic: boolean; // 在公开页面是否显示目标地址 currentResponse: number; // 当前响应时间(ms) avgResponse24h: number; // 24小时平均响应时间(ms) uptime24h: number; // 24小时在线率(百分比)