feat: v0.34 健康探针(Architecture B) + Agent v2.1 + 端口监控 + 告警联系人重构

- v0.31: AlertContact 重构(channel_type下拉+webhook_url替代三分立字段)
- v0.32: Agent ProcessTop 增强(cmdline/user/cpu_pct/mem_pct)
- v0.33: 端口监控 Tab(监听端口自动发现+down联动告警)
- v0.34: 健康探针(Agent本地执行HTTP/TCP/Exec→结果随心跳上报)
- Agent新增: ContextSwitch/FD/HealthProbe采集器
- 后端新增: health_probe handler + Agent model扩展
- HostMonitor新增Tab: 健康探针/端口监控
This commit is contained in:
attacker committed 2026-06-24 19:18:10 +08:00
1 parent e1f75f0bc4
commit d656520428
25 files changed
+1700 -619

No files matched your search

+6 -1
View File
@@ -87,7 +87,8 @@ type AgentReportRequest struct {
ProcessTop []ProcessMetric `json:"process_top,omitempty"`
FD *FDMetric `json:"fd,omitempty"`
ContextSwitches *CSMetric `json:"context_switches,omitempty"`
Heartbeat HeartbeatMetric `json:"heartbeat"`
Heartbeat HeartbeatMetric `json:"heartbeat"`
ProbeResults []HealthProbeResult `json:"probe_results,omitempty"` // v2.1 健康探针结果
}
// ──── v2.0 新增上报类型 ────
@@ -101,6 +102,10 @@ type SwapMetric struct {
type ProcessMetric struct {
PID int `json:"pid"`
Name string `json:"name"`
Cmdline string `json:"cmdline"`
User string `json:"user"`
CPUPct float64 `json:"cpu_pct"`
MemPct float64 `json:"mem_pct"`
MemoryMB float64 `json:"memory_mb"`
FDCount int `json:"fd_count"`
Threads int `json:"threads"`
+19 -22
View File
@@ -400,16 +400,15 @@ type AcknowledgeAlertRequest struct {
// ============================================
type AlertContact struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:联系人姓名" json:"name"`
Phone string `gorm:"type:varchar(32);comment:手机号" json:"phone,omitempty"`
Email string `gorm:"type:varchar(128);comment:邮箱" json:"email,omitempty"`
Dingtalk string `gorm:"type:varchar(256);comment:钉钉webhook地址" json:"dingtalk,omitempty"`
Feishu string `gorm:"type:varchar(256);comment:飞书webhook地址" json:"feishu,omitempty"`
Wechat string `gorm:"type:varchar(256);comment:企业微信webhook地址" json:"wechat,omitempty"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:联系人姓名" json:"name"`
Phone string `gorm:"type:varchar(32);comment:手机号" json:"phone,omitempty"`
Email string `gorm:"type:varchar(128);comment:邮箱" json:"email,omitempty"`
ChannelType string `gorm:"type:varchar(32);default:'feishu';comment:渠道类型: feishu/dingtalk/wechat/webhook" json:"channel_type,omitempty"`
WebhookURL string `gorm:"type:varchar(512);comment:Webhook地址" json:"webhook_url,omitempty"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
}
func (AlertContact) TableName() string {
@@ -436,22 +435,20 @@ func (AlertContactGroup) TableName() string {
// CreateContactRequest 创建联系人请求
type CreateContactRequest struct {
Name string `json:"name" binding:"required"`
Phone string `json:"phone,omitempty"`
Email string `json:"email,omitempty"`
Dingtalk string `json:"dingtalk,omitempty"`
Feishu string `json:"feishu,omitempty"`
Wechat string `json:"wechat,omitempty"`
Name string `json:"name" binding:"required"`
Phone string `json:"phone,omitempty"`
Email string `json:"email,omitempty"`
ChannelType string `json:"channel_type" binding:"required,oneof=feishu dingtalk wechat webhook"`
WebhookURL string `json:"webhook_url" binding:"required"`
}
// UpdateContactRequest 更新联系人请求
type UpdateContactRequest struct {
Name string `json:"name,omitempty"`
Phone string `json:"phone,omitempty"`
Email string `json:"email,omitempty"`
Dingtalk string `json:"dingtalk,omitempty"`
Feishu string `json:"feishu,omitempty"`
Wechat string `json:"wechat,omitempty"`
Name string `json:"name,omitempty"`
Phone string `json:"phone,omitempty"`
Email string `json:"email,omitempty"`
ChannelType string `json:"channel_type,omitempty" binding:"omitempty,oneof=feishu dingtalk wechat webhook"`
WebhookURL string `json:"webhook_url,omitempty"`
}
// CreateContactGroupRequest 创建联系组请求
+70
View File
@@ -353,3 +353,73 @@ type HostGroup struct {
func (HostGroup) TableName() string {
return "asset_host_groups"
}
// ============================================
// HealthProbe 健康探针配置(Agent 本地执行)
// ============================================
// ProbeType 探针类型
type ProbeType string
const (
ProbeTypeHTTP ProbeType = "http_get" // HTTP GET 探测
ProbeTypeTCP ProbeType = "tcp_socket" // TCP 端口连接探测
ProbeTypeExec ProbeType = "exec_command" // 命令执行探测
)
// ProbeStatus 探针结果状态
type ProbeStatus string
const (
ProbeStatusUp ProbeStatus = "up" // 健康
ProbeStatusDown ProbeStatus = "down" // 异常
)
// HealthProbe 健康探针配置表
// 存储在平台 DB,Agent 拉取配置后在目标主机本地执行,结果随心跳上报
type HealthProbe struct {
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
Name string `gorm:"type:varchar(128);not null;index" json:"name"`
Hostname string `gorm:"type:varchar(255);index;not null" json:"hostname"`
ProbeType ProbeType `gorm:"type:varchar(32);not null" json:"probe_type"`
// HTTP 探针配置
HTTPURL string `gorm:"type:varchar(512)" json:"http_url,omitempty"`
HTTPMethod string `gorm:"type:varchar(10);default:GET" json:"http_method,omitempty"`
HTTPHeaders string `gorm:"type:text" json:"http_headers,omitempty"`
HTTPExpectCode int `gorm:"default:200" json:"http_expect_code,omitempty"`
HTTPExpectBody string `gorm:"type:varchar(256)" json:"http_expect_body,omitempty"`
// TCP 探针配置
TCPHost string `gorm:"type:varchar(255)" json:"tcp_host,omitempty"`
TCPPort int `json:"tcp_port,omitempty"`
// Exec 探针配置
ExecCommand string `gorm:"type:text" json:"exec_command,omitempty"`
// 通用配置
Timeout int `gorm:"default:10" json:"timeout"`
Interval int `gorm:"default:60" json:"interval"`
Enabled bool `gorm:"default:true;index" json:"enabled"`
LastStatus ProbeStatus `gorm:"type:varchar(8);default:''" json:"last_status,omitempty"`
LastCheckedAt *time.Time `json:"last_checked_at,omitempty"`
LastLatencyMs int `json:"last_latency_ms"`
FailCount int `json:"fail_count"`
Description string `gorm:"type:varchar(256)" json:"description,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
DeletedAt *time.Time `gorm:"index" json:"deleted_at,omitempty"`
}
// TableName 指定表名
func (HealthProbe) TableName() string {
return "monitor_health_probes"
}
// HealthProbeResult Agent 上报的探针执行结果(作为心跳的一部分)
type HealthProbeResult struct {
ProbeID uint `json:"probe_id"`
Name string `json:"name"`
ProbeType string `json:"probe_type"`
Status ProbeStatus `json:"status"` // up / down
LatencyMs int `json:"latency_ms"` // 响应延迟(ms)
StatusCode int `json:"status_code,omitempty"` // HTTP 状态码
Message string `json:"message,omitempty"` // 错误/附加信息
}