Files
2026-07-13 12:31:02 +08:00

123 lines
3.4 KiB
Go

package monitoring
import (
"log"
"strings"
"time"
"service-operation/operations"
"service-operation/pocketbase"
"service-operation/shared/savers"
"service-operation/types"
)
func (ms *MonitoringService) performCheck(service pocketbase.Service) {
// First, fetch the latest service status from PocketBase to ensure we have current data
latestService, err := ms.pbClient.GetService(service.ID)
if err != nil {
log.Printf("Failed to fetch latest service status for %s: %v", service.Name, err)
return
}
// Respect the service status - don't check paused services
if latestService.Status == "paused" {
return // Silently skip paused services
}
timeout := 10 * time.Second // Default timeout
var result *types.OperationResult
serviceType := strings.ToLower(latestService.ServiceType)
// Single log message for check start
//log.Printf("Checking %s (%s)", latestService.Name, serviceType)
switch serviceType {
case "ping", "icmp":
pingOp := operations.NewPingOperation(timeout)
host := latestService.Host
if host == "" {
host = latestService.URL
}
result, err = pingOp.Execute(host, 1) // Single ping for monitoring
case "dns":
dnsOp := operations.NewDNSOperation(timeout)
host := latestService.Host
if host == "" {
host = latestService.Domain
}
// Default to A record, but could be made configurable
queryType := "A"
result, err = dnsOp.Execute(host, queryType)
case "tcp":
tcpOp := operations.NewTCPOperation(timeout)
host := latestService.Host
if host == "" {
host = latestService.URL
}
port := latestService.Port
if port <= 0 {
port = 80 // Default port
}
result, err = tcpOp.Execute(host, port)
case "http", "https":
httpOp := operations.NewHTTPOperation(timeout)
url := latestService.URL
if url == "" {
url = latestService.Host
}
result, err = httpOp.Execute(url, "GET")
default:
log.Printf("Unknown service type: %s for service %s", latestService.ServiceType, latestService.Name)
return
}
// Determine status based on result
status := "down"
errorMessage := ""
responseTime := int64(0)
if err != nil {
errorMessage = err.Error()
log.Printf("❌ %s failed: %v", latestService.Name, err)
} else if result != nil {
responseTime = result.ResponseTime.Milliseconds()
if result.Success {
status = "up"
//log.Printf("✅ %s: %.0fms", latestService.Name, float64(responseTime))
} else {
status = "down"
errorMessage = result.Error
log.Printf("❌ %s failed: %s", latestService.Name, errorMessage)
}
}
// Only update service status if the service is not paused
// Check one more time before updating to prevent race conditions
currentService, err := ms.pbClient.GetService(latestService.ID)
if err != nil {
log.Printf("Failed to verify service status before update for %s: %v", latestService.Name, err)
return
}
if currentService.Status == "paused" {
return // Silently skip status update for paused services
}
// Update service status in PocketBase only if not paused
if err := ms.pbClient.UpdateServiceStatus(latestService.ID, status, responseTime, errorMessage); err != nil {
log.Printf("Failed to update service status for %s: %v", latestService.Name, err)
}
// Save metrics data with regional information
if result != nil {
regionName, agentID := ms.GetRegionalInfo()
metricsSaver := savers.NewMetricsSaverWithRegion(ms.pbClient, regionName, agentID)
metricsSaver.SaveMetricsForService(*latestService, result)
}
}