Agent-Status und Inaktivitaets-Erkennung implementiert
- 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)
This commit is contained in:
+56
-1
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -28,7 +29,9 @@ func (h *Handler) SetupRoutes(mux *http.ServeMux, hub *ws.Hub) {
|
||||
mux.HandleFunc("POST /api/v1/agent/register", h.registerAgent)
|
||||
mux.HandleFunc("POST /api/v1/agent/heartbeat", h.heartbeat)
|
||||
mux.HandleFunc("GET /api/v1/agents", h.listAgents)
|
||||
mux.HandleFunc("GET /api/v1/agents/events", h.getAllAgentEvents)
|
||||
mux.HandleFunc("GET /api/v1/agents/{id}", h.getAgent)
|
||||
mux.HandleFunc("GET /api/v1/agents/{id}/events", h.getAgentEvents)
|
||||
mux.HandleFunc("GET /api/v1/agents/{id}/system", h.getSystemData)
|
||||
mux.HandleFunc("DELETE /api/v1/agents/{id}", h.deleteAgent)
|
||||
|
||||
@@ -151,7 +154,19 @@ func (h *Handler) listAgents(w http.ResponseWriter, r *http.Request) {
|
||||
if agents == nil {
|
||||
agents = []models.Agent{}
|
||||
}
|
||||
writeJSON(w, http.StatusOK, agents)
|
||||
|
||||
// Status fuer jeden Agent berechnen
|
||||
var response []models.AgentResponse
|
||||
for _, a := range agents {
|
||||
response = append(response, models.AgentResponse{
|
||||
Agent: a,
|
||||
Status: models.CalculateAgentStatus(a.LastHeartbeat),
|
||||
})
|
||||
}
|
||||
if response == nil {
|
||||
response = []models.AgentResponse{}
|
||||
}
|
||||
writeJSON(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
// GET /api/v1/agents/{id}
|
||||
@@ -170,6 +185,7 @@ func (h *Handler) getAgent(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
result := map[string]interface{}{
|
||||
"agent": agent,
|
||||
"status": models.CalculateAgentStatus(agent.LastHeartbeat),
|
||||
"system_data": sysData,
|
||||
}
|
||||
writeJSON(w, http.StatusOK, result)
|
||||
@@ -207,3 +223,42 @@ func (h *Handler) deleteAgent(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("Agent geloescht: %s", id)
|
||||
writeJSON(w, http.StatusOK, map[string]string{"message": "Agent geloescht"})
|
||||
}
|
||||
|
||||
// GET /api/v1/agents/{id}/events
|
||||
func (h *Handler) getAgentEvents(w http.ResponseWriter, r *http.Request) {
|
||||
agentID := r.PathValue("id")
|
||||
eventType := r.URL.Query().Get("type")
|
||||
limit := 100
|
||||
if l := r.URL.Query().Get("limit"); l != "" {
|
||||
if n, err := strconv.Atoi(l); err == nil && n > 0 {
|
||||
limit = n
|
||||
}
|
||||
}
|
||||
|
||||
events, err := h.db.GetAgentEvents(agentID, eventType, limit)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Laden der Events: %v", err)
|
||||
writeError(w, http.StatusInternalServerError, "Fehler beim Laden")
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, events)
|
||||
}
|
||||
|
||||
// GET /api/v1/agents/events
|
||||
func (h *Handler) getAllAgentEvents(w http.ResponseWriter, r *http.Request) {
|
||||
eventType := r.URL.Query().Get("type")
|
||||
limit := 100
|
||||
if l := r.URL.Query().Get("limit"); l != "" {
|
||||
if n, err := strconv.Atoi(l); err == nil && n > 0 {
|
||||
limit = n
|
||||
}
|
||||
}
|
||||
|
||||
events, err := h.db.GetAllAgentEvents(eventType, limit)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Laden der Events: %v", err)
|
||||
writeError(w, http.StatusInternalServerError, "Fehler beim Laden")
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, events)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user