feat: add alertmanager handler
This commit is contained in:
parent
1bc747c18b
commit
773555491a
4 changed files with 82 additions and 0 deletions
70
bridge/alertmanager.go
Normal file
70
bridge/alertmanager.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package bridge
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AlertmanagerEvent struct {
|
||||
Receiver string `json:"receiver"`
|
||||
Status string `json:"status"`
|
||||
Alerts []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"`
|
||||
} `json:"alerts"`
|
||||
GroupLabels map[string]string `json:"groupLabels"`
|
||||
CommonLabels map[string]string `json:"commonLabels"`
|
||||
CommonAnnotations map[string]string `json:"commonAnnotations"`
|
||||
ExternalURL string `json:"externalURL"`
|
||||
Version string `json:"version"`
|
||||
GroupKey string `json:"groupKey"`
|
||||
TruncatedAlerts int `json:"truncatedAlerts"`
|
||||
}
|
||||
|
||||
type AlertmanagerHandler struct{}
|
||||
|
||||
func NewAlertmanagerHandler() AlertmanagerHandler {
|
||||
return AlertmanagerHandler{}
|
||||
}
|
||||
|
||||
func (d AlertmanagerHandler) ProduceNotifications(r *http.Request) ([]Notification, error) {
|
||||
l := slog.With(slog.String("handler", "alertmanager"))
|
||||
|
||||
dec := json.NewDecoder(r.Body)
|
||||
defer r.Body.Close()
|
||||
|
||||
var event AlertmanagerEvent
|
||||
if err := dec.Decode(&event); err != nil {
|
||||
l.Error("invalid message format", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
notifications := make([]Notification, 0, len(event.Alerts))
|
||||
for _, alert := range event.Alerts {
|
||||
if alert.Annotations["summary"] == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
var not Notification
|
||||
not.Title = "[" + strings.ToUpper(event.Status) + "] " + alert.Annotations["summary"]
|
||||
not.Body = alert.Annotations["description"]
|
||||
if runbook := alert.Annotations["runbook_url"]; runbook != "" {
|
||||
not.Actions = append(not.Actions, NewViewAction("Runbook", runbook))
|
||||
}
|
||||
if event.Status == "resolved" {
|
||||
not.Tags = []string{"resolved"}
|
||||
}
|
||||
|
||||
notifications = append(notifications, not)
|
||||
}
|
||||
|
||||
return notifications, nil
|
||||
}
|
|
@ -12,6 +12,7 @@ type HandlerType int
|
|||
const (
|
||||
HandlerFlux HandlerType = iota + 1
|
||||
HandlerDiscordEmbed
|
||||
HandlerAlertmanager
|
||||
)
|
||||
|
||||
func (h HandlerType) String() string {
|
||||
|
@ -20,6 +21,8 @@ func (h HandlerType) String() string {
|
|||
return "flux"
|
||||
case HandlerDiscordEmbed:
|
||||
return "discord_embed"
|
||||
case HandlerAlertmanager:
|
||||
return "alertmanager"
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
@ -153,6 +156,8 @@ func readHandlerType(d *scfg.Directive) (HandlerType, error) {
|
|||
return HandlerFlux, nil
|
||||
case "discord_embed":
|
||||
return HandlerDiscordEmbed, nil
|
||||
case "alertmanager":
|
||||
return HandlerAlertmanager, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid handler type %q", ty)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@ data:
|
|||
type "discord_embed"
|
||||
topic "forgejo"
|
||||
}
|
||||
|
||||
handler "/alerts" {
|
||||
type "alertmanager"
|
||||
topic "infra"
|
||||
}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
|
|
2
main.go
2
main.go
|
@ -76,6 +76,8 @@ func main() {
|
|||
h = bridge.NewFluxHandler()
|
||||
case config.HandlerDiscordEmbed:
|
||||
h = bridge.NewDiscordEmbedHandler()
|
||||
case config.HandlerAlertmanager:
|
||||
h = bridge.NewAlertmanagerHandler()
|
||||
}
|
||||
|
||||
slog.Debug("Registering bridge", "route", route, "handler", handler.Type)
|
||||
|
|
Loading…
Reference in a new issue