alerttonotify/server/server.go
2024-12-03 00:47:40 +01:00

92 lines
2.7 KiB
Go

package server
import (
"encoding/json"
"fmt"
"log/slog"
"net/http"
"strings"
"time"
"git.t-juice.club/torjus/alerttonotify/bus"
)
type Server struct {
logger *slog.Logger
nbus *bus.NotifyBus
http.Server
}
type Alert struct {
Status string `json:"status"`
Labels map[string]string `json:"labels"`
Annotations map[string]string `json:"annotations"`
StartsAt time.Time `json:"startsAt"`
EndsAt time.Time `json:"endsAt"`
GeneratorURL string `json:"generatorURL"`
Fingerprint string `json:"fingerprint"`
}
type AlertMessage struct {
Version string `json:"version"`
GroupKey string `json:"groupKey"`
TruncatedAlerts int `json:"truncatedAlerts"`
Status string `json:"status"`
Receiver string `json:"receiver"`
GroupLabels map[string]string `json:"groupLabels"`
CommonLabels map[string]string `json:"commonLabels"`
CommonAnnotations map[string]string `json:"commonAnnotations"`
ExternalURL string `json:"externalURL"`
Alerts []Alert `json:"alerts"`
}
func NewServer(nbus *bus.NotifyBus, logger *slog.Logger) *Server {
srv := &Server{
nbus: nbus,
logger: logger,
}
mux := http.NewServeMux()
mux.HandleFunc("GET /", srv.handleIndex)
mux.HandleFunc("POST /alert", srv.handleAlert)
srv.Handler = mux
return srv
}
func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) {
s.logger.Info("index page")
w.Write([]byte("Hello!"))
}
func (s *Server) handleAlert(w http.ResponseWriter, r *http.Request) {
s.logger.Debug("Got new alert", "remoteAddr", r.RemoteAddr)
decoder := json.NewDecoder(r.Body)
var alertMessage AlertMessage
if err := decoder.Decode(&alertMessage); err != nil {
s.logger.Error("Failed to decode alert message", "error", err)
w.WriteHeader(http.StatusBadRequest)
return
}
s.logger.Debug("Decoded alert message", "alert", alertMessage)
s.logger.Info("Incoming message", "status", alertMessage.Status)
var sb strings.Builder
for _, alert := range alertMessage.Alerts {
s.logger.Debug("Incoming alert", "status", alert.Status, "fingerprint", alert.Fingerprint)
if summary, ok := alert.Annotations["summary"]; ok {
sb.WriteString(fmt.Sprintf("[%s] %s\n", strings.ToUpper(alert.Status), summary))
} else {
sb.WriteString(fmt.Sprintf("[%s]: %s\n", strings.ToUpper(alert.Status), alert.Fingerprint))
}
}
notification := bus.BusNotification{
Summary: fmt.Sprintf("%d alerts %s", len(alertMessage.Alerts), alertMessage.Status),
Body: sb.String(),
}
s.logger.Debug("Sending notification", "notification", notification)
s.nbus.Notify(notification)
}