diff --git a/model/channel_monitor.go b/model/channel_monitor.go new file mode 100644 index 00000000..d0b20fd7 --- /dev/null +++ b/model/channel_monitor.go @@ -0,0 +1,66 @@ +package model + +import "time" + +type ChannelMonitor struct { + Id int `json:"id" gorm:"primaryKey;autoIncrement"` + Name string `json:"name" gorm:"size:128;not null"` + ChannelId int `json:"channel_id" gorm:"index;default:0"` + TargetUrl string `json:"target_url" gorm:"size:512;not null"` + PrimaryModel string `json:"primary_model" gorm:"size:128;not null"` + ExtraModels string `json:"extra_models" gorm:"type:text"` + CheckInterval int `json:"check_interval" gorm:"not null;default:300"` + Timeout int `json:"timeout" gorm:"not null;default:30"` + RequestTemplates string `json:"request_templates" gorm:"type:text"` + CustomHeaders string `json:"custom_headers" gorm:"type:text"` + CustomBody string `json:"custom_body" gorm:"type:text"` + Status int `json:"status" gorm:"not null;default:1;index"` + LastCheckedAt *time.Time `json:"last_checked_at"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +func (ChannelMonitor) TableName() string { + return "channel_monitors" +} + +func (m *ChannelMonitor) Insert() error { + return DB.Create(m).Error +} + +func (m *ChannelMonitor) Update() error { + return DB.Save(m).Error +} + +func GetChannelMonitorByID(id int) (*ChannelMonitor, error) { + var monitor ChannelMonitor + err := DB.First(&monitor, "id = ?", id).Error + return &monitor, err +} + +func GetEnabledChannelMonitors() ([]ChannelMonitor, error) { + var monitors []ChannelMonitor + err := DB.Where("status = ?", 1).Order("id DESC").Find(&monitors).Error + return monitors, err +} + +func GetChannelMonitors(page int, pageSize int) ([]ChannelMonitor, int64, error) { + var monitors []ChannelMonitor + var total int64 + query := DB.Model(&ChannelMonitor{}) + if err := query.Count(&total).Error; err != nil { + return nil, 0, err + } + if page < 1 { + page = 1 + } + if pageSize < 1 { + pageSize = 20 + } + err := query.Order("id DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&monitors).Error + return monitors, total, err +} + +func DeleteChannelMonitorByID(id int) error { + return DB.Delete(&ChannelMonitor{}, id).Error +} diff --git a/model/channel_monitor_daily_rollup.go b/model/channel_monitor_daily_rollup.go new file mode 100644 index 00000000..bb2a2b6d --- /dev/null +++ b/model/channel_monitor_daily_rollup.go @@ -0,0 +1,41 @@ +package model + +type ChannelMonitorDailyRollup struct { + Id int `json:"id" gorm:"primaryKey;autoIncrement"` + MonitorId int `json:"monitor_id" gorm:"not null;index;uniqueIndex:idx_channel_monitor_daily_rollup,priority:1"` + ChannelId int `json:"channel_id" gorm:"index;uniqueIndex:idx_channel_monitor_daily_rollup,priority:2"` + ModelName string `json:"model_name" gorm:"size:128;not null;uniqueIndex:idx_channel_monitor_daily_rollup,priority:3"` + Date string `json:"date" gorm:"size:10;not null;uniqueIndex:idx_channel_monitor_daily_rollup,priority:4"` + TotalChecks int `json:"total_checks" gorm:"not null;default:0"` + PassCount int `json:"pass_count" gorm:"not null;default:0"` + DegradedCount int `json:"degraded_count" gorm:"not null;default:0"` + FailedCount int `json:"failed_count" gorm:"not null;default:0"` + AvgLatencyMs int `json:"avg_latency_ms" gorm:"not null;default:0"` +} + +func (ChannelMonitorDailyRollup) TableName() string { + return "channel_monitor_daily_rollups" +} + +func GetChannelMonitorDailyRollups(monitorId int, modelName string, startDate string, endDate string) ([]ChannelMonitorDailyRollup, error) { + var rollups []ChannelMonitorDailyRollup + query := DB.Model(&ChannelMonitorDailyRollup{}) + if monitorId > 0 { + query = query.Where("monitor_id = ?", monitorId) + } + if modelName != "" { + query = query.Where("model_name = ?", modelName) + } + if startDate != "" { + query = query.Where("date >= ?", startDate) + } + if endDate != "" { + query = query.Where("date <= ?", endDate) + } + err := query.Order("date DESC").Find(&rollups).Error + return rollups, err +} + +func GetMonitorDailyRollups(monitorId int, modelName string, startDate string, endDate string) ([]ChannelMonitorDailyRollup, error) { + return GetChannelMonitorDailyRollups(monitorId, modelName, startDate, endDate) +} diff --git a/model/channel_monitor_history.go b/model/channel_monitor_history.go new file mode 100644 index 00000000..01a993bd --- /dev/null +++ b/model/channel_monitor_history.go @@ -0,0 +1,61 @@ +package model + +import "time" + +type ChannelMonitorHistory struct { + Id int `json:"id" gorm:"primaryKey;autoIncrement"` + MonitorId int `json:"monitor_id" gorm:"index;not null"` + ChannelId int `json:"channel_id" gorm:"index"` + ModelName string `json:"model_name" gorm:"size:128;not null;index"` + Status string `json:"status" gorm:"size:16;not null;index"` + StatusCode int `json:"status_code"` + LatencyMs int `json:"latency_ms"` + ErrorMessage string `json:"error_message" gorm:"type:text"` + RequestBody string `json:"request_body" gorm:"type:text"` + ResponseSnippet string `json:"response_snippet" gorm:"type:text"` + CheckedAt time.Time `json:"checked_at" gorm:"index;not null"` +} + +func (ChannelMonitorHistory) TableName() string { + return "channel_monitor_histories" +} + +func (h *ChannelMonitorHistory) Insert() error { + return DB.Create(h).Error +} + +func GetChannelMonitorHistories(monitorId int, page int, pageSize int, modelName string, status string, startTime *time.Time, endTime *time.Time) ([]ChannelMonitorHistory, int64, error) { + var histories []ChannelMonitorHistory + var total int64 + query := DB.Model(&ChannelMonitorHistory{}) + if monitorId > 0 { + query = query.Where("monitor_id = ?", monitorId) + } + if modelName != "" { + query = query.Where("model_name = ?", modelName) + } + if status != "" { + query = query.Where("status = ?", status) + } + if startTime != nil { + query = query.Where("checked_at >= ?", *startTime) + } + if endTime != nil { + query = query.Where("checked_at <= ?", *endTime) + } + if err := query.Count(&total).Error; err != nil { + return nil, 0, err + } + if page < 1 { + page = 1 + } + if pageSize < 1 { + pageSize = 20 + } + err := query.Order("id DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&histories).Error + return histories, total, err +} + +func GetMonitorHistory(monitorId int, page int, pageSize int, modelName string, status string, startTime *time.Time, endTime *time.Time) ([]ChannelMonitorHistory, int64, error) { + return GetChannelMonitorHistories(monitorId, page, pageSize, modelName, status, startTime, endTime) +} diff --git a/model/main.go b/model/main.go index 2e554302..c286d64f 100644 --- a/model/main.go +++ b/model/main.go @@ -285,6 +285,9 @@ func migrateDB() error { &PromoCodeUsage{}, &Announcement{}, &AnnouncementRead{}, + &ChannelMonitor{}, + &ChannelMonitorHistory{}, + &ChannelMonitorDailyRollup{}, ) if err != nil { return err @@ -338,6 +341,9 @@ func migrateDBFast() error { {&PromoCodeUsage{}, "PromoCodeUsage"}, {&Announcement{}, "Announcement"}, {&AnnouncementRead{}, "AnnouncementRead"}, + {&ChannelMonitor{}, "ChannelMonitor"}, + {&ChannelMonitorHistory{}, "ChannelMonitorHistory"}, + {&ChannelMonitorDailyRollup{}, "ChannelMonitorDailyRollup"}, } // 动态计算migration数量,确保errChan缓冲区足够大 errChan := make(chan error, len(migrations))