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 (
|
const (
|
||||||
HandlerFlux HandlerType = iota + 1
|
HandlerFlux HandlerType = iota + 1
|
||||||
HandlerDiscordEmbed
|
HandlerDiscordEmbed
|
||||||
|
HandlerAlertmanager
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h HandlerType) String() string {
|
func (h HandlerType) String() string {
|
||||||
|
@ -20,6 +21,8 @@ func (h HandlerType) String() string {
|
||||||
return "flux"
|
return "flux"
|
||||||
case HandlerDiscordEmbed:
|
case HandlerDiscordEmbed:
|
||||||
return "discord_embed"
|
return "discord_embed"
|
||||||
|
case HandlerAlertmanager:
|
||||||
|
return "alertmanager"
|
||||||
}
|
}
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
@ -153,6 +156,8 @@ func readHandlerType(d *scfg.Directive) (HandlerType, error) {
|
||||||
return HandlerFlux, nil
|
return HandlerFlux, nil
|
||||||
case "discord_embed":
|
case "discord_embed":
|
||||||
return HandlerDiscordEmbed, nil
|
return HandlerDiscordEmbed, nil
|
||||||
|
case "alertmanager":
|
||||||
|
return HandlerAlertmanager, nil
|
||||||
default:
|
default:
|
||||||
return 0, fmt.Errorf("invalid handler type %q", ty)
|
return 0, fmt.Errorf("invalid handler type %q", ty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,11 @@ data:
|
||||||
type "discord_embed"
|
type "discord_embed"
|
||||||
topic "forgejo"
|
topic "forgejo"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handler "/alerts" {
|
||||||
|
type "alertmanager"
|
||||||
|
topic "infra"
|
||||||
|
}
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
|
|
2
main.go
2
main.go
|
@ -76,6 +76,8 @@ func main() {
|
||||||
h = bridge.NewFluxHandler()
|
h = bridge.NewFluxHandler()
|
||||||
case config.HandlerDiscordEmbed:
|
case config.HandlerDiscordEmbed:
|
||||||
h = bridge.NewDiscordEmbedHandler()
|
h = bridge.NewDiscordEmbedHandler()
|
||||||
|
case config.HandlerAlertmanager:
|
||||||
|
h = bridge.NewAlertmanagerHandler()
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Debug("Registering bridge", "route", route, "handler", handler.Type)
|
slog.Debug("Registering bridge", "route", route, "handler", handler.Type)
|
||||||
|
|
Loading…
Reference in a new issue