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 = () => {
{/* 系统信息 */}
+ {/* 系统负载 */}
+
+
+
+
+
+
+
+
{/* 历史趋势图表 */}