Alerting: Add expression type information to webhook valueString (#112312)

* Alerting: Add expression type to webhook valueString
- Add Type field to NumberValueCapture struct
- Implement AlertQuery.GetExpressionType() method
- Update valueString format to include type information

* Alerting: Add expression type to webhook valueString
- Fix tests

* Alerting: Add expression type to webhook valueString
- Update default annotations in notifier templates to include type field

* Alerting: Add expression type to webhook valueString
- Add type='math' to webhook and email test expectations
This commit is contained in:
Seunghun Shin
2025-12-02 22:03:17 +01:00
committed by GitHub
parent 5175beb9ef
commit 55b94e6df6
7 changed files with 77 additions and 27 deletions
@@ -137,7 +137,7 @@ func TestIntegrationTestReceivers(t *testing.T) {
"__dashboardUid__": "dashboard_uid",
"__orgId__": "1",
"__panelId__": "1",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=1 ]",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='reduce' value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='threshold' value=1 ]",
"__values__": "{\"B\":22,\"C\":1}"
},
"labels": {
@@ -225,7 +225,7 @@ func TestIntegrationTestReceivers(t *testing.T) {
"__dashboardUid__": "dashboard_uid",
"__orgId__": "1",
"__panelId__": "1",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=1 ]",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='reduce' value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='threshold' value=1 ]",
"__values__": "{\"B\":22,\"C\":1}"
},
"labels": {
@@ -307,7 +307,7 @@ func TestIntegrationTestReceivers(t *testing.T) {
"__dashboardUid__": "dashboard_uid",
"__orgId__": "1",
"__panelId__": "1",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=1 ]",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='reduce' value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='threshold' value=1 ]",
"__values__": "{\"B\":22,\"C\":1}"
},
"labels": {
@@ -400,7 +400,7 @@ func TestIntegrationTestReceivers(t *testing.T) {
"__dashboardUid__": "dashboard_uid",
"__orgId__": "1",
"__panelId__": "1",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=1 ]",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='reduce' value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='threshold' value=1 ]",
"__values__": "{\"B\":22,\"C\":1}"
},
"labels": {
@@ -506,7 +506,7 @@ func TestIntegrationTestReceivers(t *testing.T) {
"__dashboardUid__": "dashboard_uid",
"__orgId__": "1",
"__panelId__": "1",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=1 ]",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='reduce' value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='threshold' value=1 ]",
"__values__": "{\"B\":22,\"C\":1}"
},
"labels": {
@@ -805,7 +805,7 @@ func TestIntegrationTestReceiversAlertCustomization(t *testing.T) {
"__dashboardUid__": "dashboard_uid",
"__orgId__": "1",
"__panelId__": "1",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} value=1 ]",
"__value_string__": "[ var='B' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='reduce' value=22 ], [ var='C' labels={__name__=go_threads, instance=host.docker.internal:3000, job=grafana} type='threshold' value=1 ]",
"__values__": "{\"B\":22,\"C\":1}"
},
"labels": {
@@ -2440,7 +2440,7 @@ var expEmailNotifications = []*notifications.SendEmailCommandSync{
PanelURL: "",
OrgID: util.Pointer(int64(1)),
Values: map[string]float64{"A": 1},
ValueString: "[ var='A' labels={} value=1 ]",
ValueString: "[ var='A' labels={} type='math' value=1 ]",
},
},
"GroupLabels": template.KV{"alertname": "EmailAlert"},
@@ -2594,10 +2594,10 @@ var expNonEmailNotifications = map[string][]string{
"grafana_folder": "default"
},
"annotations": {},
"startsAt": "%s",
"startsAt": "%s",
"values": {"A": 1},
"valueString": "[ var='A' labels={} value=1 ]",
"endsAt": "0001-01-01T00:00:00Z",
"valueString": "[ var='A' labels={} type='math' value=1 ]",
"endsAt": "0001-01-01T00:00:00Z",
"generatorURL": "http://localhost:3000/alerting/grafana/UID_WebhookAlert/view?orgId=1",
"fingerprint": "15c59b0a380bd9f1",
"silenceURL": "http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=__alert_rule_uid__%%3DUID_WebhookAlert&orgId=1",
@@ -2768,10 +2768,10 @@ var expNonEmailNotifications = map[string][]string{
"alertname": "AlertmanagerAlert",
"grafana_folder": "default"
},
"annotations": {
"__orgId__":"1",
"annotations": {
"__orgId__":"1",
"__values__": "{\"A\":1}",
"__value_string__": "[ var='A' labels={} value=1 ]"
"__value_string__": "[ var='A' labels={} type='math' value=1 ]"
},
"startsAt": "%s",
"endsAt": "0001-01-01T00:00:00Z",
+4 -4
View File
@@ -150,8 +150,8 @@ func TestGrafanaRuleConfig(t *testing.T) {
for i, alert := range result {
require.NotEmpty(t, alert.Annotations["values.B"])
require.NotEmpty(t, alert.Annotations["values.C"])
valueB := fmt.Sprintf("[ var='B' labels={state=%s} value=%s ]", dynamicLabels[i], alert.Annotations["values.B"])
valueC := fmt.Sprintf("[ var='C' labels={state=%s} value=%s ]", dynamicLabels[i], alert.Annotations["values.C"])
valueB := fmt.Sprintf("[ var='B' labels={state=%s} type='reduce' value=%s ]", dynamicLabels[i], alert.Annotations["values.B"])
valueC := fmt.Sprintf("[ var='C' labels={state=%s} type='threshold' value=%s ]", dynamicLabels[i], alert.Annotations["values.C"])
require.Contains(t, alert.Annotations["value"], valueB)
require.Contains(t, alert.Annotations["value"], valueC)
}
@@ -172,8 +172,8 @@ func TestGrafanaRuleConfig(t *testing.T) {
for i, alert := range result {
require.NotEmpty(t, alert.Labels["values.B"])
require.NotEmpty(t, alert.Labels["values.C"])
valueB := fmt.Sprintf("[ var='B' labels={state=%s} value=%s ]", dynamicLabels[i], alert.Labels["values.B"])
valueC := fmt.Sprintf("[ var='C' labels={state=%s} value=%s ]", dynamicLabels[i], alert.Labels["values.C"])
valueB := fmt.Sprintf("[ var='B' labels={state=%s} type='reduce' value=%s ]", dynamicLabels[i], alert.Labels["values.B"])
valueC := fmt.Sprintf("[ var='C' labels={state=%s} type='threshold' value=%s ]", dynamicLabels[i], alert.Labels["values.C"])
require.Contains(t, alert.Labels["value"], valueB)
require.Contains(t, alert.Labels["value"], valueC)
}