mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Fix ambiguous handling of equals in labels when bucketing Loki state history streams (#65013)
* Use JSON instead of data.Labels string format as label repr * Drop debug log line
This commit is contained in:
parent
bfb0dde4a8
commit
cc7e5ce62e
@ -242,7 +242,7 @@ func merge(res queryRes, ruleUID string) (*data.Frame, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func statesToStreams(rule history_model.RuleMeta, states []state.StateTransition, externalLabels map[string]string, logger log.Logger) []stream {
|
func statesToStreams(rule history_model.RuleMeta, states []state.StateTransition, externalLabels map[string]string, logger log.Logger) []stream {
|
||||||
buckets := make(map[string][]sample) // label repr -> entries
|
buckets := make(map[string][]sample) // label repr (JSON) -> entries
|
||||||
for _, state := range states {
|
for _, state := range states {
|
||||||
if !shouldRecord(state) {
|
if !shouldRecord(state) {
|
||||||
continue
|
continue
|
||||||
@ -254,7 +254,12 @@ func statesToStreams(rule history_model.RuleMeta, states []state.StateTransition
|
|||||||
labels[RuleUIDLabel] = fmt.Sprint(rule.UID)
|
labels[RuleUIDLabel] = fmt.Sprint(rule.UID)
|
||||||
labels[GroupLabel] = fmt.Sprint(rule.Group)
|
labels[GroupLabel] = fmt.Sprint(rule.Group)
|
||||||
labels[FolderUIDLabel] = fmt.Sprint(rule.NamespaceUID)
|
labels[FolderUIDLabel] = fmt.Sprint(rule.NamespaceUID)
|
||||||
repr := labels.String()
|
lblJsn, err := json.Marshal(labels)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to marshal labels to JSON", "error", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
repr := string(lblJsn)
|
||||||
|
|
||||||
entry := lokiEntry{
|
entry := lokiEntry{
|
||||||
SchemaVersion: 1,
|
SchemaVersion: 1,
|
||||||
|
@ -323,6 +323,29 @@ grafana_alerting_state_history_writes_total{org="1"} 2
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, req.lastRequest)
|
require.Nil(t, req.lastRequest)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("succeeds with special chars in labels", func(t *testing.T) {
|
||||||
|
req := NewFakeRequester()
|
||||||
|
loki := createTestLokiBackend(req, metrics.NewHistorianMetrics(prometheus.NewRegistry()))
|
||||||
|
rule := createTestRule()
|
||||||
|
states := singleFromNormal(&state.State{
|
||||||
|
State: eval.Alerting,
|
||||||
|
Labels: data.Labels{
|
||||||
|
"dots": "contains.dot",
|
||||||
|
"equals": "contains=equals",
|
||||||
|
"emoji": "contains🤔emoji",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
err := <-loki.Record(context.Background(), rule, states)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Contains(t, "/loki/api/v1/push", req.lastRequest.URL.Path)
|
||||||
|
sent := string(readBody(t, req.lastRequest))
|
||||||
|
require.Contains(t, sent, "contains.dot")
|
||||||
|
require.Contains(t, sent, "contains=equals")
|
||||||
|
require.Contains(t, sent, "contains🤔emoji")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestLokiBackend(req client.Requester, met *metrics.Historian) *RemoteLokiBackend {
|
func createTestLokiBackend(req client.Requester, met *metrics.Historian) *RemoteLokiBackend {
|
||||||
@ -378,3 +401,11 @@ func badResponse() *http.Response {
|
|||||||
Header: make(http.Header, 0),
|
Header: make(http.Header, 0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readBody(t *testing.T, req *http.Request) []byte {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
val, err := io.ReadAll(req.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user