- Status wird aus last_heartbeat berechnet (online/stale/offline/unknown)
- GET /agents und GET /agents/{id} liefern status Feld
- agent_events Tabelle fuer Event-Tracking (Migration automatisch)
- Inaktivitaets-Monitor als Goroutine (prueft alle 60s, schreibt Events bei Statuswechsel)
- WebSocket Connect/Disconnect Events werden automatisch geschrieben
- API-Endpoints: GET /agents/events und GET /agents/{id}/events (?limit=N&type=X)
- DB-Methoden: InsertAgentEvent, GetAgentEvents, GetAllAgentEvents, GetAgentStatus
- README aktualisiert (Status-Doku, Events API, Dateistruktur)
78 lines
1.8 KiB
Go
78 lines
1.8 KiB
Go
package monitor
|
|
|
|
import (
|
|
"log"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/cynfo/rmm-backend/db"
|
|
"github.com/cynfo/rmm-backend/models"
|
|
)
|
|
|
|
// Monitor prueft periodisch den Agent-Status und schreibt Events bei Statuswechsel
|
|
type Monitor struct {
|
|
db *db.Database
|
|
lastStatus map[string]string
|
|
lastStatusMu sync.Mutex
|
|
interval time.Duration
|
|
}
|
|
|
|
// New erstellt einen neuen Monitor
|
|
func New(database *db.Database) *Monitor {
|
|
return &Monitor{
|
|
db: database,
|
|
lastStatus: make(map[string]string),
|
|
interval: 60 * time.Second,
|
|
}
|
|
}
|
|
|
|
// Run startet den Monitor als Goroutine — blockiert, also mit go aufrufen
|
|
func (m *Monitor) Run() {
|
|
log.Println("Inaktivitaets-Monitor gestartet (Intervall: 60s)")
|
|
|
|
// Initialen Status laden
|
|
m.checkAgents()
|
|
|
|
ticker := time.NewTicker(m.interval)
|
|
defer ticker.Stop()
|
|
|
|
for range ticker.C {
|
|
m.checkAgents()
|
|
}
|
|
}
|
|
|
|
func (m *Monitor) checkAgents() {
|
|
agents, err := m.db.GetAgents()
|
|
if err != nil {
|
|
log.Printf("Monitor: Fehler beim Laden der Agents: %v", err)
|
|
return
|
|
}
|
|
|
|
m.lastStatusMu.Lock()
|
|
defer m.lastStatusMu.Unlock()
|
|
|
|
for _, agent := range agents {
|
|
newStatus := models.CalculateAgentStatus(agent.LastHeartbeat)
|
|
oldStatus, known := m.lastStatus[agent.ID]
|
|
|
|
if !known {
|
|
// Erster Check — Status merken, kein Event
|
|
m.lastStatus[agent.ID] = newStatus
|
|
log.Printf("Monitor: Agent %s (%s) initialer Status: %s", agent.Name, agent.ID, newStatus)
|
|
continue
|
|
}
|
|
|
|
if oldStatus == newStatus {
|
|
continue
|
|
}
|
|
|
|
// Statuswechsel erkannt
|
|
log.Printf("Monitor: Agent %s (%s) Status-Wechsel: %s -> %s", agent.Name, agent.ID, oldStatus, newStatus)
|
|
m.lastStatus[agent.ID] = newStatus
|
|
|
|
// Event schreiben
|
|
message := "Status-Wechsel: " + oldStatus + " -> " + newStatus
|
|
m.db.InsertAgentEvent(agent.ID, newStatus, message)
|
|
}
|
|
}
|