feat: add channel monitor data models

Add monitor configuration, history, and daily rollup models for the operations channel monitoring module.
This commit is contained in:
zizi 2026-05-20 13:21:11 +08:00
parent eec9f4dcae
commit 5154ca2e4d
4 changed files with 174 additions and 0 deletions

66
model/channel_monitor.go Normal file
View File

@ -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
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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))