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 && (
- {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小时在线率(百分比)