933e70a3f6
- Add robust notification system supporting 7+ communication channels with intelligent message templating, resource monitoring, and SSL certificate alerts. Notification Channels: (Telegram, Discord, Slack, Signal, Email, Google Chat, Webhooks). - This notification system provides enterprise-grade alerting capabilities with extensive customization options and multi-channel redundancy for critical service monitoring.
236 lines
9.5 KiB
Go
236 lines
9.5 KiB
Go
|
|
package servermonitoring
|
|
|
|
import (
|
|
"time"
|
|
|
|
"service-operation/notification"
|
|
"service-operation/pocketbase"
|
|
)
|
|
|
|
// ServerNotificationService handles server-specific notifications
|
|
type ServerNotificationService struct {
|
|
notificationManager *notification.NotificationManager
|
|
}
|
|
|
|
// NewServerNotificationService creates a new server notification service
|
|
func NewServerNotificationService(pbClient *pocketbase.PocketBaseClient) *ServerNotificationService {
|
|
// log.Println("🔧 Creating new ServerNotificationService instance")
|
|
return &ServerNotificationService{
|
|
notificationManager: notification.NewNotificationManager(pbClient),
|
|
}
|
|
}
|
|
|
|
// SendResourceNotification sends a resource-specific notification (CPU, RAM, Disk, etc.)
|
|
func (sns *ServerNotificationService) SendResourceNotification(server Server, status string, message string, resourceType string) error {
|
|
return sns.SendResourceNotificationWithValues(server, status, message, resourceType, "N/A", "N/A")
|
|
}
|
|
|
|
// SendResourceNotificationWithValues sends a resource-specific notification with actual usage and threshold values
|
|
func (sns *ServerNotificationService) SendResourceNotificationWithValues(server Server, status string, message string, resourceType string, usageValue string, thresholdValue string) error {
|
|
// log.Printf("📨 === SENDING RESOURCE NOTIFICATION WITH VALUES ===")
|
|
// log.Printf("🔔 SendResourceNotificationWithValues called for server: %s", server.Name)
|
|
// log.Printf("📊 Resource Notification Parameters:")
|
|
// log.Printf(" - Server Name: %s", server.Name)
|
|
// log.Printf(" - Resource Type: %s", resourceType)
|
|
// log.Printf(" - Status: %s", status)
|
|
// log.Printf(" - Message: %s", message)
|
|
// log.Printf(" - Usage Value: %s", usageValue)
|
|
// log.Printf(" - Threshold Value: %s", thresholdValue)
|
|
// log.Printf(" - Notification ID: '%s'", server.NotificationID)
|
|
// log.Printf(" - Template ID: '%s'", server.TemplateID)
|
|
|
|
// Validate notification configuration
|
|
if server.NotificationID == "" {
|
|
// log.Printf("❌ NOTIFICATION FAILED: No notification ID configured for server %s", server.Name)
|
|
return nil
|
|
}
|
|
|
|
// Get server metrics for notification
|
|
cpuUsage, ramUsage, diskUsage, networkUsage, cpuTemp, diskIO := sns.getServerMetrics(server.ServerID)
|
|
|
|
// Override specific resource metric with actual value
|
|
switch resourceType {
|
|
case "cpu":
|
|
cpuUsage = usageValue
|
|
case "ram", "memory":
|
|
ramUsage = usageValue
|
|
case "disk":
|
|
diskUsage = usageValue
|
|
case "network":
|
|
networkUsage = usageValue
|
|
case "cpu_temp", "cpu_temperature":
|
|
cpuTemp = usageValue
|
|
case "disk_io":
|
|
diskIO = usageValue
|
|
}
|
|
|
|
// Convert to generic notification payload
|
|
notificationPayload := ¬ification.NotificationPayload{
|
|
ServiceName: server.Name,
|
|
Status: status,
|
|
Host: server.IPAddress,
|
|
Hostname: server.Hostname,
|
|
Port: 0,
|
|
ServiceType: "server",
|
|
ResponseTime: 0,
|
|
Timestamp: time.Now(),
|
|
Message: message,
|
|
// Server monitoring metrics
|
|
CPUUsage: cpuUsage,
|
|
RAMUsage: ramUsage,
|
|
DiskUsage: diskUsage,
|
|
NetworkUsage: networkUsage,
|
|
CPUTemp: cpuTemp,
|
|
DiskIO: diskIO,
|
|
Threshold: thresholdValue,
|
|
}
|
|
|
|
// log.Printf("📤 About to call SendResourceNotification...")
|
|
// log.Printf(" - Resource Type: %s", resourceType)
|
|
// log.Printf(" - Notification ID: %s", server.NotificationID)
|
|
// log.Printf(" - Template ID: %s", server.TemplateID)
|
|
// log.Printf(" - Usage Value: %s", usageValue)
|
|
// log.Printf(" - Threshold Value: %s", thresholdValue)
|
|
|
|
// Send resource-specific notification using the notification manager
|
|
err := sns.notificationManager.SendResourceNotification(notificationPayload, server.NotificationID, server.TemplateID, resourceType)
|
|
if err != nil {
|
|
// log.Printf("❌ RESOURCE NOTIFICATION ERROR for server %s: %v", server.Name, err)
|
|
return err
|
|
}
|
|
|
|
// log.Printf("✅ RESOURCE NOTIFICATION SENT SUCCESSFULLY for server %s (%s)", server.Name, resourceType)
|
|
// log.Printf("=== RESOURCE NOTIFICATION COMPLETE ===")
|
|
|
|
return nil
|
|
}
|
|
|
|
// SendServerNotification sends a notification for server status change
|
|
func (sns *ServerNotificationService) SendServerNotification(server Server, status string, message string) error {
|
|
// log.Printf("📨 === SENDING SERVER NOTIFICATION ===")
|
|
// log.Printf("🔔 SendServerNotification called for server: %s", server.Name)
|
|
// log.Printf("📊 Notification Parameters:")
|
|
// log.Printf(" - Server Name: %s", server.Name)
|
|
// log.Printf(" - Server ID: %s", server.ServerID)
|
|
// log.Printf(" - Status: %s", status)
|
|
// log.Printf(" - Message: %s", message)
|
|
// log.Printf(" - Notification ID: '%s'", server.NotificationID)
|
|
// log.Printf(" - Template ID: '%s'", server.TemplateID)
|
|
// log.Printf(" - IP Address: %s", server.IPAddress)
|
|
// log.Printf(" - Hostname: %s", server.Hostname)
|
|
|
|
// Validate notification configuration
|
|
if server.NotificationID == "" {
|
|
// log.Printf("❌ NOTIFICATION FAILED: No notification ID configured for server %s", server.Name)
|
|
return nil
|
|
}
|
|
|
|
// log.Printf("✅ Notification ID validation passed: %s", server.NotificationID)
|
|
|
|
// Get server metrics for notification
|
|
cpuUsage, ramUsage, diskUsage, networkUsage, cpuTemp, diskIO := sns.getServerMetrics(server.ServerID)
|
|
|
|
// Convert to generic notification payload
|
|
// log.Printf("🔄 Converting to generic notification payload...")
|
|
notificationPayload := ¬ification.NotificationPayload{
|
|
ServiceName: server.Name,
|
|
Status: status,
|
|
Host: server.IPAddress,
|
|
Hostname: server.Hostname,
|
|
Port: 0, // Servers don't have ports
|
|
ServiceType: "server",
|
|
ResponseTime: 0,
|
|
Timestamp: time.Now(),
|
|
Message: message,
|
|
// Server monitoring metrics
|
|
CPUUsage: cpuUsage,
|
|
RAMUsage: ramUsage,
|
|
DiskUsage: diskUsage,
|
|
NetworkUsage: networkUsage,
|
|
CPUTemp: cpuTemp,
|
|
DiskIO: diskIO,
|
|
Threshold: "N/A", // Can be set based on server configuration
|
|
}
|
|
|
|
// log.Printf("📦 Generic notification payload created:")
|
|
// log.Printf(" - ServiceName: %s", notificationPayload.ServiceName)
|
|
// log.Printf(" - Status: %s", notificationPayload.Status)
|
|
// log.Printf(" - Host: %s", notificationPayload.Host)
|
|
// log.Printf(" - ServiceType: %s", notificationPayload.ServiceType)
|
|
// log.Printf(" - Message: %s", notificationPayload.Message)
|
|
// log.Printf(" - CPUUsage: %s", notificationPayload.CPUUsage)
|
|
// log.Printf(" - RAMUsage: %s", notificationPayload.RAMUsage)
|
|
// log.Printf(" - DiskUsage: %s", notificationPayload.DiskUsage)
|
|
// log.Printf(" - NetworkUsage: %s", notificationPayload.NetworkUsage)
|
|
// log.Printf(" - CPUTemp: %s", notificationPayload.CPUTemp)
|
|
// log.Printf(" - DiskIO: %s", notificationPayload.DiskIO)
|
|
// log.Printf(" - Timestamp: %v", notificationPayload.Timestamp)
|
|
|
|
// log.Printf("📤 About to call SendServiceNotification...")
|
|
// log.Printf(" - Notification ID: %s", server.NotificationID)
|
|
// log.Printf(" - Template ID: %s", server.TemplateID)
|
|
|
|
// Send notification using the notification manager
|
|
err := sns.notificationManager.SendServiceNotification(notificationPayload, server.NotificationID, server.TemplateID)
|
|
if err != nil {
|
|
// log.Printf("❌ NOTIFICATION MANAGER ERROR for server %s: %v", server.Name, err)
|
|
// log.Printf("❌ Error Details:")
|
|
// log.Printf(" - Error Type: %T", err)
|
|
// log.Printf(" - Error Message: %s", err.Error())
|
|
// log.Printf(" - Notification ID used: %s", server.NotificationID)
|
|
// log.Printf(" - Template ID used: %s", server.TemplateID)
|
|
return err
|
|
}
|
|
|
|
// log.Printf("✅ NOTIFICATION SENT SUCCESSFULLY for server %s", server.Name)
|
|
// log.Printf("✅ Notification Details:")
|
|
// log.Printf(" - Status: %s", status)
|
|
// log.Printf(" - Notification ID: %s", server.NotificationID)
|
|
// log.Printf(" - Template ID: %s", server.TemplateID)
|
|
// log.Printf("=== NOTIFICATION COMPLETE ===")
|
|
|
|
return nil
|
|
}
|
|
|
|
// getServerMetrics retrieves the latest server metrics (placeholder implementation)
|
|
// This should be replaced with actual metric retrieval from your monitoring system
|
|
func (sns *ServerNotificationService) getServerMetrics(serverID string) (cpuUsage, ramUsage, diskUsage, networkUsage, cpuTemp, diskIO string) {
|
|
// TODO: Implement actual metric retrieval from your server monitoring system
|
|
// For now, returning placeholder values
|
|
// You should replace this with actual calls to your metrics collection system
|
|
|
|
// log.Printf("🔍 Retrieving server metrics for server ID: %s", serverID)
|
|
|
|
// These should be replaced with actual metric values from your monitoring system
|
|
cpuUsage = "N/A"
|
|
ramUsage = "N/A"
|
|
diskUsage = "N/A"
|
|
networkUsage = "N/A"
|
|
cpuTemp = "N/A"
|
|
diskIO = "N/A"
|
|
|
|
// Example of how you might retrieve metrics:
|
|
// You could query your metrics database, call an API, or read from system files
|
|
// For example:
|
|
// metrics, err := sns.getLatestMetrics(serverID)
|
|
// if err == nil {
|
|
// cpuUsage = fmt.Sprintf("%.1f%%", metrics.CPUUsage)
|
|
// ramUsage = fmt.Sprintf("%.1f%%", metrics.RAMUsage)
|
|
// diskUsage = fmt.Sprintf("%.1f%%", metrics.DiskUsage)
|
|
// networkUsage = fmt.Sprintf("%.2f MB/s", metrics.NetworkUsage)
|
|
// cpuTemp = fmt.Sprintf("%.1f°C", metrics.CPUTemp)
|
|
// diskIO = fmt.Sprintf("%.2f MB/s", metrics.DiskIO)
|
|
// }
|
|
|
|
// log.Printf("📊 Retrieved server metrics:")
|
|
// log.Printf(" - CPU Usage: %s", cpuUsage)
|
|
// log.Printf(" - RAM Usage: %s", ramUsage)
|
|
// log.Printf(" - Disk Usage: %s", diskUsage)
|
|
// log.Printf(" - Network Usage: %s", networkUsage)
|
|
// log.Printf(" - CPU Temperature: %s", cpuTemp)
|
|
// log.Printf(" - Disk I/O: %s", diskIO)
|
|
|
|
_ = serverID
|
|
return cpuUsage, ramUsage, diskUsage, networkUsage, cpuTemp, diskIO
|
|
} |