- Client: Go-based Windows hardware monitoring (CPU, GPU, memory, disk, network, power) - Server: Go + Gin + SQLite backend with REST API - Frontend: Vue 3 + Element Plus dashboard - Docker deployment support - Windows service installation script
100 lines
2.4 KiB
Go
100 lines
2.4 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"pc-monitor-server/model"
|
|
"pc-monitor-server/repository"
|
|
"time"
|
|
)
|
|
|
|
type AlertService struct {
|
|
alertRepo *repository.AlertRepository
|
|
metricsRepo *repository.MetricsRepository
|
|
}
|
|
|
|
func NewAlertService(alertRepo *repository.AlertRepository, metricsRepo *repository.MetricsRepository) *AlertService {
|
|
return &AlertService{alertRepo: alertRepo, metricsRepo: metricsRepo}
|
|
}
|
|
|
|
func (s *AlertService) CreateRule(rule *model.AlertRule) error {
|
|
rule.CreatedAt = time.Now()
|
|
return s.alertRepo.CreateRule(rule)
|
|
}
|
|
|
|
func (s *AlertService) GetRulesByDevice(deviceID string) ([]model.AlertRule, error) {
|
|
return s.alertRepo.GetRulesByDevice(deviceID)
|
|
}
|
|
|
|
func (s *AlertService) DeleteRule(id string) error {
|
|
return s.alertRepo.DeleteRule(id)
|
|
}
|
|
|
|
func (s *AlertService) GetActiveAlerts() ([]model.Alert, error) {
|
|
return s.alertRepo.GetActiveAlerts()
|
|
}
|
|
|
|
func (s *AlertService) ResolveAlert(id string) error {
|
|
return s.alertRepo.ResolveAlert(id)
|
|
}
|
|
|
|
func (s *AlertService) CheckAlerts(deviceID string, metrics *model.Metrics) error {
|
|
rules, err := s.alertRepo.GetRulesByDevice(deviceID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, rule := range rules {
|
|
value := getMetricValue(metrics, rule.Metric)
|
|
if checkThreshold(value, rule.Operator, rule.Threshold) {
|
|
alert := &model.Alert{
|
|
ID: fmt.Sprintf("%s-%s-%d", deviceID, rule.ID, time.Now().Unix()),
|
|
DeviceID: deviceID,
|
|
RuleID: rule.ID,
|
|
Metric: rule.Metric,
|
|
Value: value,
|
|
Message: fmt.Sprintf("%s %s %.2f (threshold: %.2f)", rule.Metric, rule.Operator, value, rule.Threshold),
|
|
Status: "active",
|
|
CreatedAt: time.Now(),
|
|
}
|
|
s.alertRepo.CreateAlert(alert)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getMetricValue(m *model.Metrics, metric string) float64 {
|
|
switch metric {
|
|
case "cpu_usage":
|
|
return m.CPUUsage
|
|
case "cpu_temperature":
|
|
return m.CPUTemperature
|
|
case "memory_usage":
|
|
return m.MemoryUsage
|
|
case "gpu_usage":
|
|
return m.GPUUsage
|
|
case "gpu_temperature":
|
|
return m.GPUTemperature
|
|
case "battery_level":
|
|
return float64(m.BatteryLevel)
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
func checkThreshold(value float64, operator string, threshold float64) bool {
|
|
switch operator {
|
|
case ">":
|
|
return value > threshold
|
|
case ">=":
|
|
return value >= threshold
|
|
case "<":
|
|
return value < threshold
|
|
case "<=":
|
|
return value <= threshold
|
|
case "==":
|
|
return value == threshold
|
|
default:
|
|
return false
|
|
}
|
|
}
|