diff --git a/Dashboard/Services/EmailAlertService.cs b/Dashboard/Services/EmailAlertService.cs index cd96afab..7b1afd84 100644 --- a/Dashboard/Services/EmailAlertService.cs +++ b/Dashboard/Services/EmailAlertService.cs @@ -79,9 +79,6 @@ public async Task TrySendAlertEmailAsync( try { var prefs = _preferencesService.GetPreferences(); - string? sendError = null; - bool sent = false; - string notificationType = "tray"; /* Attempt email delivery if SMTP is fully configured */ if (prefs.SmtpEnabled && @@ -95,7 +92,8 @@ public async Task TrySendAlertEmailAsync( if (!withinCooldown) { - notificationType = "email"; + bool sent = false; + string? sendError = null; var subject = $"[SQL Monitor Alert] {metricName} on {serverName}"; var (htmlBody, plainTextBody) = EmailTemplateBuilder.BuildAlertEmail( metricName, serverName, currentValue, thresholdValue, prefs.EmailCooldownMinutes, context); @@ -130,18 +128,21 @@ public async Task TrySendAlertEmailAsync( Logger.Error($"ALERT EMAIL STILL FAILING: {_consecutiveFailures} consecutive failures. Last error: {ex.Message}"); } } + + RecordAlert(serverId, serverName, metricName, currentValue, thresholdValue, sent, "email", sendError); } } - /* Log the alert attempt */ - RecordAlert(serverId, serverName, metricName, currentValue, thresholdValue, sent, notificationType, sendError); - /* Send webhook notifications (Teams / Slack) — independent of email */ var webhookService = WebhookAlertService.Current; if (webhookService != null) { - await webhookService.TrySendWebhookAlertsAsync( + var webhookSent = await webhookService.TrySendWebhookAlertsAsync( metricName, serverName, currentValue, thresholdValue, serverId, context); + if (webhookSent) + { + RecordAlert(serverId, serverName, metricName, currentValue, thresholdValue, true, "webhook"); + } } } catch (Exception ex) diff --git a/Dashboard/Services/WebhookAlertService.cs b/Dashboard/Services/WebhookAlertService.cs index d6340cfb..f9cb68b2 100644 --- a/Dashboard/Services/WebhookAlertService.cs +++ b/Dashboard/Services/WebhookAlertService.cs @@ -46,7 +46,7 @@ public WebhookAlertService(UserPreferencesService preferencesService) /// Sends webhook alerts to all configured channels (Teams and/or Slack). /// Respects the email cooldown setting for throttling. Never throws. /// - public async Task TrySendWebhookAlertsAsync( + public async Task TrySendWebhookAlertsAsync( string metricName, string serverName, string currentValue, @@ -62,7 +62,7 @@ public async Task TrySendWebhookAlertsAsync( if (_cooldowns.TryGetValue(cooldownKey, out var lastSent) && DateTime.UtcNow - lastSent < TimeSpan.FromMinutes(prefs.EmailCooldownMinutes)) { - return; + return false; } bool sent = false; @@ -81,10 +81,13 @@ public async Task TrySendWebhookAlertsAsync( { _cooldowns[cooldownKey] = DateTime.UtcNow; } + + return sent; } catch (Exception ex) { Logger.Error($"TrySendWebhookAlertsAsync outer error: {ex.Message}"); + return false; } } diff --git a/Lite/Services/EmailAlertService.cs b/Lite/Services/EmailAlertService.cs index b22da7fe..c895b9f8 100644 --- a/Lite/Services/EmailAlertService.cs +++ b/Lite/Services/EmailAlertService.cs @@ -112,12 +112,20 @@ public async Task TrySendAlertEmailAsync( } /* Send webhook notifications (Teams / Slack) alongside email */ + bool webhookSent = false; if (!muted) { - await _webhookAlertService.TrySendWebhookAlertsAsync( + webhookSent = await _webhookAlertService.TrySendWebhookAlertsAsync( metricName, serverName, currentValue, thresholdValue, serverId, context); } + /* Reflect webhook delivery in notification type */ + if (webhookSent) + { + notificationType = notificationType == "email" ? "email+webhook" : "webhook"; + sent = true; + } + /* Always log the alert to DuckDB, regardless of email status */ var logCurrent = numericCurrentValue ?? (double.TryParse(currentValue.TrimEnd('%'), out var cv) ? cv : 0); diff --git a/Lite/Services/WebhookAlertService.cs b/Lite/Services/WebhookAlertService.cs index afc2d35e..7e54ea58 100644 --- a/Lite/Services/WebhookAlertService.cs +++ b/Lite/Services/WebhookAlertService.cs @@ -37,7 +37,7 @@ public class WebhookAlertService /// Sends webhook alerts to all configured channels (Teams and/or Slack). /// Respects the email cooldown setting for throttling. Never throws. /// - public async Task TrySendWebhookAlertsAsync( + public async Task TrySendWebhookAlertsAsync( string metricName, string serverName, string currentValue, @@ -51,7 +51,7 @@ public async Task TrySendWebhookAlertsAsync( if (_cooldowns.TryGetValue(cooldownKey, out var lastSent) && DateTime.UtcNow - lastSent < TimeSpan.FromMinutes(App.EmailCooldownMinutes)) { - return; + return false; } bool sent = false; @@ -70,10 +70,13 @@ public async Task TrySendWebhookAlertsAsync( { _cooldowns[cooldownKey] = DateTime.UtcNow; } + + return sent; } catch (Exception ex) { AppLogger.Error("Webhook", $"TrySendWebhookAlertsAsync outer error: {ex.Message}"); + return false; } }