mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Support values in notification templates (#56457)
We have received a lot of feedback regarding the ValueString in alert notifications. Perhaps one of the most frequent complaints about ValueString is that it is difficult to read because it contains a lot of information, and the information is shown as a JSON-like string. Users have often asked how it can be templated and the answer is that it can't. Until now users have been able to add custom annotations to their alert rules which contains values via the $values variable added in previous versions of Grafana. However, these custom annotations must be added for each of the user's alert rule, instead of once in a template that all of their alerts can be notified via. This commit adds then the much requested feature to support values in notification templates. Users can then create a single template that prints the annotations, labels and values of their alerts in a format of their choice!
This commit is contained in:
parent
62674604b4
commit
802d67eeca
@ -3,6 +3,10 @@
|
||||
|
||||
[[Subject .Subject "[[.Title]]"]]
|
||||
|
||||
[[ define "__text_values_list" ]][[ $len := len .Values ]][[ if $len ]][[ $first := gt $len 1 ]][[ range $refID, $value := .Values -]]
|
||||
[[ $refID ]]=[[ $value ]][[ if $first ]], [[ end ]][[ $first = false ]][[ end -]]
|
||||
[[ else ]][no value][[ end ]][[ end ]]
|
||||
|
||||
[[ define "alert" ]]
|
||||
|
||||
[[ if ne .ImageURL "" ]]
|
||||
@ -21,7 +25,7 @@
|
||||
[[ end ]]
|
||||
<tr>
|
||||
<td colspan="2" class="value">
|
||||
<span class="value-heading">Value:</span> <span class="value-value">[[ .ValueString ]]</span>
|
||||
<span class="value-heading">Value:</span> <span class="value-value">[[ template "__text_values_list" . ]]</span>
|
||||
</td>
|
||||
</tr>
|
||||
[[ if gt (len .Annotations.SortedPairs) 0 ]]
|
||||
|
@ -101,6 +101,9 @@ const (
|
||||
|
||||
// StateReasonAnnotation is the name of the annotation that explains the difference between evaluation state and alert state (i.e. changing state when NoData or Error).
|
||||
StateReasonAnnotation = GrafanaReservedLabelPrefix + "state_reason"
|
||||
|
||||
ValuesAnnotation = "__values__"
|
||||
ValueStringAnnotation = "__value_string__"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -16,8 +16,12 @@ const (
|
||||
var DefaultTemplateString = `
|
||||
{{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ if gt (.Alerts.Resolved | len) 0 }}, RESOLVED:{{ .Alerts.Resolved | len }}{{ end }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }}
|
||||
|
||||
{{ define "__text_values_list" }}{{ $len := len .Values }}{{ if $len }}{{ $first := gt $len 1 }}{{ range $refID, $value := .Values -}}
|
||||
{{ $refID }}={{ $value }}{{ if $first }}, {{ end }}{{ $first = false }}{{ end -}}
|
||||
{{ else }}[no value]{{ end }}{{ end }}
|
||||
|
||||
{{ define "__text_alert_list" }}{{ range . }}
|
||||
Value: {{ or .ValueString "[no value]" }}
|
||||
Value: {{ template "__text_values_list" . }}
|
||||
Labels:
|
||||
{{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }}
|
||||
{{ end }}Annotations:
|
||||
@ -38,7 +42,7 @@ Labels:
|
||||
|
||||
|
||||
{{ define "__teams_text_alert_list" }}{{ range . }}
|
||||
Value: {{ or .ValueString "[no value]" }}
|
||||
Value: {{ template "__text_values_list" . }}
|
||||
Labels:
|
||||
{{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }}
|
||||
{{ end }}
|
||||
@ -70,8 +74,12 @@ Annotations:
|
||||
const TemplateForTestsString = `
|
||||
{{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }}
|
||||
|
||||
{{ define "__text_values_list" }}{{ $len := len .Values }}{{ if $len }}{{ $first := gt $len 1 }}{{ range $refID, $value := .Values -}}
|
||||
{{ $refID }}={{ $value }}{{ if $first }}, {{ end }}{{ $first = false }}{{ end -}}
|
||||
{{ else }}[no value]{{ end }}{{ end }}
|
||||
|
||||
{{ define "__text_alert_list" }}{{ range . }}
|
||||
Value: {{ or .ValueString "[no value]" }}
|
||||
Value: {{ template "__text_values_list" . }}
|
||||
Labels:
|
||||
{{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }}
|
||||
{{ end }}Annotations:
|
||||
|
@ -20,7 +20,7 @@ func TestDefaultTemplateString(t *testing.T) {
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1"},
|
||||
Annotations: model.LabelSet{
|
||||
"ann1": "annv1", "__dashboardUid__": "dbuid123", "__panelId__": "puid123", "__value_string__": "1234",
|
||||
"ann1": "annv1", "__dashboardUid__": "dbuid123", "__panelId__": "puid123", "__values__": "{\"A\": 1234}", "__value_string__": "1234",
|
||||
},
|
||||
StartsAt: time.Now(),
|
||||
EndsAt: time.Now().Add(1 * time.Hour),
|
||||
@ -29,7 +29,7 @@ func TestDefaultTemplateString(t *testing.T) {
|
||||
}, { // Firing without dashboard and panel ID.
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val2"},
|
||||
Annotations: model.LabelSet{"ann1": "annv2", "__value_string__": "1234"},
|
||||
Annotations: model.LabelSet{"ann1": "annv2", "__values__": "{\"A\": 1234}", "__value_string__": "1234"},
|
||||
StartsAt: time.Now(),
|
||||
EndsAt: time.Now().Add(2 * time.Hour),
|
||||
GeneratorURL: "http://localhost/alert2",
|
||||
@ -38,7 +38,7 @@ func TestDefaultTemplateString(t *testing.T) {
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val3"},
|
||||
Annotations: model.LabelSet{
|
||||
"ann1": "annv3", "__dashboardUid__": "dbuid456", "__panelId__": "puid456", "__value_string__": "1234",
|
||||
"ann1": "annv3", "__dashboardUid__": "dbuid456", "__panelId__": "puid456", "__values__": "{\"A\": 1234}", "__value_string__": "1234",
|
||||
},
|
||||
StartsAt: time.Now().Add(-1 * time.Hour),
|
||||
EndsAt: time.Now().Add(-30 * time.Minute),
|
||||
@ -47,7 +47,7 @@ func TestDefaultTemplateString(t *testing.T) {
|
||||
}, { // Resolved without dashboard and panel ID.
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val4"},
|
||||
Annotations: model.LabelSet{"ann1": "annv4", "__value_string__": "1234"},
|
||||
Annotations: model.LabelSet{"ann1": "annv4", "__values__": "{\"A\": 1234}", "__value_string__": "1234"},
|
||||
StartsAt: time.Now().Add(-2 * time.Hour),
|
||||
EndsAt: time.Now().Add(-3 * time.Hour),
|
||||
GeneratorURL: "http://localhost/alert4",
|
||||
@ -91,7 +91,7 @@ func TestDefaultTemplateString(t *testing.T) {
|
||||
templateString: DefaultMessageEmbed,
|
||||
expected: `**Firing**
|
||||
|
||||
Value: 1234
|
||||
Value: A=1234
|
||||
Labels:
|
||||
- alertname = alert1
|
||||
- lbl1 = val1
|
||||
@ -102,7 +102,7 @@ Silence: http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matc
|
||||
Dashboard: http://localhost/grafana/d/dbuid123
|
||||
Panel: http://localhost/grafana/d/dbuid123?viewPanel=puid123
|
||||
|
||||
Value: 1234
|
||||
Value: A=1234
|
||||
Labels:
|
||||
- alertname = alert1
|
||||
- lbl1 = val2
|
||||
@ -114,7 +114,7 @@ Silence: http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matc
|
||||
|
||||
**Resolved**
|
||||
|
||||
Value: 1234
|
||||
Value: A=1234
|
||||
Labels:
|
||||
- alertname = alert1
|
||||
- lbl1 = val3
|
||||
@ -125,7 +125,7 @@ Silence: http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matc
|
||||
Dashboard: http://localhost/grafana/d/dbuid456
|
||||
Panel: http://localhost/grafana/d/dbuid456?viewPanel=puid456
|
||||
|
||||
Value: 1234
|
||||
Value: A=1234
|
||||
Labels:
|
||||
- alertname = alert1
|
||||
- lbl1 = val4
|
||||
@ -139,7 +139,7 @@ Silence: http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matc
|
||||
templateString: `{{ template "teams.default.message" .}}`,
|
||||
expected: `**Firing**
|
||||
|
||||
Value: 1234
|
||||
Value: A=1234
|
||||
Labels:
|
||||
- alertname = alert1
|
||||
- lbl1 = val1
|
||||
@ -157,7 +157,7 @@ Panel: [http://localhost/grafana/d/dbuid123?viewPanel=puid123](http://localhost/
|
||||
|
||||
|
||||
|
||||
Value: 1234
|
||||
Value: A=1234
|
||||
Labels:
|
||||
- alertname = alert1
|
||||
- lbl1 = val2
|
||||
@ -174,7 +174,7 @@ Silence: [http://localhost/grafana/alerting/silence/new?alertmanager=grafana&mat
|
||||
|
||||
**Resolved**
|
||||
|
||||
Value: 1234
|
||||
Value: A=1234
|
||||
Labels:
|
||||
- alertname = alert1
|
||||
- lbl1 = val3
|
||||
@ -192,7 +192,7 @@ Panel: [http://localhost/grafana/d/dbuid456?viewPanel=puid456](http://localhost/
|
||||
|
||||
|
||||
|
||||
Value: 1234
|
||||
Value: A=1234
|
||||
Labels:
|
||||
- alertname = alert1
|
||||
- lbl1 = val4
|
||||
|
@ -36,7 +36,7 @@ func TestDingdingNotifier(t *testing.T) {
|
||||
{
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1"},
|
||||
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh", "__value_string__": "1234"},
|
||||
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh", "__values__": "{\"A\": 1234}", "__value_string__": "1234"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -44,7 +44,7 @@ func TestDingdingNotifier(t *testing.T) {
|
||||
"msgtype": "link",
|
||||
"link": map[string]interface{}{
|
||||
"messageUrl": "dingtalk://dingtalkclient/page/link?pc_slide=false&url=http%3A%2F%2Flocalhost%2Falerting%2Flist",
|
||||
"text": "**Firing**\n\nValue: 1234\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n",
|
||||
"text": "**Firing**\n\nValue: A=1234\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n",
|
||||
"title": "[FIRING:1] (val1)",
|
||||
},
|
||||
},
|
||||
|
@ -2,6 +2,7 @@ package channels
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"path"
|
||||
"sort"
|
||||
@ -18,19 +19,20 @@ import (
|
||||
)
|
||||
|
||||
type ExtendedAlert struct {
|
||||
Status string `json:"status"`
|
||||
Labels template.KV `json:"labels"`
|
||||
Annotations template.KV `json:"annotations"`
|
||||
StartsAt time.Time `json:"startsAt"`
|
||||
EndsAt time.Time `json:"endsAt"`
|
||||
GeneratorURL string `json:"generatorURL"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
SilenceURL string `json:"silenceURL"`
|
||||
DashboardURL string `json:"dashboardURL"`
|
||||
PanelURL string `json:"panelURL"`
|
||||
ValueString string `json:"valueString"`
|
||||
ImageURL string `json:"imageURL,omitempty"`
|
||||
EmbeddedImage string `json:"embeddedImage,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Labels template.KV `json:"labels"`
|
||||
Annotations template.KV `json:"annotations"`
|
||||
StartsAt time.Time `json:"startsAt"`
|
||||
EndsAt time.Time `json:"endsAt"`
|
||||
GeneratorURL string `json:"generatorURL"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
SilenceURL string `json:"silenceURL"`
|
||||
DashboardURL string `json:"dashboardURL"`
|
||||
PanelURL string `json:"panelURL"`
|
||||
Values map[string]float64 `json:"values"`
|
||||
ValueString string `json:"valueString"` // TODO: Remove in Grafana 10
|
||||
ImageURL string `json:"imageURL,omitempty"`
|
||||
EmbeddedImage string `json:"embeddedImage,omitempty"`
|
||||
}
|
||||
|
||||
type ExtendedAlerts []ExtendedAlert
|
||||
@ -90,7 +92,13 @@ func extendAlert(alert template.Alert, externalURL string, logger log.Logger) *E
|
||||
}
|
||||
|
||||
if alert.Annotations != nil {
|
||||
extended.ValueString = alert.Annotations[`__value_string__`]
|
||||
if s, ok := alert.Annotations[ngmodels.ValuesAnnotation]; ok {
|
||||
if err := json.Unmarshal([]byte(s), &extended.Values); err != nil {
|
||||
logger.Warn("failed to unmarshal values annotation", "err", err)
|
||||
}
|
||||
}
|
||||
// TODO: Remove in Grafana 10
|
||||
extended.ValueString = alert.Annotations[ngmodels.ValueStringAnnotation]
|
||||
}
|
||||
|
||||
matchers := make([]string, 0)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package schedule
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
@ -35,8 +36,15 @@ func stateToPostableAlert(alertState *state.State, appURL *url.URL) *models.Post
|
||||
nL := alertState.Labels.Copy()
|
||||
nA := data.Labels(alertState.Annotations).Copy()
|
||||
|
||||
// encode the values as JSON where it will be expanded later
|
||||
if len(alertState.Values) > 0 {
|
||||
if b, err := json.Marshal(alertState.Values); err == nil {
|
||||
nA[ngModels.ValuesAnnotation] = string(b)
|
||||
}
|
||||
}
|
||||
|
||||
if alertState.LastEvaluationString != "" {
|
||||
nA["__value_string__"] = alertState.LastEvaluationString
|
||||
nA[ngModels.ValueStringAnnotation] = alertState.LastEvaluationString
|
||||
}
|
||||
|
||||
if alertState.Image != nil {
|
||||
|
@ -276,5 +276,6 @@ func randomState(evalState eval.State) *state.State {
|
||||
LastSentAt: randomTimeInPast(),
|
||||
Annotations: make(map[string]string),
|
||||
Labels: make(map[string]string),
|
||||
Values: make(map[string]float64),
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package state
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -50,6 +51,15 @@ func (c *cache) getOrCreate(ctx context.Context, log log.Logger, alertRule *ngMo
|
||||
func (rs *ruleStates) getOrCreate(ctx context.Context, log log.Logger, alertRule *ngModels.AlertRule, result eval.Result, extraLabels data.Labels, externalURL *url.URL) *State {
|
||||
ruleLabels, annotations := rs.expandRuleLabelsAndAnnotations(ctx, log, alertRule, result, extraLabels, externalURL)
|
||||
|
||||
values := make(map[string]float64)
|
||||
for _, v := range result.Values {
|
||||
if v.Value != nil {
|
||||
values[v.Var] = *v.Value
|
||||
} else {
|
||||
values[v.Var] = math.NaN()
|
||||
}
|
||||
}
|
||||
|
||||
lbs := make(data.Labels, len(extraLabels)+len(ruleLabels)+len(result.Instance))
|
||||
dupes := make(data.Labels)
|
||||
for key, val := range extraLabels {
|
||||
@ -102,6 +112,7 @@ func (rs *ruleStates) getOrCreate(ctx context.Context, log log.Logger, alertRule
|
||||
}
|
||||
}
|
||||
state.Annotations = annotations
|
||||
state.Values = values
|
||||
rs.states[id] = state
|
||||
return state
|
||||
}
|
||||
@ -115,6 +126,7 @@ func (rs *ruleStates) getOrCreate(ctx context.Context, log log.Logger, alertRule
|
||||
Labels: lbs,
|
||||
Annotations: annotations,
|
||||
EvaluationDuration: result.EvaluationDuration,
|
||||
Values: values,
|
||||
}
|
||||
if result.State == eval.Alerting {
|
||||
newState.StartsAt = result.EvaluatedAt
|
||||
|
@ -125,7 +125,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Normal,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -179,7 +180,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label_1": "test",
|
||||
},
|
||||
State: eval.Normal,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -202,7 +204,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label_2": "test",
|
||||
},
|
||||
State: eval.Alerting,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Alerting,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -259,7 +262,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Normal,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -320,7 +324,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Alerting,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Alerting,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -392,7 +397,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Alerting,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Alerting,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -486,7 +492,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Pending,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Pending,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime.Add(30 * time.Second),
|
||||
@ -567,7 +574,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.NoData,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.NoData,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime.Add(20 * time.Second),
|
||||
@ -631,7 +639,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Pending,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Pending,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -695,7 +704,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Pending,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Pending,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -759,6 +769,7 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Alerting,
|
||||
StateReason: eval.NoData.String(),
|
||||
Results: []state.Evaluation{
|
||||
@ -824,7 +835,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.NoData,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.NoData,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -888,7 +900,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Normal,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -912,7 +925,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"alertname": "test_title",
|
||||
"label": "test",
|
||||
},
|
||||
State: eval.NoData,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.NoData,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime.Add(10 * time.Second),
|
||||
@ -977,7 +991,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test-1",
|
||||
},
|
||||
State: eval.Normal,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -1002,7 +1017,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test-2",
|
||||
},
|
||||
State: eval.Normal,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -1026,7 +1042,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"alertname": "test_title",
|
||||
"label": "test",
|
||||
},
|
||||
State: eval.NoData,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.NoData,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime.Add(10 * time.Second),
|
||||
@ -1093,7 +1110,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Normal,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -1122,7 +1140,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"alertname": "test_title",
|
||||
"label": "test",
|
||||
},
|
||||
State: eval.NoData,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.NoData,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime.Add(10 * time.Second),
|
||||
@ -1181,6 +1200,7 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
StateReason: eval.NoData.String(),
|
||||
Results: []state.Evaluation{
|
||||
@ -1247,6 +1267,7 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Alerting,
|
||||
StateReason: eval.NoData.String(),
|
||||
|
||||
@ -1314,6 +1335,7 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Pending,
|
||||
StateReason: eval.Error.String(),
|
||||
Results: []state.Evaluation{
|
||||
@ -1404,6 +1426,7 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Alerting,
|
||||
StateReason: eval.Error.String(),
|
||||
Results: []state.Evaluation{
|
||||
@ -1485,7 +1508,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"datasource_uid": "datasource_uid_1",
|
||||
"ref_id": "A",
|
||||
},
|
||||
State: eval.Error,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Error,
|
||||
Error: expr.QueryError{
|
||||
RefID: "A",
|
||||
Err: errors.New("this is an error"),
|
||||
@ -1562,6 +1586,7 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
StateReason: eval.Error.String(),
|
||||
Error: nil,
|
||||
@ -1635,6 +1660,7 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
StateReason: eval.Error.String(),
|
||||
Error: nil,
|
||||
@ -1734,7 +1760,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Error,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Error,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime.Add(40 * time.Second),
|
||||
@ -1815,7 +1842,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.Alerting,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Alerting,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime.Add(30 * time.Second),
|
||||
@ -1902,7 +1930,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"instance_label": "test",
|
||||
},
|
||||
State: eval.NoData,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.NoData,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime.Add(30 * time.Second),
|
||||
@ -1964,7 +1993,8 @@ func TestProcessEvalResults(t *testing.T) {
|
||||
"label": "test",
|
||||
"job": "prod/grafana",
|
||||
},
|
||||
State: eval.Normal,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
@ -2117,7 +2147,8 @@ func TestStaleResultsHandler(t *testing.T) {
|
||||
"alertname": rule.Title,
|
||||
"test1": "testValue1",
|
||||
},
|
||||
State: eval.Normal,
|
||||
Values: make(map[string]float64),
|
||||
State: eval.Normal,
|
||||
Results: []state.Evaluation{
|
||||
{
|
||||
EvaluationTime: evaluationTime,
|
||||
|
@ -32,6 +32,7 @@ type State struct {
|
||||
Resolved bool
|
||||
Annotations map[string]string
|
||||
Labels data.Labels
|
||||
Values map[string]float64
|
||||
Image *models.Image
|
||||
Error error
|
||||
}
|
||||
|
@ -2275,6 +2275,7 @@ var expEmailNotifications = []*models.SendEmailCommandSync{
|
||||
SilenceURL: "http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DEmailAlert&matcher=grafana_folder%3Ddefault",
|
||||
DashboardURL: "",
|
||||
PanelURL: "",
|
||||
Values: map[string]float64{"A": 1},
|
||||
ValueString: "[ var='A' labels={} value=1 ]",
|
||||
},
|
||||
},
|
||||
@ -2332,7 +2333,7 @@ var expNonEmailNotifications = map[string][]string{
|
||||
{
|
||||
"title": "[FIRING:1] SlackAlert2 (default)",
|
||||
"title_link": "http://localhost:3000/alerting/list",
|
||||
"text": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = SlackAlert2\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_SlackAlert2/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DSlackAlert2&matcher=grafana_folder%%3Ddefault\n",
|
||||
"text": "**Firing**\n\nValue: A=1\nLabels:\n - alertname = SlackAlert2\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_SlackAlert2/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DSlackAlert2&matcher=grafana_folder%%3Ddefault\n",
|
||||
"fallback": "[FIRING:1] SlackAlert2 (default)",
|
||||
"footer": "Grafana v",
|
||||
"footer_icon": "https://grafana.com/assets/img/fav32.png",
|
||||
@ -2365,7 +2366,7 @@ var expNonEmailNotifications = map[string][]string{
|
||||
"component": "Integration Test",
|
||||
"group": "testgroup",
|
||||
"custom_details": {
|
||||
"firing": "\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = PagerdutyAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_PagerdutyAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DPagerdutyAlert&matcher=grafana_folder%%3Ddefault\n",
|
||||
"firing": "\nValue: A=1\nLabels:\n - alertname = PagerdutyAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_PagerdutyAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DPagerdutyAlert&matcher=grafana_folder%%3Ddefault\n",
|
||||
"num_firing": "1",
|
||||
"num_resolved": "0",
|
||||
"resolved": ""
|
||||
@ -2385,7 +2386,7 @@ var expNonEmailNotifications = map[string][]string{
|
||||
`{
|
||||
"link": {
|
||||
"messageUrl": "dingtalk://dingtalkclient/page/link?pc_slide=false&url=http%3A%2F%2Flocalhost%3A3000%2Falerting%2Flist",
|
||||
"text": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = DingDingAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_DingDingAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DDingDingAlert&matcher=grafana_folder%3Ddefault\n",
|
||||
"text": "**Firing**\n\nValue: A=1\nLabels:\n - alertname = DingDingAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_DingDingAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DDingDingAlert&matcher=grafana_folder%3Ddefault\n",
|
||||
"title": "[FIRING:1] DingDingAlert (default)"
|
||||
},
|
||||
"msgtype": "link"
|
||||
@ -2406,7 +2407,7 @@ var expNonEmailNotifications = map[string][]string{
|
||||
"weight": "bolder",
|
||||
"wrap": true
|
||||
}, {
|
||||
"text": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = TeamsAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_TeamsAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana\u0026matcher=alertname%3DTeamsAlert\u0026matcher=grafana_folder%3Ddefault\n",
|
||||
"text": "**Firing**\n\nValue: A=1\nLabels:\n - alertname = TeamsAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_TeamsAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana\u0026matcher=alertname%3DTeamsAlert\u0026matcher=grafana_folder%3Ddefault\n",
|
||||
"type": "TextBlock",
|
||||
"wrap": true
|
||||
}, {
|
||||
@ -2447,7 +2448,8 @@ var expNonEmailNotifications = map[string][]string{
|
||||
},
|
||||
"annotations": {},
|
||||
"startsAt": "%s",
|
||||
"valueString": "[ var='A' labels={} value=1 ]",
|
||||
"values": {"A": 1},
|
||||
"valueString": "[ var='A' labels={} value=1 ]",
|
||||
"endsAt": "0001-01-01T00:00:00Z",
|
||||
"generatorURL": "http://localhost:3000/alerting/grafana/UID_WebhookAlert/view",
|
||||
"fingerprint": "15c59b0a380bd9f1",
|
||||
@ -2470,12 +2472,12 @@ var expNonEmailNotifications = map[string][]string{
|
||||
"truncatedAlerts": 0,
|
||||
"title": "[FIRING:1] WebhookAlert (default)",
|
||||
"state": "alerting",
|
||||
"message": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = WebhookAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_WebhookAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DWebhookAlert&matcher=grafana_folder%%3Ddefault\n"
|
||||
"message": "**Firing**\n\nValue: A=1\nLabels:\n - alertname = WebhookAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_WebhookAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DWebhookAlert&matcher=grafana_folder%%3Ddefault\n"
|
||||
}`,
|
||||
},
|
||||
"discord_recv/discord_test": {
|
||||
`{
|
||||
"content": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = DiscordAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_DiscordAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DDiscordAlert&matcher=grafana_folder%3Ddefault\n",
|
||||
"content": "**Firing**\n\nValue: A=1\nLabels:\n - alertname = DiscordAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_DiscordAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DDiscordAlert&matcher=grafana_folder%3Ddefault\n",
|
||||
"embeds": [
|
||||
{
|
||||
"color": 14037554,
|
||||
@ -2503,7 +2505,7 @@ var expNonEmailNotifications = map[string][]string{
|
||||
},
|
||||
"name": "default"
|
||||
},
|
||||
"output": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = SensuGoAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_SensuGoAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DSensuGoAlert&matcher=grafana_folder%%3Ddefault\n",
|
||||
"output": "**Firing**\n\nValue: A=1\nLabels:\n - alertname = SensuGoAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_SensuGoAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DSensuGoAlert&matcher=grafana_folder%%3Ddefault\n",
|
||||
"status": 2
|
||||
},
|
||||
"entity": {
|
||||
@ -2516,10 +2518,10 @@ var expNonEmailNotifications = map[string][]string{
|
||||
}`,
|
||||
},
|
||||
"pushover_recv/pushover_test": {
|
||||
"--abcd\r\nContent-Disposition: form-data; name=\"user\"\r\n\r\nmysecretkey\r\n--abcd\r\nContent-Disposition: form-data; name=\"token\"\r\n\r\nmysecrettoken\r\n--abcd\r\nContent-Disposition: form-data; name=\"priority\"\r\n\r\n0\r\n--abcd\r\nContent-Disposition: form-data; name=\"sound\"\r\n\r\n\r\n--abcd\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n[FIRING:1] PushoverAlert (default)\r\n--abcd\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\nhttp://localhost:3000/alerting/list\r\n--abcd\r\nContent-Disposition: form-data; name=\"url_title\"\r\n\r\nShow alert rule\r\n--abcd\r\nContent-Disposition: form-data; name=\"message\"\r\n\r\n**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = PushoverAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_PushoverAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DPushoverAlert&matcher=grafana_folder%3Ddefault\n\r\n--abcd\r\nContent-Disposition: form-data; name=\"html\"\r\n\r\n1\r\n--abcd--\r\n",
|
||||
"--abcd\r\nContent-Disposition: form-data; name=\"user\"\r\n\r\nmysecretkey\r\n--abcd\r\nContent-Disposition: form-data; name=\"token\"\r\n\r\nmysecrettoken\r\n--abcd\r\nContent-Disposition: form-data; name=\"priority\"\r\n\r\n0\r\n--abcd\r\nContent-Disposition: form-data; name=\"sound\"\r\n\r\n\r\n--abcd\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n[FIRING:1] PushoverAlert (default)\r\n--abcd\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\nhttp://localhost:3000/alerting/list\r\n--abcd\r\nContent-Disposition: form-data; name=\"url_title\"\r\n\r\nShow alert rule\r\n--abcd\r\nContent-Disposition: form-data; name=\"message\"\r\n\r\n**Firing**\n\nValue: A=1\nLabels:\n - alertname = PushoverAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_PushoverAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DPushoverAlert&matcher=grafana_folder%3Ddefault\n\r\n--abcd\r\nContent-Disposition: form-data; name=\"html\"\r\n\r\n1\r\n--abcd--\r\n",
|
||||
},
|
||||
"telegram_recv/bot6sh027hs034h": {
|
||||
"--abcd\r\nContent-Disposition: form-data; name=\"chat_id\"\r\n\r\ntelegram_chat_id\r\n--abcd\r\nContent-Disposition: form-data; name=\"parse_mode\"\r\n\r\nhtml\r\n--abcd\r\nContent-Disposition: form-data; name=\"text\"\r\n\r\n**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = TelegramAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_TelegramAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DTelegramAlert&matcher=grafana_folder%3Ddefault\n\r\n--abcd--\r\n",
|
||||
"--abcd\r\nContent-Disposition: form-data; name=\"chat_id\"\r\n\r\ntelegram_chat_id\r\n--abcd\r\nContent-Disposition: form-data; name=\"parse_mode\"\r\n\r\nhtml\r\n--abcd\r\nContent-Disposition: form-data; name=\"text\"\r\n\r\n**Firing**\n\nValue: A=1\nLabels:\n - alertname = TelegramAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_TelegramAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DTelegramAlert&matcher=grafana_folder%3Ddefault\n\r\n--abcd--\r\n",
|
||||
},
|
||||
"googlechat_recv/googlechat_test": {
|
||||
`{
|
||||
@ -2535,7 +2537,7 @@ var expNonEmailNotifications = map[string][]string{
|
||||
"widgets": [
|
||||
{
|
||||
"textParagraph": {
|
||||
"text": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = GoogleChatAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_GoogleChatAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DGoogleChatAlert&matcher=grafana_folder%%3Ddefault\n"
|
||||
"text": "**Firing**\n\nValue: A=1\nLabels:\n - alertname = GoogleChatAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_GoogleChatAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DGoogleChatAlert&matcher=grafana_folder%%3Ddefault\n"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -2573,7 +2575,7 @@ var expNonEmailNotifications = map[string][]string{
|
||||
"client": "Grafana",
|
||||
"client_url": "http://localhost:3000/alerting/list",
|
||||
"description": "[FIRING:1] KafkaAlert (default)",
|
||||
"details": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = KafkaAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_KafkaAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DKafkaAlert&matcher=grafana_folder%3Ddefault\n",
|
||||
"details": "**Firing**\n\nValue: A=1\nLabels:\n - alertname = KafkaAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_KafkaAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DKafkaAlert&matcher=grafana_folder%3Ddefault\n",
|
||||
"incident_key": "35c0bdb1715f9162a20d7b2a01cb2e3a4c5b1dc663571701e3f67212b696332f"
|
||||
}
|
||||
}
|
||||
@ -2581,10 +2583,10 @@ var expNonEmailNotifications = map[string][]string{
|
||||
}`,
|
||||
},
|
||||
"line_recv/line_test": {
|
||||
`message=%5BFIRING%3A1%5D+LineAlert+%28default%29%0Ahttp%3A%2Flocalhost%3A3000%2Falerting%2Flist%0A%0A%2A%2AFiring%2A%2A%0A%0AValue%3A+%5B+var%3D%27A%27+labels%3D%7B%7D+value%3D1+%5D%0ALabels%3A%0A+-+alertname+%3D+LineAlert%0A+-+grafana_folder+%3D+default%0AAnnotations%3A%0ASource%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fgrafana%2FUID_LineAlert%2Fview%0ASilence%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matcher%3Dalertname%253DLineAlert%26matcher%3Dgrafana_folder%253Ddefault%0A`,
|
||||
`message=%5BFIRING%3A1%5D+LineAlert+%28default%29%0Ahttp%3A%2Flocalhost%3A3000%2Falerting%2Flist%0A%0A%2A%2AFiring%2A%2A%0A%0AValue%3A+A%3D1%0ALabels%3A%0A+-+alertname+%3D+LineAlert%0A+-+grafana_folder+%3D+default%0AAnnotations%3A%0ASource%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fgrafana%2FUID_LineAlert%2Fview%0ASilence%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matcher%3Dalertname%253DLineAlert%26matcher%3Dgrafana_folder%253Ddefault%0A`,
|
||||
},
|
||||
"threema_recv/threema_test": {
|
||||
`from=%2A1234567&secret=myapisecret&text=%E2%9A%A0%EF%B8%8F+%5BFIRING%3A1%5D+ThreemaAlert+%28default%29%0A%0A%2AMessage%3A%2A%0A%2A%2AFiring%2A%2A%0A%0AValue%3A+%5B+var%3D%27A%27+labels%3D%7B%7D+value%3D1+%5D%0ALabels%3A%0A+-+alertname+%3D+ThreemaAlert%0A+-+grafana_folder+%3D+default%0AAnnotations%3A%0ASource%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fgrafana%2FUID_ThreemaAlert%2Fview%0ASilence%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matcher%3Dalertname%253DThreemaAlert%26matcher%3Dgrafana_folder%253Ddefault%0A%0A%2AURL%3A%2A+http%3A%2Flocalhost%3A3000%2Falerting%2Flist%0A&to=abcdefgh`,
|
||||
`from=%2A1234567&secret=myapisecret&text=%E2%9A%A0%EF%B8%8F+%5BFIRING%3A1%5D+ThreemaAlert+%28default%29%0A%0A%2AMessage%3A%2A%0A%2A%2AFiring%2A%2A%0A%0AValue%3A+A%3D1%0ALabels%3A%0A+-+alertname+%3D+ThreemaAlert%0A+-+grafana_folder+%3D+default%0AAnnotations%3A%0ASource%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fgrafana%2FUID_ThreemaAlert%2Fview%0ASilence%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matcher%3Dalertname%253DThreemaAlert%26matcher%3Dgrafana_folder%253Ddefault%0A%0A%2AURL%3A%2A+http%3A%2Flocalhost%3A3000%2Falerting%2Flist%0A&to=abcdefgh`,
|
||||
},
|
||||
"victorops_recv/victorops_test": {
|
||||
`{
|
||||
@ -2593,14 +2595,14 @@ var expNonEmailNotifications = map[string][]string{
|
||||
"entity_id": "633ae988fa7074bcb51f3d1c5fef2ba1c5c4ccb45b3ecbf681f7d507b078b1ae",
|
||||
"message_type": "CRITICAL",
|
||||
"monitoring_tool": "Grafana v",
|
||||
"state_message": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = VictorOpsAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_VictorOpsAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DVictorOpsAlert&matcher=grafana_folder%%3Ddefault\n",
|
||||
"state_message": "**Firing**\n\nValue: A=1\nLabels:\n - alertname = VictorOpsAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_VictorOpsAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%%3DVictorOpsAlert&matcher=grafana_folder%%3Ddefault\n",
|
||||
"timestamp": %s
|
||||
}`,
|
||||
},
|
||||
"opsgenie_recv/opsgenie_test": {
|
||||
`{
|
||||
"alias": "47e92f0f6ef9fe99f3954e0d6155f8d09c4b9a038d8c3105e82c0cee4c62956e",
|
||||
"description": "[FIRING:1] OpsGenieAlert (default)\nhttp://localhost:3000/alerting/list\n\n**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = OpsGenieAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_OpsGenieAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DOpsGenieAlert&matcher=grafana_folder%3Ddefault\n",
|
||||
"description": "[FIRING:1] OpsGenieAlert (default)\nhttp://localhost:3000/alerting/list\n\n**Firing**\n\nValue: A=1\nLabels:\n - alertname = OpsGenieAlert\n - grafana_folder = default\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_OpsGenieAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DOpsGenieAlert&matcher=grafana_folder%3Ddefault\n",
|
||||
"details": {
|
||||
"url": "http://localhost:3000/alerting/list"
|
||||
},
|
||||
@ -2619,8 +2621,9 @@ var expNonEmailNotifications = map[string][]string{
|
||||
"grafana_folder": "default"
|
||||
},
|
||||
"annotations": {
|
||||
"__value_string__": "[ var='A' labels={} value=1 ]"
|
||||
},
|
||||
"__values__": "{\"A\":1}",
|
||||
"__value_string__": "[ var='A' labels={} value=1 ]"
|
||||
},
|
||||
"startsAt": "%s",
|
||||
"endsAt": "0001-01-01T00:00:00Z",
|
||||
"generatorURL": "http://localhost:3000/alerting/grafana/UID_AlertmanagerAlert/view",
|
||||
|
@ -75,6 +75,12 @@ export const AlertTemplateData: TemplateDataItem[] = [
|
||||
type: 'KeyValue',
|
||||
notes: 'Set of annotations attached to the alert.',
|
||||
},
|
||||
{
|
||||
name: 'Values',
|
||||
type: 'KeyValue',
|
||||
notes:
|
||||
'The values of all instant queries, reduce and math expressions, and classic conditions for the alert. It does not contain time series data.',
|
||||
},
|
||||
{
|
||||
name: 'StartsAt',
|
||||
type: 'time.Time',
|
||||
|
@ -209,6 +209,10 @@ text-decoration: underline;
|
||||
|
||||
{{Subject .Subject "{{.Title}}"}}
|
||||
|
||||
{{ define "__text_values_list" }}{{ $len := len .Values }}{{ if $len }}{{ $first := gt $len 1 }}{{ range $refID, $value := .Values -}}
|
||||
{{ $refID }}={{ $value }}{{ if $first }}, {{ end }}{{ $first = false }}{{ end -}}
|
||||
{{ else }}[no value]{{ end }}{{ end }}
|
||||
|
||||
{{ define "alert" }}
|
||||
|
||||
{{ if ne .ImageURL "" }}
|
||||
@ -227,7 +231,7 @@ text-decoration: underline;
|
||||
{{ end }}
|
||||
<tr style="vertical-align: top; padding: 0;" align="left">
|
||||
<td colspan="2" class="value" style="word-break: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; border-collapse: collapse !important; color: #222222; font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: normal; line-height: 19px; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; margin: 0; padding: 24px 0 0;" align="left" valign="top">
|
||||
<span class="value-heading" style="font-weight: bold;">Value:</span> <span class="value-value" style="padding-left: 8px;">{{ .ValueString }}</span>
|
||||
<span class="value-heading" style="font-weight: bold;">Value:</span> <span class="value-value" style="padding-left: 8px;">{{ template "__text_values_list" . }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
{{ if gt (len .Annotations.SortedPairs) 0 }}
|
||||
|
Loading…
Reference in New Issue
Block a user