feat(audit): F1+F2 告警静默规则标记完成 + 审计日志CSV导出实现
F1 告警静默规则 [done]: - 后端 alert_silence.go: CRUD + Toggle (onetime/daily/weekly 三模式) - 告警引擎 isSilenced 集成 (alert_engine.go) - 前端 SilenceRuleTab + SilenceDialog - 路由 /alerts/silences 已注册 F2 审计日志导出 [done]: - 重写 ExportAuditLogs: 真正的 CSV 导出 (encoding/csv + UTF-8 BOM) - 支持 module/action/username/startTime/endTime 筛选 - 导出限制 10000 条防溢出,自动记录审计日志 - JSON 格式向后兼容 (format=json) - 前端 exportLogs 传递查询参数 同时包含累积的前期工作: - 目录重构 internal/ -> controller/model/router (v0.55-v0.57) - 后端分层架构 dto/repository/service/utils - 审计模块全功能 (终端审计/操作审计/登录日志) - asciicast v2 录制格式 - SFTP 文件浏览器 - StatStrip 紧凑统计条 - 在线会话自动刷新 - LiveMonitor WebSocket 诊断修复 验证: go build ✅ | npm run build ✅ | Docker 部署 ✅ | 10 回归端点 ✅ | CSV 导出 ✅ | 静默 CRUD ✅
This commit is contained in:
1 parent
e57718998a
commit
77c234b060
314 files changed
+10050
-4065
No files matched your search
@@ -0,0 +1,266 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// ============================================
|
||||
// SiteTask 拨测任务
|
||||
// ============================================
|
||||
|
||||
// SiteTaskType 拨测任务类型
|
||||
type SiteTaskType string
|
||||
|
||||
const (
|
||||
SiteTaskTypeHTTP SiteTaskType = "http" // HTTP/HTTPS拨测
|
||||
SiteTaskTypeTCP SiteTaskType = "tcp" // TCP拨测
|
||||
SiteTaskTypePing SiteTaskType = "ping" // ICMP Ping拨测
|
||||
SiteTaskTypeDNS SiteTaskType = "dns" // DNS拨测
|
||||
SiteTaskTypeUDP SiteTaskType = "udp" // UDP拨测
|
||||
SiteTaskTypeFTP SiteTaskType = "ftp" // FTP拨测
|
||||
SiteTaskTypeSMTP SiteTaskType = "smtp" // SMTP拨测
|
||||
SiteTaskTypeTraceroute SiteTaskType = "traceroute" // 路由追踪
|
||||
)
|
||||
|
||||
// SiteTaskMethod HTTP请求方法
|
||||
type SiteTaskMethod string
|
||||
|
||||
const (
|
||||
SiteTaskMethodGET SiteTaskMethod = "GET"
|
||||
SiteTaskMethodPOST SiteTaskMethod = "POST"
|
||||
SiteTaskMethodHEAD SiteTaskMethod = "HEAD"
|
||||
)
|
||||
|
||||
// SiteTaskStatus 拨测任务状态
|
||||
type SiteTaskStatus string
|
||||
|
||||
const (
|
||||
SiteTaskStatusRunning SiteTaskStatus = "running" // 运行中
|
||||
SiteTaskStatusPaused SiteTaskStatus = "paused" // 已暂停
|
||||
SiteTaskStatusError SiteTaskStatus = "error" // 异常
|
||||
)
|
||||
|
||||
// SiteTask 站点拨测任务表
|
||||
// 定义对网站、服务等进行主动拨测的任务配置
|
||||
type SiteTask struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;comment:任务名称" json:"name"`
|
||||
URL string `gorm:"type:varchar(512);not null;comment:拨测URL/地址" json:"url"`
|
||||
TaskType SiteTaskType `gorm:"type:varchar(16);not null;comment:拨测类型" json:"task_type"`
|
||||
Method SiteTaskMethod `gorm:"type:varchar(8);default:'GET';comment:HTTP方法" json:"method"`
|
||||
// HTTP 拨测配置
|
||||
Headers string `gorm:"type:text;comment:请求头JSON" json:"headers,omitempty"`
|
||||
Body string `gorm:"type:text;comment:请求体" json:"body,omitempty"`
|
||||
Timeout int `gorm:"default:10;comment:超时时间(秒)" json:"timeout"`
|
||||
FollowRedirect bool `gorm:"default:true;comment:是否跟随重定向" json:"follow_redirect"`
|
||||
VerifySSL bool `gorm:"default:true;comment:是否验证SSL证书" json:"verify_ssl"`
|
||||
// 期望响应配置
|
||||
ExpectedStatus int `gorm:"default:200;comment:期望状态码" json:"expected_status"`
|
||||
ExpectedContent string `gorm:"type:text;comment:期望响应内容(支持正则)" json:"expected_content,omitempty"`
|
||||
ExpectedLength int `gorm:"default:0;comment:期望响应长度(0表示不检查)" json:"expected_length"`
|
||||
// 执行配置
|
||||
Frequency int `gorm:"default:60;comment:拨测频率(秒)" json:"frequency"`
|
||||
Nodes string `gorm:"type:varchar(256);comment:执行节点列表JSON" json:"nodes,omitempty"`
|
||||
// DNS 配置
|
||||
DNSResolver string `gorm:"type:varchar(64);comment:DNS解析服务器" json:"dns_resolver,omitempty"`
|
||||
// 状态
|
||||
Status SiteTaskStatus `gorm:"type:varchar(16);default:'running';comment:任务状态" json:"status"`
|
||||
LastResult string `gorm:"type:varchar(16);comment:最近结果: success/fail" json:"last_result,omitempty"`
|
||||
LastCheckAt *time.Time `gorm:"comment:最近检查时间" json:"last_check_at,omitempty"`
|
||||
SuccessRate float64 `gorm:"type:decimal(5,2);default:100.00;comment:成功率(%)" json:"success_rate"`
|
||||
AvgResponse float64 `gorm:"comment:平均响应时间(ms)" json:"avg_response,omitempty"`
|
||||
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
|
||||
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
||||
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
|
||||
|
||||
// 关联关系
|
||||
Results []SiteResult `gorm:"foreignKey:TaskID" json:"results,omitempty"`
|
||||
Alerts []SiteAlert `gorm:"foreignKey:TaskID" json:"alerts,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SiteTask) TableName() string {
|
||||
return "ops_site_tasks"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SiteResult 拨测结果
|
||||
// ============================================
|
||||
|
||||
// SiteResultStatus 拨测结果状态
|
||||
type SiteResultStatus string
|
||||
|
||||
const (
|
||||
SiteResultSuccess SiteResultStatus = "success" // 成功
|
||||
SiteResultFail SiteResultStatus = "fail" // 失败
|
||||
SiteResultTimeout SiteResultStatus = "timeout" // 超时
|
||||
)
|
||||
|
||||
// SiteResult 拨测结果表
|
||||
// 存储每次拨测的详细结果数据
|
||||
type SiteResult struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
TaskID uint `gorm:"not null;index:idx_task_time;comment:任务ID" json:"task_id"`
|
||||
Status SiteResultStatus `gorm:"type:varchar(16);not null;comment:结果状态" json:"status"`
|
||||
HTTPStatusCode int `gorm:"comment:HTTP状态码" json:"http_status_code,omitempty"`
|
||||
// 时间指标
|
||||
DNSTime float64 `gorm:"comment:DNS解析时间(ms)" json:"dns_time,omitempty"`
|
||||
ConnectTime float64 `gorm:"comment:连接时间(ms)" json:"connect_time,omitempty"`
|
||||
TLSTime float64 `gorm:"comment:TLS握手时间(ms)" json:"tls_time,omitempty"`
|
||||
TTFB float64 `gorm:"comment:首字节时间(ms)" json:"ttfb,omitempty"`
|
||||
ResponseTime float64 `gorm:"comment:响应时间(ms)" json:"response_time,omitempty"`
|
||||
TotalTime float64 `gorm:"not null;comment:总耗时(ms)" json:"total_time"`
|
||||
// 响应信息
|
||||
ResponseSize int `gorm:"comment:响应大小(bytes)" json:"response_size,omitempty"`
|
||||
ResponseBody string `gorm:"type:text;comment:响应内容摘要" json:"response_body,omitempty"`
|
||||
// 网络信息
|
||||
RemoteIP string `gorm:"type:varchar(64);comment:远端IP" json:"remote_ip,omitempty"`
|
||||
LocalNode string `gorm:"type:varchar(64);comment:执行节点" json:"local_node,omitempty"`
|
||||
// 错误信息
|
||||
ErrorMessage string `gorm:"type:text;comment:错误信息" json:"error_message,omitempty"`
|
||||
ErrorDetail string `gorm:"type:text;comment:错误详情" json:"error_detail,omitempty"`
|
||||
// SSL 证书信息
|
||||
SSLCertExpiry *time.Time `gorm:"comment:SSL证书过期时间" json:"ssl_cert_expiry,omitempty"`
|
||||
SSLCertIssuer string `gorm:"type:varchar(256);comment:SSL证书签发者" json:"ssl_cert_issuer,omitempty"`
|
||||
SSLCertSubject string `gorm:"type:varchar(256);comment:SSL证书主题" json:"ssl_cert_subject,omitempty"`
|
||||
SSLDaysRemaining int `gorm:"comment:SSL证书剩余天数" json:"ssl_days_remaining,omitempty"`
|
||||
// 检查内容匹配
|
||||
ContentMatch bool `gorm:"comment:内容匹配结果" json:"content_match,omitempty"`
|
||||
// 时间戳
|
||||
CheckedAt time.Time `gorm:"not null;index:idx_task_time;comment:拨测时间" json:"checked_at"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
|
||||
// 关联关系
|
||||
Task *SiteTask `gorm:"foreignKey:TaskID" json:"task,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SiteResult) TableName() string {
|
||||
return "ops_site_results"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SiteAlert 拨测告警
|
||||
// ============================================
|
||||
|
||||
// SiteAlertStatus 拨测告警状态
|
||||
type SiteAlertStatus string
|
||||
|
||||
const (
|
||||
SiteAlertStatusActive SiteAlertStatus = "active" // 活跃
|
||||
SiteAlertStatusResolved SiteAlertStatus = "resolved" // 已恢复
|
||||
SiteAlertStatusMuted SiteAlertStatus = "muted" // 已静默
|
||||
)
|
||||
|
||||
// SiteAlertSeverity 拨测告警级别
|
||||
type SiteAlertSeverity string
|
||||
|
||||
const (
|
||||
SiteAlertCritical SiteAlertSeverity = "critical" // 严重
|
||||
SiteAlertWarning SiteAlertSeverity = "warning" // 警告
|
||||
SiteAlertInfo SiteAlertSeverity = "info" // 通知
|
||||
)
|
||||
|
||||
// SiteAlert 拨测告警表
|
||||
// 记录拨测任务触发的告警事件
|
||||
type SiteAlert struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
TaskID uint `gorm:"not null;index;comment:任务ID" json:"task_id"`
|
||||
Severity SiteAlertSeverity `gorm:"type:varchar(16);not null;comment:告警级别" json:"severity"`
|
||||
Status SiteAlertStatus `gorm:"type:varchar(16);default:'active';index;comment:告警状态" json:"status"`
|
||||
Title string `gorm:"type:varchar(256);not null;comment:告警标题" json:"title"`
|
||||
Message string `gorm:"type:text;comment:告警详情" json:"message,omitempty"`
|
||||
// 触发条件
|
||||
TriggerType string `gorm:"type:varchar(32);comment:触发类型: timeout/status_error/response_time/ssl_expiry" json:"trigger_type"`
|
||||
TriggerValue string `gorm:"type:varchar(128);comment:触发值" json:"trigger_value,omitempty"`
|
||||
Threshold float64 `gorm:"comment:阈值" json:"threshold,omitempty"`
|
||||
// 响应信息
|
||||
ResponseTime float64 `gorm:"comment:响应时间(ms)" json:"response_time,omitempty"`
|
||||
HTTPStatus int `gorm:"comment:HTTP状态码" json:"http_status,omitempty"`
|
||||
ErrorMessage string `gorm:"type:text;comment:错误信息" json:"error_message,omitempty"`
|
||||
// 状态变化
|
||||
StartedAt time.Time `gorm:"not null;comment:告警开始时间" json:"started_at"`
|
||||
ResolvedAt *time.Time `gorm:"comment:告警恢复时间" json:"resolved_at,omitempty"`
|
||||
Duration int `gorm:"comment:持续时间(秒)" json:"duration,omitempty"`
|
||||
NotifyCount int `gorm:"default:0;comment:通知次数" json:"notify_count"`
|
||||
LastNotifyAt *time.Time `gorm:"comment:最近通知时间" json:"last_notify_at,omitempty"`
|
||||
Acknowledged bool `gorm:"default:false;comment:是否已确认" json:"acknowledged"`
|
||||
AcknowledgedBy uint `gorm:"comment:确认人ID" json:"acknowledged_by,omitempty"`
|
||||
AcknowledgedAt *time.Time `gorm:"comment:确认时间" json:"acknowledged_at,omitempty"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
||||
|
||||
// 关联关系
|
||||
Task *SiteTask `gorm:"foreignKey:TaskID" json:"task,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SiteAlert) TableName() string {
|
||||
return "ops_site_alerts"
|
||||
}
|
||||
|
||||
// SiteTaskCreateRequest 拨测任务创建请求
|
||||
type SiteTaskCreateRequest struct {
|
||||
Name string `json:"name" binding:"required,max=128"`
|
||||
URL string `json:"url" binding:"required,max=512,url"`
|
||||
TaskType SiteTaskType `json:"task_type" binding:"required"`
|
||||
Method SiteTaskMethod `json:"method"`
|
||||
Headers string `json:"headers"`
|
||||
Body string `json:"body"`
|
||||
Timeout int `json:"timeout"`
|
||||
FollowRedirect bool `json:"follow_redirect"`
|
||||
VerifySSL bool `json:"verify_ssl"`
|
||||
ExpectedStatus int `json:"expected_status"`
|
||||
ExpectedContent string `json:"expected_content"`
|
||||
ExpectedLength int `json:"expected_length"`
|
||||
Frequency int `json:"frequency"`
|
||||
Nodes []string `json:"nodes"`
|
||||
DNSResolver string `json:"dns_resolver"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// SiteTaskUpdateRequest 拨测任务更新请求
|
||||
type SiteTaskUpdateRequest struct {
|
||||
Name string `json:"name" binding:"max=128"`
|
||||
URL string `json:"url" binding:"max=512,url"`
|
||||
Method SiteTaskMethod `json:"method"`
|
||||
Headers string `json:"headers"`
|
||||
Body string `json:"body"`
|
||||
Timeout int `json:"timeout"`
|
||||
FollowRedirect bool `json:"follow_redirect"`
|
||||
VerifySSL bool `json:"verify_ssl"`
|
||||
ExpectedStatus int `json:"expected_status"`
|
||||
ExpectedContent string `json:"expected_content"`
|
||||
Frequency int `json:"frequency"`
|
||||
Nodes []string `json:"nodes"`
|
||||
Status SiteTaskStatus `json:"status"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// SiteTaskStatistics 拨测任务统计
|
||||
type SiteTaskStatistics struct {
|
||||
TaskID uint `json:"task_id"`
|
||||
TotalChecks int64 `json:"total_checks"`
|
||||
SuccessCount int64 `json:"success_count"`
|
||||
FailCount int64 `json:"fail_count"`
|
||||
TimeoutCount int64 `json:"timeout_count"`
|
||||
SuccessRate float64 `json:"success_rate"`
|
||||
AvgResponseTime float64 `json:"avg_response_time"`
|
||||
MinResponseTime float64 `json:"min_response_time"`
|
||||
MaxResponseTime float64 `json:"max_response_time"`
|
||||
Last24hUptime float64 `json:"last_24h_uptime"`
|
||||
Last7dUptime float64 `json:"last_7d_uptime"`
|
||||
Last30dUptime float64 `json:"last_30d_uptime"`
|
||||
}
|
||||
|
||||
// SiteResultQuery 拨测结果查询参数
|
||||
type SiteResultQuery struct {
|
||||
TaskID uint `json:"task_id" form:"task_id"`
|
||||
Status string `json:"status" form:"status"`
|
||||
StartTime int64 `json:"start_time" form:"start_time"`
|
||||
EndTime int64 `json:"end_time" form:"end_time"`
|
||||
Limit int `json:"limit" form:"limit"`
|
||||
Offset int `json:"offset" form:"offset"`
|
||||
}
|
||||
Reference in new issue
Block a user