mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 04:59:02 +08:00
fix(alertmanager): fix templating (#7288)
### Summary - Fix templating of alertmanagerURL to include links to our alerts page - Return an empty array instead of null in contextlinks
This commit is contained in:
parent
5dba1f3dbb
commit
06be0f4330
@ -218,7 +218,7 @@ func (server *Server) SetConfig(ctx context.Context, alertmanagerConfig *alertma
|
|||||||
config := alertmanagerConfig.AlertmanagerConfig()
|
config := alertmanagerConfig.AlertmanagerConfig()
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
server.tmpl, err = template.FromGlobs(config.Templates)
|
server.tmpl, err = alertmanagertypes.FromGlobs(config.Templates)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ func PrepareLinksToLogs(start, end time.Time, filterItems []v3.FilterItem) strin
|
|||||||
// i.e Severity text = WARN
|
// i.e Severity text = WARN
|
||||||
// If the Severity text is not part of the group by clause, then we add it as it is
|
// If the Severity text is not part of the group by clause, then we add it as it is
|
||||||
func PrepareFilters(labels map[string]string, whereClauseItems []v3.FilterItem, groupByItems []v3.AttributeKey, keys map[string]v3.AttributeKey) []v3.FilterItem {
|
func PrepareFilters(labels map[string]string, whereClauseItems []v3.FilterItem, groupByItems []v3.AttributeKey, keys map[string]v3.AttributeKey) []v3.FilterItem {
|
||||||
var filterItems []v3.FilterItem
|
filterItems := make([]v3.FilterItem, 0)
|
||||||
|
|
||||||
added := make(map[string]struct{})
|
added := make(map[string]struct{})
|
||||||
|
|
||||||
|
28
pkg/types/alertmanagertypes/template.go
Normal file
28
pkg/types/alertmanagertypes/template.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package alertmanagertypes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
alertmanagertemplate "github.com/prometheus/alertmanager/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FromGlobs overrides the default alertmanager template to add a ruleIdPath template.
|
||||||
|
// This is used to generate a link to the rule in the alertmanager.
|
||||||
|
//
|
||||||
|
// It explicitly checks for a ruleId that is a number and then generates a path to the rule.
|
||||||
|
func FromGlobs(paths []string) (*alertmanagertemplate.Template, error) {
|
||||||
|
t, err := alertmanagertemplate.FromGlobs(paths)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := t.Parse(bytes.NewReader([]byte(`
|
||||||
|
{{ define "__ruleIdPath" }}{{ range .CommonLabels.SortedPairs }}{{ if eq .Name "ruleId" }}{{ if match "^[0-9]+$" .Value }}/edit?ruleId={{ .Value | urlquery }}{{ end }}{{ end }}{{ end }}{{ end }}
|
||||||
|
{{ define "__alertmanagerURL" }}{{ .ExternalURL }}/alerts{{ template "__ruleIdPath" . }}{{ end }}
|
||||||
|
`))); err != nil {
|
||||||
|
return nil, fmt.Errorf("error parsing alertmanager templates: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, nil
|
||||||
|
}
|
141
pkg/types/alertmanagertypes/template_test.go
Normal file
141
pkg/types/alertmanagertypes/template_test.go
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
package alertmanagertypes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/prometheus/alertmanager/types"
|
||||||
|
"github.com/prometheus/common/model"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFromGlobs(t *testing.T) {
|
||||||
|
template, err := FromGlobs([]string{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
template.ExternalURL = &url.URL{Scheme: "http", Host: "localhost:8080", Path: ""}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
alerts []*types.Alert
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "SingleAlertWithValidRuleId",
|
||||||
|
alerts: []*types.Alert{
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"ruleId": "439453587",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Timeout: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: "http://localhost:8080/alerts/edit?ruleId=439453587",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SingleAlertWithInvalidRuleId",
|
||||||
|
alerts: []*types.Alert{
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"ruleId": "43textabc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Timeout: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: "http://localhost:8080/alerts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MultipleAlertsWithMismatchingRuleId",
|
||||||
|
alerts: []*types.Alert{
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"ruleId": "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Timeout: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"ruleId": "2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Timeout: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: "http://localhost:8080/alerts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MultipleAlertsWithMatchingRuleId",
|
||||||
|
alerts: []*types.Alert{
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"ruleId": "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Timeout: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"ruleId": "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Timeout: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: "http://localhost:8080/alerts/edit?ruleId=1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MultipleAlertsWithNoRuleId",
|
||||||
|
alerts: []*types.Alert{
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"label1": "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Timeout: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"label2": "2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
Timeout: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: "http://localhost:8080/alerts",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
data := template.Data("__receiver", model.LabelSet{}, tc.alerts...)
|
||||||
|
|
||||||
|
url, err := template.ExecuteTextString(`{{ template "__alertmanagerURL" . }}`, data)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, tc.expected, url)
|
||||||
|
|
||||||
|
url, err = template.ExecuteHTMLString(`{{ template "__alertmanagerURL" . }}`, data)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, tc.expected, url)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user