Add agent operations history and manual links
This commit is contained in:
110
service_links.go
Normal file
110
service_links.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ServiceLink struct {
|
||||
ServiceID int64 `json:"serviceId"`
|
||||
AgentID string `json:"agentId"`
|
||||
VMID int `json:"vmid"`
|
||||
ComponentType string `json:"componentType"`
|
||||
ComponentName string `json:"componentName"`
|
||||
Port int `json:"port"`
|
||||
}
|
||||
|
||||
func (s *Store) ServiceLinks() ([]ServiceLink, error) {
|
||||
rows, err := s.db.Query(`SELECT service_id,agent_id,vmid,component_type,component_name,port FROM service_links ORDER BY service_id`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var out []ServiceLink
|
||||
for rows.Next() {
|
||||
var v ServiceLink
|
||||
if err = rows.Scan(&v.ServiceID, &v.AgentID, &v.VMID, &v.ComponentType, &v.ComponentName, &v.Port); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, v)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) SaveServiceLink(v ServiceLink) (ServiceLink, error) {
|
||||
v.AgentID = strings.TrimSpace(v.AgentID)
|
||||
v.ComponentType = strings.TrimSpace(v.ComponentType)
|
||||
v.ComponentName = strings.TrimSpace(v.ComponentName)
|
||||
if v.ServiceID <= 0 {
|
||||
return v, fmt.Errorf("выберите сервис")
|
||||
}
|
||||
if v.AgentID == "" && v.VMID <= 0 {
|
||||
return v, fmt.Errorf("выберите агент или VMID")
|
||||
}
|
||||
if v.ComponentType != "" && v.ComponentType != "systemd" && v.ComponentType != "docker" && v.ComponentType != "process" {
|
||||
return v, fmt.Errorf("неизвестный тип компонента")
|
||||
}
|
||||
if v.Port < 0 || v.Port > 65535 {
|
||||
return v, fmt.Errorf("некорректный порт")
|
||||
}
|
||||
_, err := s.db.Exec(`INSERT INTO service_links(service_id,agent_id,vmid,component_type,component_name,port) VALUES(?,?,?,?,?,?) ON CONFLICT(service_id) DO UPDATE SET agent_id=excluded.agent_id,vmid=excluded.vmid,component_type=excluded.component_type,component_name=excluded.component_name,port=excluded.port`, v.ServiceID, v.AgentID, v.VMID, v.ComponentType, v.ComponentName, v.Port)
|
||||
return v, err
|
||||
}
|
||||
func (s *Store) DeleteServiceLink(serviceID int64) error {
|
||||
_, err := s.db.Exec(`DELETE FROM service_links WHERE service_id=?`, serviceID)
|
||||
return err
|
||||
}
|
||||
|
||||
func groupLinkedAlerts(metrics dashboardMetrics, alerts []Alert) []Alert {
|
||||
if len(metrics.ServiceLinks) == 0 {
|
||||
return alerts
|
||||
}
|
||||
agentOffline := map[string]ManagedAgent{}
|
||||
for _, agent := range metrics.Agents {
|
||||
if !agent.Online {
|
||||
agentOffline[agent.ID] = agent
|
||||
}
|
||||
}
|
||||
affected := map[string][]string{}
|
||||
remove := map[string]bool{}
|
||||
for _, link := range metrics.ServiceLinks {
|
||||
agent, offline := agentOffline[link.AgentID]
|
||||
if !offline {
|
||||
continue
|
||||
}
|
||||
for _, service := range metrics.Services.Services {
|
||||
if service.ID != link.ServiceID {
|
||||
continue
|
||||
}
|
||||
for _, endpoint := range service.Endpoints {
|
||||
if !endpoint.Up {
|
||||
key := fmt.Sprintf("service-%d-%s", service.ID, endpoint.Kind)
|
||||
remove[key] = true
|
||||
affected[agent.ID] = append(affected[agent.ID], service.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(affected) == 0 {
|
||||
return alerts
|
||||
}
|
||||
out := make([]Alert, 0, len(alerts))
|
||||
for _, alert := range alerts {
|
||||
skip := remove[alert.ID]
|
||||
for agentID := range affected {
|
||||
if alert.ID == "agent-offline-"+agentID+fmt.Sprintf("-%d", agentOffline[agentID].VMID) {
|
||||
skip = true
|
||||
}
|
||||
}
|
||||
if !skip {
|
||||
out = append(out, alert)
|
||||
}
|
||||
}
|
||||
for agentID, names := range affected {
|
||||
sort.Strings(names)
|
||||
agent := agentOffline[agentID]
|
||||
out = append(out, Alert{ID: "group-agent-offline-" + agentID + fmt.Sprintf("-%d", agent.VMID), Severity: "critical", Source: "Корреляция", Title: agent.Name + ": агент недоступен, связанные сервисы не отвечают", Message: fmt.Sprintf("VMID %d. Затронуто сервисов: %d — %s. Вероятная первопричина: недоступна гостевая система или агент.", agent.VMID, len(names), strings.Join(names, ", "))})
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user