fix
This commit is contained in:
29
internal/models/alert_outbox.go
Normal file
29
internal/models/alert_outbox.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// AlertOutbox 表示待发送或重试中的告警任务。
|
||||
type AlertOutbox struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// LogEventID 关联日志事件 ID。
|
||||
LogEventID uint `gorm:"index" json:"log_event_id"`
|
||||
// PayloadJSON 保存 AlertReceiveBody 的 JSON 文本。
|
||||
PayloadJSON string `gorm:"type:text" json:"payload_json"`
|
||||
// Status 任务状态:pending/retrying/sent/dead。
|
||||
Status string `gorm:"size:32;index" json:"status"`
|
||||
// RetryCount 已重试次数。
|
||||
RetryCount int `json:"retry_count"`
|
||||
// NextRetryAt 下一次可重试时间。
|
||||
NextRetryAt time.Time `gorm:"index" json:"next_retry_at"`
|
||||
// LastError 最近一次错误信息。
|
||||
LastError string `gorm:"type:text" json:"last_error"`
|
||||
}
|
||||
|
||||
func (AlertOutbox) TableName() string {
|
||||
return "logs_alert_outbox"
|
||||
}
|
||||
|
||||
@@ -20,6 +20,18 @@ type LogEvent struct {
|
||||
NormalizedDetail string `gorm:"type:text" json:"normalized_detail"`
|
||||
// DeviceName 表示关联设备名称。
|
||||
DeviceName string `gorm:"size:512;index" json:"device_name"`
|
||||
// SourceIP 表示原始来源 IP(不含端口)。
|
||||
SourceIP string `gorm:"size:64;index" json:"source_ip"`
|
||||
// ResourceType 表示关联到的资源类型。
|
||||
ResourceType string `gorm:"size:32;index" json:"resource_type"`
|
||||
// ResourceID 表示关联到的资源 ID。
|
||||
ResourceID string `gorm:"size:128;index" json:"resource_id"`
|
||||
// ResourceName 表示关联到的资源名称。
|
||||
ResourceName string `gorm:"size:256" json:"resource_name"`
|
||||
// MatchMethod 表示资源命中方式(ip/hostname/none)。
|
||||
MatchMethod string `gorm:"size:32" json:"match_method"`
|
||||
// DispatchStatus 表示告警分发状态(not_applicable/pending/retrying/sent/dead)。
|
||||
DispatchStatus string `gorm:"size:32;index" json:"dispatch_status"`
|
||||
// SeverityCode 表示告警/严重度编码。
|
||||
SeverityCode string `gorm:"size:32" json:"severity_code"`
|
||||
// TrapOID 表示关联的 Trap OID(若来源为 trap)。
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package models
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
// GetAllModels 数据库迁移用模型列表
|
||||
func GetAllModels() []interface{} {
|
||||
return []interface{}{
|
||||
&LogEvent{},
|
||||
&AlertOutbox{},
|
||||
&ResourceMapping{},
|
||||
&ResourceEventDedup{},
|
||||
&TrapDictionaryEntry{},
|
||||
&SyslogRule{},
|
||||
&TrapRule{},
|
||||
@@ -11,7 +16,104 @@ func GetAllModels() []interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
// InitData 预留默认数据
|
||||
func InitData() error {
|
||||
// InitData 初始化默认规则数据(幂等)
|
||||
func InitData(db *gorm.DB) error {
|
||||
if db == nil {
|
||||
return nil
|
||||
}
|
||||
if err := seedDefaultSyslogRules(db); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := seedDefaultTrapRules(db); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := seedDefaultTrapDictionary(db); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func seedDefaultSyslogRules(db *gorm.DB) error {
|
||||
var cnt int64
|
||||
if err := db.Model(&SyslogRule{}).Count(&cnt).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if cnt > 0 {
|
||||
return nil
|
||||
}
|
||||
rows := []SyslogRule{
|
||||
{
|
||||
Name: "默认-系统严重错误",
|
||||
Enabled: true,
|
||||
Priority: 100,
|
||||
DeviceNameContains: "",
|
||||
KeywordRegex: "(?i)(panic|fatal|segmentation fault|kernel panic|out of memory|oom)",
|
||||
AlertName: "Syslog严重错误",
|
||||
SeverityCode: "critical",
|
||||
PolicyID: 0,
|
||||
},
|
||||
{
|
||||
Name: "默认-链路中断告警",
|
||||
Enabled: true,
|
||||
Priority: 90,
|
||||
DeviceNameContains: "",
|
||||
KeywordRegex: "(?i)(link down|interface .* down|port .* down)",
|
||||
AlertName: "Syslog链路中断",
|
||||
SeverityCode: "major",
|
||||
PolicyID: 0,
|
||||
},
|
||||
}
|
||||
return db.Create(&rows).Error
|
||||
}
|
||||
|
||||
func seedDefaultTrapRules(db *gorm.DB) error {
|
||||
var cnt int64
|
||||
if err := db.Model(&TrapRule{}).Count(&cnt).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if cnt > 0 {
|
||||
return nil
|
||||
}
|
||||
rows := []TrapRule{
|
||||
{
|
||||
Name: "默认-Trap链路中断",
|
||||
Enabled: true,
|
||||
Priority: 100,
|
||||
OIDPrefix: "1.3.6.1.6.3.1.1.5",
|
||||
VarbindMatchRegex: "(?i)(linkdown|ifdown|down)",
|
||||
AlertName: "SNMP Trap链路中断",
|
||||
SeverityCode: "major",
|
||||
PolicyID: 0,
|
||||
},
|
||||
}
|
||||
return db.Create(&rows).Error
|
||||
}
|
||||
|
||||
func seedDefaultTrapDictionary(db *gorm.DB) error {
|
||||
var cnt int64
|
||||
if err := db.Model(&TrapDictionaryEntry{}).Count(&cnt).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if cnt > 0 {
|
||||
return nil
|
||||
}
|
||||
rows := []TrapDictionaryEntry{
|
||||
{
|
||||
OIDPrefix: "1.3.6.1.6.3.1.1.5.3",
|
||||
Title: "ifDown 接口中断",
|
||||
Description: "检测到设备接口状态变为 down。",
|
||||
SeverityCode: "major",
|
||||
RecoveryMessage: "请检查链路、端口状态和对端设备。",
|
||||
Enabled: true,
|
||||
},
|
||||
{
|
||||
OIDPrefix: "1.3.6.1.6.3.1.1.5.4",
|
||||
Title: "ifUp 接口恢复",
|
||||
Description: "检测到设备接口状态恢复为 up。",
|
||||
SeverityCode: "info",
|
||||
RecoveryMessage: "接口已恢复,请确认业务连通性。",
|
||||
Enabled: true,
|
||||
},
|
||||
}
|
||||
return db.Create(&rows).Error
|
||||
}
|
||||
|
||||
24
internal/models/resource_event_dedup.go
Normal file
24
internal/models/resource_event_dedup.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// ResourceEventDedup 用于资源事件幂等去重。
|
||||
type ResourceEventDedup struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// EventID 为外部事件唯一标识。
|
||||
EventID string `gorm:"size:128;uniqueIndex" json:"event_id"`
|
||||
// EventTime 记录事件时间,便于排查重放问题。
|
||||
EventTime time.Time `json:"event_time"`
|
||||
// ResourceType/ResourceID 便于定位被操作资源。
|
||||
ResourceType string `gorm:"size:32;index" json:"resource_type"`
|
||||
ResourceID string `gorm:"size:128;index" json:"resource_id"`
|
||||
}
|
||||
|
||||
func (ResourceEventDedup) TableName() string {
|
||||
return "logs_resource_event_dedup"
|
||||
}
|
||||
|
||||
37
internal/models/resource_mapping.go
Normal file
37
internal/models/resource_mapping.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// ResourceMapping 表示来自 dc-control 的资源映射快照。
|
||||
type ResourceMapping struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
// CreatedAt/UpdatedAt 由 GORM 维护。
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// ResourceType 资源类型(server/collector/device)。
|
||||
ResourceType string `gorm:"size:32;index:idx_logs_resource_unique,unique" json:"resource_type"`
|
||||
// ResourceID 资源 ID(来自 dc-control)。
|
||||
ResourceID string `gorm:"size:128;index:idx_logs_resource_unique,unique" json:"resource_id"`
|
||||
// ResourceName 资源名称。
|
||||
ResourceName string `gorm:"size:256" json:"resource_name"`
|
||||
|
||||
// IPsJSON/HostnamesJSON/LabelsJSON 以 JSON 文本存储数组和标签。
|
||||
IPsJSON string `gorm:"type:text" json:"ips_json"`
|
||||
HostnamesJSON string `gorm:"type:text" json:"hostnames_json"`
|
||||
LabelsJSON string `gorm:"type:text" json:"labels_json"`
|
||||
|
||||
// Version 用于处理乱序事件,仅允许新版本覆盖。
|
||||
Version int64 `gorm:"index" json:"version"`
|
||||
// IsDeleted 表示逻辑删除。
|
||||
IsDeleted bool `gorm:"index" json:"is_deleted"`
|
||||
// LastEventID 记录最后一次成功应用的事件 ID(幂等辅助)。
|
||||
LastEventID string `gorm:"size:128" json:"last_event_id"`
|
||||
// EventTime 记录事件产生时间。
|
||||
EventTime time.Time `json:"event_time"`
|
||||
}
|
||||
|
||||
func (ResourceMapping) TableName() string {
|
||||
return "logs_resource_mappings"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user