diff --git a/go.sum b/go.sum index 9fb5bfa..0e36957 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,7 @@ aead.dev/minisign v0.3.0 h1:8Xafzy5PEVZqYDNP60yJHARlW1eOQtsKNp/Ph2c0vRA= aead.dev/minisign v0.3.0/go.mod h1:NLvG3Uoq3skkRMDuc3YHpWUTMTrSExqm+Ij73W13F6Y= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc= github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= diff --git a/internal/repo/ssh_login_repo.go b/internal/repo/ssh_login_repo.go index 50f454e..1828518 100644 --- a/internal/repo/ssh_login_repo.go +++ b/internal/repo/ssh_login_repo.go @@ -24,20 +24,3 @@ func NewSSHLoginEventRepo(db *gorm.DB) *SSHLoginEventRepo { func (r *SSHLoginEventRepo) DeleteEventsByAgentID(ctx context.Context, agentID string) error { return r.GetDB(ctx).Where("agent_id = ?", agentID).Delete(&models.SSHLoginEvent{}).Error } - -// DeleteOldEvents 删除旧的事件记录(保留最近N天) -func (r *SSHLoginEventRepo) DeleteOldEvents(ctx context.Context, beforeTimestamp int64) error { - return r.GetDB(ctx).Where("timestamp < ?", beforeTimestamp).Delete(&models.SSHLoginEvent{}).Error -} - -// FindEventByTimestamp 查找指定时间范围内的事件(用于去重) -func (r *SSHLoginEventRepo) FindEventByTimestamp(ctx context.Context, agentID string, timestamp, tolerance int64) (*models.SSHLoginEvent, error) { - var event models.SSHLoginEvent - err := r.GetDB(ctx).Where("agent_id = ? AND timestamp >= ? AND timestamp <= ?", - agentID, timestamp-tolerance, timestamp+tolerance). - First(&event).Error - if err == gorm.ErrRecordNotFound { - return nil, nil - } - return &event, err -} diff --git a/internal/repo/tamper_event_repo.go b/internal/repo/tamper_event_repo.go index b830bea..a03cf0a 100644 --- a/internal/repo/tamper_event_repo.go +++ b/internal/repo/tamper_event_repo.go @@ -18,7 +18,7 @@ func NewTamperEventRepo(db *gorm.DB) *TamperEventRepo { } } -// DeleteOldEvents 删除旧的事件记录(保留最近N天) -func (r *TamperEventRepo) DeleteOldEvents(ctx context.Context, beforeTimestamp int64) error { - return r.GetDB(ctx).Where("timestamp < ?", beforeTimestamp).Delete(&models.TamperEvent{}).Error +// DeleteEventsByAgentID 删除探针的所有防篡改事件 +func (r *TamperEventRepo) DeleteEventsByAgentID(ctx context.Context, agentID string) error { + return r.GetDB(ctx).Where("agent_id = ?", agentID).Delete(&models.TamperEvent{}).Error } diff --git a/internal/service/agent_service.go b/internal/service/agent_service.go index d5afda6..8a96376 100644 --- a/internal/service/agent_service.go +++ b/internal/service/agent_service.go @@ -20,20 +20,24 @@ import ( type AgentService struct { logger *zap.Logger *orz.Service - AgentRepo *repo.AgentRepo - apiKeyService *ApiKeyService - metricService *MetricService - geoipService *GeoIPService + AgentRepo *repo.AgentRepo + TamperEventRepo *repo.TamperEventRepo + SSHLoginEventRepo *repo.SSHLoginEventRepo + apiKeyService *ApiKeyService + metricService *MetricService + geoipService *GeoIPService } func NewAgentService(logger *zap.Logger, db *gorm.DB, apiKeyService *ApiKeyService, metricService *MetricService, geoipService *GeoIPService) *AgentService { return &AgentService{ - logger: logger, - Service: orz.NewService(db), - AgentRepo: repo.NewAgentRepo(db), - apiKeyService: apiKeyService, - metricService: metricService, - geoipService: geoipService, + logger: logger, + Service: orz.NewService(db), + AgentRepo: repo.NewAgentRepo(db), + TamperEventRepo: repo.NewTamperEventRepo(db), + SSHLoginEventRepo: repo.NewSSHLoginEventRepo(db), + apiKeyService: apiKeyService, + metricService: metricService, + geoipService: geoipService, } } @@ -333,15 +337,21 @@ func (s *AgentService) GetStatistics(ctx context.Context) (map[string]interface{ func (s *AgentService) DeleteAgent(ctx context.Context, agentID string) error { // 在事务中执行所有删除操作 return s.Transaction(ctx, func(ctx context.Context) error { - // 1. 删除探针的所有指标数据 - if err := s.metricService.DeleteAgentMetrics(ctx, agentID); err != nil { - s.logger.Error("删除探针指标数据失败", zap.String("agentId", agentID), zap.Error(err)) + // 1. 删除探针的审计结果 + if err := s.AgentRepo.DeleteAuditResults(ctx, agentID); err != nil { + s.logger.Error("删除探针审计结果失败", zap.String("agentId", agentID), zap.Error(err)) return err } - // 2. 删除探针的审计结果 - if err := s.AgentRepo.DeleteAuditResults(ctx, agentID); err != nil { - s.logger.Error("删除探针审计结果失败", zap.String("agentId", agentID), zap.Error(err)) + // 2. 删除探针的目录保护事件数据 + if err := s.TamperEventRepo.DeleteEventsByAgentID(ctx, agentID); err != nil { + s.logger.Error("删除探针目录保护事件失败", zap.String("agentId", agentID), zap.Error(err)) + return err + } + + // 3. 删除探针的SSH登录事件数据 + if err := s.SSHLoginEventRepo.DeleteEventsByAgentID(ctx, agentID); err != nil { + s.logger.Error("删除探针SSH登录事件失败", zap.String("agentId", agentID), zap.Error(err)) return err } diff --git a/internal/service/ssh_login_service.go b/internal/service/ssh_login_service.go index 04a4a2f..17a6bba 100644 --- a/internal/service/ssh_login_service.go +++ b/internal/service/ssh_login_service.go @@ -127,15 +127,6 @@ func (s *SSHLoginService) HandleEvent(ctx context.Context, agentID string, event return nil } - // 去重检查(避免 Agent 重启时重复上报) - existing, err := s.SSHLoginEventRepo.FindEventByTimestamp(ctx, agentID, eventData.Timestamp, 5000) // 5秒容差 - if err != nil { - s.logger.Warn("查询事件去重失败", zap.Error(err)) - } else if existing != nil { - s.logger.Debug("检测到重复事件,跳过", zap.String("agentId", agentID), zap.Int64("timestamp", eventData.Timestamp)) - return nil - } - // 保存事件到数据库 event := &models.SSHLoginEvent{ AgentID: agentID, @@ -170,21 +161,3 @@ func (s *SSHLoginService) HandleEvent(ctx context.Context, agentID string, event func (s *SSHLoginService) DeleteEventsByAgentID(ctx context.Context, agentID string) error { return s.SSHLoginEventRepo.DeleteEventsByAgentID(ctx, agentID) } - -// CleanupOldEvents 清理旧事件(定期任务) -func (s *SSHLoginService) CleanupOldEvents(ctx context.Context, days int) error { - if days < 1 { - days = 90 // 默认保留90天 - } - - timestamp := int64(days) * 24 * 60 * 60 * 1000 - cutoff := time.Now().UnixMilli() - timestamp - - if err := s.SSHLoginEventRepo.DeleteOldEvents(ctx, cutoff); err != nil { - s.logger.Error("清理SSH登录事件失败", zap.Error(err), zap.Int("days", days)) - return err - } - - s.logger.Info("成功清理SSH登录事件", zap.Int("days", days)) - return nil -} diff --git a/internal/service/tamper_service.go b/internal/service/tamper_service.go index eae485b..0bfe219 100644 --- a/internal/service/tamper_service.go +++ b/internal/service/tamper_service.go @@ -203,13 +203,6 @@ func (s *TamperService) CreateEvent(ctx context.Context, agentID string, eventDa return s.TamperEventRepo.Create(ctx, event) } -// CleanupOldRecords 清理旧记录(保留最近30天) -func (s *TamperService) CleanupOldRecords(ctx context.Context) error { - // 30天前的时间戳 - threshold := time.Now().AddDate(0, 0, -30).UnixMilli() - return s.TamperEventRepo.DeleteOldEvents(ctx, threshold) -} - func (s *TamperService) HandleConfigResult(ctx context.Context, agentID string, resp protocol.TamperProtectResponse) error { // 获取现有配置 config, err := s.GetConfigByAgentID(ctx, agentID) diff --git a/web/src/portal/pages/ServerDetail.tsx b/web/src/portal/pages/ServerDetail.tsx index eda8c42..75981c5 100644 --- a/web/src/portal/pages/ServerDetail.tsx +++ b/web/src/portal/pages/ServerDetail.tsx @@ -19,6 +19,7 @@ import {NetworkConnectionChart} from '@portal/components/server/NetworkConnectio import {TemperatureChart} from '@portal/components/server/TemperatureChart.tsx'; import {useAgentQuery, useLatestMetricsQuery} from '@portal/hooks/server.ts'; import {SERVER_TIME_RANGE_OPTIONS} from '@portal/constants/time.ts'; +import LittleStatCard from '@portal/components/LittleStatCard.tsx'; /** * 服务器详情页面 @@ -43,6 +44,9 @@ const ServerDetail = () => { const agent = agentResponse?.data; const latestMetrics = latestMetricsResponse?.data || null; + const formatLoad = (value?: number) => ( + typeof value === 'number' && Number.isFinite(value) ? value.toFixed(2) : '-' + ); if (isLoading) { return ; @@ -67,6 +71,18 @@ const ServerDetail = () => { {/* 系统信息 */} + {/* 系统负载 */} + +
+ + + +
+
+ {/* 历史趋势图表 */}