137 lines
4.2 KiB
Go
137 lines
4.2 KiB
Go
package alert
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
|
|
"go-admin/app/bell/event"
|
|
)
|
|
|
|
var ErrNotFound = errors.New("预警不存在")
|
|
|
|
type PageQuery struct {
|
|
PageIndex int `form:"pageIndex"`
|
|
PageSize int `form:"pageSize"`
|
|
Status string `form:"status"`
|
|
Severity string `form:"severity"`
|
|
Location string `form:"location"`
|
|
}
|
|
|
|
type Summary struct {
|
|
Alert
|
|
RuleName string `json:"ruleName"`
|
|
EventCount int64 `json:"eventCount"`
|
|
}
|
|
|
|
type LinkedEvent struct {
|
|
event.Event
|
|
LinkedAt time.Time `json:"linkedAt"`
|
|
}
|
|
|
|
type Detail struct {
|
|
Alert Summary `json:"alert"`
|
|
Events []LinkedEvent `json:"events"`
|
|
Matches []RuleMatch `json:"matches"`
|
|
}
|
|
|
|
type Service struct{ DB *gorm.DB }
|
|
|
|
func NewService(db *gorm.DB) Service { return Service{DB: db} }
|
|
|
|
func (s Service) List(ctx context.Context, query PageQuery) ([]Summary, int64, error) {
|
|
page, size := pageValues(query.PageIndex, query.PageSize)
|
|
base := s.DB.WithContext(ctx).Table("bell_alerts a")
|
|
if query.Status = strings.TrimSpace(query.Status); query.Status != "" {
|
|
base = base.Where("a.status = ?", query.Status)
|
|
}
|
|
if query.Severity = strings.TrimSpace(query.Severity); query.Severity != "" {
|
|
base = base.Where("a.severity = ?", query.Severity)
|
|
}
|
|
if query.Location = strings.TrimSpace(query.Location); query.Location != "" {
|
|
base = base.Where("a.location ILIKE ?", "%"+query.Location+"%")
|
|
}
|
|
var count int64
|
|
if err := base.Count(&count).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
items := make([]Summary, 0)
|
|
err := base.Select("a.*, r.name AS rule_name, (SELECT count(*) FROM bell_alert_events ae WHERE ae.alert_id = a.id) AS event_count").
|
|
Joins("JOIN bell_rules r ON r.id = a.primary_rule_id").
|
|
Order("a.created_at DESC, a.id DESC").Offset((page - 1) * size).Limit(size).Scan(&items).Error
|
|
return items, count, err
|
|
}
|
|
|
|
func (s Service) Get(ctx context.Context, id string) (Detail, error) {
|
|
if _, err := uuid.Parse(id); err != nil {
|
|
return Detail{}, ErrNotFound
|
|
}
|
|
detail := Detail{Events: make([]LinkedEvent, 0), Matches: make([]RuleMatch, 0)}
|
|
db := s.DB.WithContext(ctx)
|
|
err := db.Table("bell_alerts a").
|
|
Select("a.*, r.name AS rule_name, (SELECT count(*) FROM bell_alert_events ae WHERE ae.alert_id = a.id) AS event_count").
|
|
Joins("JOIN bell_rules r ON r.id = a.primary_rule_id").Where("a.id = ?", id).Take(&detail.Alert).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return Detail{}, ErrNotFound
|
|
}
|
|
if err != nil {
|
|
return Detail{}, err
|
|
}
|
|
if err = db.Table("bell_events e").Select("e.*, ae.linked_at").
|
|
Joins("JOIN bell_alert_events ae ON ae.event_id = e.id").
|
|
Where("ae.alert_id = ?", id).Order("e.occurred_at, e.id").Scan(&detail.Events).Error; err != nil {
|
|
return Detail{}, err
|
|
}
|
|
err = db.Where("alert_id = ?", id).Order("matched_at, event_id, rule_id").Find(&detail.Matches).Error
|
|
return detail, err
|
|
}
|
|
|
|
type EventPageQuery struct {
|
|
PageIndex int `form:"pageIndex"`
|
|
PageSize int `form:"pageSize"`
|
|
EventType string `form:"eventType"`
|
|
Severity string `form:"severity"`
|
|
Location string `form:"location"`
|
|
}
|
|
|
|
type EventSummary struct {
|
|
event.Event
|
|
AlertCount int64 `json:"alertCount"`
|
|
}
|
|
|
|
func (s Service) ListEvents(ctx context.Context, query EventPageQuery) ([]EventSummary, int64, error) {
|
|
page, size := pageValues(query.PageIndex, query.PageSize)
|
|
db := s.DB.WithContext(ctx).Model(&event.Event{})
|
|
if value := strings.TrimSpace(query.EventType); value != "" {
|
|
db = db.Where("event_type ILIKE ?", "%"+value+"%")
|
|
}
|
|
if value := strings.TrimSpace(query.Severity); value != "" {
|
|
db = db.Where("severity = ?", value)
|
|
}
|
|
if value := strings.TrimSpace(query.Location); value != "" {
|
|
db = db.Where("location ILIKE ?", "%"+value+"%")
|
|
}
|
|
var count int64
|
|
if err := db.Count(&count).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
items := make([]EventSummary, 0)
|
|
err := db.Select("bell_events.*, (SELECT count(*) FROM bell_alert_events ae WHERE ae.event_id = bell_events.id) AS alert_count").
|
|
Order("occurred_at DESC, id DESC").Offset((page - 1) * size).Limit(size).Scan(&items).Error
|
|
return items, count, err
|
|
}
|
|
|
|
func pageValues(page, size int) (int, int) {
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
if size < 1 || size > 100 {
|
|
size = 20
|
|
}
|
|
return page, size
|
|
}
|