Skip to content

Commit 1b562c4

Browse files
committed
Fix: process percentile metric queries to display values on the frontend
1 parent 3ea07b4 commit 1b562c4

File tree

2 files changed

+91
-2
lines changed

2 files changed

+91
-2
lines changed

pkg/opensearch/response_parser.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,8 +1122,20 @@ func (rp *responseParser) processAggregationDocs(esAgg *simplejson.Json, aggDef
11221122
value = castToFloat(bucket.GetPath(metric.ID, statName))
11231123
}
11241124

1125-
fields = addMetricValue(fields, rp.getMetricName(metric.Type), value)
1126-
break
1125+
fieldName := fmt.Sprintf("%v %v", rp.getMetricName(metric.Type), rp.getMetricName(statName))
1126+
fields = addMetricValue(fields, fieldName, value)
1127+
}
1128+
case percentilesType:
1129+
percentiles := bucket.GetPath(metric.ID, "values")
1130+
percentileKeys := make([]string, 0, len(percentiles.MustMap()))
1131+
for k := range percentiles.MustMap() {
1132+
percentileKeys = append(percentileKeys, k)
1133+
}
1134+
sort.Strings(percentileKeys)
1135+
for _, percentileName := range percentileKeys {
1136+
percentileValue := percentiles.Get(percentileName).MustFloat64()
1137+
fieldName := fmt.Sprintf("p%v %v", percentileName, metric.Field)
1138+
fields = addMetricValue(fields, fieldName, &percentileValue)
11271139
}
11281140
default:
11291141
metricName := rp.getMetricName(metric.Type)

pkg/opensearch/response_parser_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,83 @@ func Test_ResponseParser_test(t *testing.T) {
11581158
assert.EqualValues(t, 200, *frames.Fields[2].At(1).(*float64))
11591159
})
11601160

1161+
t.Run("Percentiles and Extended Stats with Terms", func(t *testing.T) {
1162+
targets := []tsdbQuery{{
1163+
refId: "A",
1164+
body: `{
1165+
"timeField": "@timestamp",
1166+
"metrics": [
1167+
{ "type": "percentiles", "field": "bytes", "settings": { "percents": [25, 50, 75, 95, 99] }, "id": "1" },
1168+
{ "type": "extended_stats", "field": "bytes", "meta": { "max": true, "min": true }, "id": "2" }
1169+
],
1170+
"bucketAggs": [{ "type": "terms", "field": "host.keyword", "id": "3" }]
1171+
}`,
1172+
}}
1173+
response := `{
1174+
"responses": [
1175+
{
1176+
"aggregations": {
1177+
"3": {
1178+
"buckets": [
1179+
{
1180+
"1": { "values": { "25": 25, "50": 50, "75": 75, "95": 95, "99": 99 } },
1181+
"2": { "max": 99, "min": 25 },
1182+
"key": "www.example-1.com",
1183+
"doc_count": 100
1184+
},
1185+
{
1186+
"1": { "values": { "25": 125, "50": 150, "75": 175, "95": 195, "99": 199 } },
1187+
"2": { "max": 199, "min": 125 },
1188+
"key": "www.example-2.com",
1189+
"doc_count": 50
1190+
}
1191+
]
1192+
}
1193+
}
1194+
}
1195+
]
1196+
}`
1197+
rp, err := newResponseParserForTest(targets, response, nil, client.ConfiguredFields{TimeField: "@timestamp"}, nil)
1198+
assert.Nil(t, err)
1199+
result, err := rp.parseResponse()
1200+
assert.Nil(t, err)
1201+
require.Len(t, result.Responses, 1)
1202+
1203+
queryRes := result.Responses["A"]
1204+
assert.NotNil(t, queryRes)
1205+
assert.Len(t, queryRes.Frames, 1)
1206+
1207+
frame := queryRes.Frames[0]
1208+
require.Len(t, frame.Fields, 8)
1209+
1210+
assert.Equal(t, "host.keyword", frame.Fields[0].Name)
1211+
assert.Equal(t, "p25 bytes", frame.Fields[1].Name)
1212+
assert.Equal(t, "p50 bytes", frame.Fields[2].Name)
1213+
assert.Equal(t, "p75 bytes", frame.Fields[3].Name)
1214+
assert.Equal(t, "p95 bytes", frame.Fields[4].Name)
1215+
assert.Equal(t, "p99 bytes", frame.Fields[5].Name)
1216+
assert.Equal(t, "Extended Stats Max", frame.Fields[6].Name)
1217+
assert.Equal(t, "Extended Stats Min", frame.Fields[7].Name)
1218+
1219+
assert.Equal(t, "www.example-1.com", *frame.Fields[0].At(0).(*string))
1220+
assert.EqualValues(t, 25, *frame.Fields[1].At(0).(*float64))
1221+
assert.EqualValues(t, 50, *frame.Fields[2].At(0).(*float64))
1222+
assert.EqualValues(t, 75, *frame.Fields[3].At(0).(*float64))
1223+
assert.EqualValues(t, 95, *frame.Fields[4].At(0).(*float64))
1224+
assert.EqualValues(t, 99, *frame.Fields[5].At(0).(*float64))
1225+
assert.EqualValues(t, 99, *frame.Fields[6].At(0).(*float64))
1226+
assert.EqualValues(t, 25, *frame.Fields[7].At(0).(*float64))
1227+
1228+
assert.Equal(t, "www.example-2.com", *frame.Fields[0].At(1).(*string))
1229+
assert.EqualValues(t, 125, *frame.Fields[1].At(1).(*float64))
1230+
assert.EqualValues(t, 150, *frame.Fields[2].At(1).(*float64))
1231+
assert.EqualValues(t, 175, *frame.Fields[3].At(1).(*float64))
1232+
assert.EqualValues(t, 195, *frame.Fields[4].At(1).(*float64))
1233+
assert.EqualValues(t, 199, *frame.Fields[5].At(1).(*float64))
1234+
assert.EqualValues(t, 199, *frame.Fields[6].At(1).(*float64))
1235+
assert.EqualValues(t, 125, *frame.Fields[7].At(1).(*float64))
1236+
})
1237+
11611238
t.Run("Multiple metrics of same type", func(t *testing.T) {
11621239
targets := []tsdbQuery{{
11631240
refId: "A",

0 commit comments

Comments
 (0)