feat: Implement comprehensive multi-channel notification system with templating and SSL monitoring
- 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.
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user