OnConnect resolves any active host_down alert for the host when an agent reconnects. Called by the agent WebSocket connect handler.
(ctx context.Context, d *database.DB, apiID string, tenantHost string, emit *notifications.Emitter, log *slog.Logger)
| 205 | // OnConnect resolves any active host_down alert for the host when an agent reconnects. |
| 206 | // Called by the agent WebSocket connect handler. |
| 207 | func OnConnect(ctx context.Context, d *database.DB, apiID string, tenantHost string, emit *notifications.Emitter, log *slog.Logger) { |
| 208 | enabled, err := IsAlertsEnabled(ctx, d) |
| 209 | if err != nil || !enabled { |
| 210 | return |
| 211 | } |
| 212 | |
| 213 | host, err := d.Queries.GetHostByApiID(ctx, apiID) |
| 214 | if err != nil { |
| 215 | return |
| 216 | } |
| 217 | |
| 218 | // Resolve any active host_down alert for this host. |
| 219 | hadAlert := false |
| 220 | activeAlerts, _ := d.Queries.ListActiveAlertsByType(ctx, "host_down") |
| 221 | alertsStore := store.NewAlertsStore(d) |
| 222 | for _, a := range activeAlerts { |
| 223 | var meta map[string]interface{} |
| 224 | if len(a.Metadata) > 0 { |
| 225 | _ = json.Unmarshal(a.Metadata, &meta) |
| 226 | } |
| 227 | if meta != nil { |
| 228 | if hid, ok := meta["host_id"].(string); ok && hid == host.ID { |
| 229 | hadAlert = true |
| 230 | if err := alertsStore.UpdateResolved(ctx, a.ID, nil); err != nil { |
| 231 | log.Debug("host_down: failed to resolve alert on connect", "api_id", apiID, "alert_id", a.ID, "error", err) |
| 232 | } else { |
| 233 | _ = alertsStore.RecordHistory(ctx, a.ID, nil, "resolved", map[string]interface{}{ |
| 234 | "resolved_reason": "Host reconnected via WebSocket", |
| 235 | "system_action": true, |
| 236 | }) |
| 237 | log.Info("host_down: resolved alert on connect", "api_id", apiID, "host_id", host.ID, "alert_id", a.ID) |
| 238 | } |
| 239 | break |
| 240 | } |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | // Emit host_recovered when resolving an active host_down alert (recovery from tracked down state). |
| 245 | // If host_down is disabled, emit as a standalone "host up" signal on WebSocket connect. |
| 246 | if emit != nil { |
| 247 | hn := hostDisplayNameFromRow(host) |
| 248 | if hadAlert { |
| 249 | emit.EmitEvent(ctx, d, tenantHost, notifications.Event{ |
| 250 | Type: "host_recovered", |
| 251 | Severity: ResolveSeverity(ctx, d, "host_recovered", "informational"), |
| 252 | Title: "Host reconnected", |
| 253 | Message: fmt.Sprintf("Host %s WebSocket reconnected.", hn), |
| 254 | ReferenceType: "host", |
| 255 | ReferenceID: host.ID, |
| 256 | Metadata: map[string]interface{}{"host_id": host.ID, "host_name": hn}, |
| 257 | }) |
| 258 | } else { |
| 259 | // host_down is disabled or no alert existed — emit host_recovered |
| 260 | // as a standalone "host up" notification if that event type is enabled. |
| 261 | cfg, _ := GetConfigForType(ctx, d, "host_recovered") |
| 262 | if cfg != nil && cfg.IsEnabled { |
| 263 | emit.EmitEvent(ctx, d, tenantHost, notifications.Event{ |
| 264 | Type: "host_recovered", |
nothing calls this directly
no test coverage detected