mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-09 16:00:59 +00:00
wire PDM alert bridge into PatrolService and seed demo
This commit is contained in:
parent
b9844f22c1
commit
99d0edb04a
4 changed files with 40 additions and 2 deletions
|
|
@ -159,6 +159,23 @@ func (p *PatrolService) InjectDemoFindings() {
|
|||
TimesRaised: 2,
|
||||
Source: updateSafetySource,
|
||||
},
|
||||
{
|
||||
ID: "demo-pdm-alert-node-offline",
|
||||
Key: PDMAlertFindingPrefix + ":datacenter-a/node/pve-edge-01",
|
||||
Severity: FindingSeverityWarning,
|
||||
Category: FindingCategoryReliability,
|
||||
Title: "PDM: node \"pve-edge-01\" is offline",
|
||||
Description: "Proxmox Datacenter Manager reports node \"pve-edge-01\" in remote \"datacenter-a\" is offline.",
|
||||
ResourceID: "datacenter-a/node/pve-edge-01",
|
||||
ResourceName: "pve-edge-01",
|
||||
ResourceType: "node",
|
||||
Node: "datacenter-a",
|
||||
Evidence: "status=offline remote=datacenter-a",
|
||||
DetectedAt: now.Add(-8 * time.Minute),
|
||||
LastSeenAt: now.Add(-2 * time.Minute),
|
||||
TimesRaised: 1,
|
||||
Source: pdmAlertSourceLabel,
|
||||
},
|
||||
}
|
||||
|
||||
// Add findings to the store
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ func TestPatrolService_InjectDemoFindings(t *testing.T) {
|
|||
service.InjectDemoFindings()
|
||||
|
||||
findings := service.findings.GetAll(nil)
|
||||
if len(findings) != 6 {
|
||||
t.Fatalf("expected 6 demo findings, got %d", len(findings))
|
||||
if len(findings) != 7 {
|
||||
t.Fatalf("expected 7 demo findings, got %d", len(findings))
|
||||
}
|
||||
if service.runHistoryStore.Count() != 13 {
|
||||
t.Fatalf("expected 13 demo run history entries, got %d", service.runHistoryStore.Count())
|
||||
|
|
|
|||
|
|
@ -464,6 +464,11 @@ type PatrolService struct {
|
|||
// lifetime; in-memory only, no goroutine.
|
||||
stormThrottler *findingStormThrottler
|
||||
updateSafetyWatcher *UpdateSafetyWatcher
|
||||
// PDM alert bridge -- polls the PDM resource list on each patrol cycle
|
||||
// and emits reliability findings for offline nodes and failed guests.
|
||||
// Nil source at MVP makes Observe a no-op; the real HTTP client is a
|
||||
// follow-on.
|
||||
pdmAlertBridge *pdmAlertBridge
|
||||
// ReadState provides typed read-only views over resource state (VMs, nodes, hosts, etc.).
|
||||
// This is injected separately from stateProvider since stateProvider also contains
|
||||
// non-resource telemetry (alerts, backups, connection health) that isn't modeled as resources yet.
|
||||
|
|
@ -687,5 +692,6 @@ func NewPatrolService(aiService *Service, stateProvider StateProvider) *PatrolSe
|
|||
p.stormThrottler = newFindingStormThrottler()
|
||||
p.findings.SetStormThrottler(p.stormThrottler)
|
||||
p.updateSafetyWatcher = newUpdateSafetyWatcher()
|
||||
p.pdmAlertBridge = newPDMAlertBridge(nil)
|
||||
return p
|
||||
}
|
||||
|
|
|
|||
|
|
@ -423,6 +423,21 @@ func (p *PatrolService) runPatrolWithTrigger(ctx context.Context, trigger Trigge
|
|||
}
|
||||
}
|
||||
|
||||
// Run PDM alert bridge on every patrol cycle if a source is configured.
|
||||
// Nil source guard mirrors the MVP no-op behavior; the real HTTP client
|
||||
// is wired in a follow-on. Direct FindingsStore.Add bypasses push.
|
||||
if p.pdmAlertBridge != nil && p.pdmAlertBridge.source != nil {
|
||||
pdmEmit, pdmResolve := p.pdmAlertBridge.Observe(ctx, time.Now())
|
||||
for _, f := range pdmEmit {
|
||||
if !p.findings.Add(f) {
|
||||
log.Debug().Str("finding_id", f.ID).Msg("AI Patrol: PDM alert finding already in store")
|
||||
}
|
||||
}
|
||||
for _, s := range pdmResolve {
|
||||
p.findings.ResolveWithReason(s.DedupKey, s.Reason)
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if we can run LLM analysis (requires AI service + circuit breaker not open)
|
||||
aiServiceEnabled := p.aiService != nil && p.aiService.IsEnabled()
|
||||
canRunLLM := aiServiceEnabled && llmAllowed
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue