Skip to content

Commit f5d62bd

Browse files
feat: present DF bytes values in queryable format (#15272)
1 parent c96b750 commit f5d62bd

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

‎pkg/querier/queryrange/detected_fields.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"net/http"
66
"slices"
77
"strconv"
8+
"strings"
89
"time"
910

1011
"github.com/axiomhq/hyperloglog"
@@ -114,7 +115,13 @@ func parseDetectedFieldValues(limit uint32, streams []push.Stream, name string)
114115
parsedLabels, _ := parseEntry(entry, entryLbls)
115116
if vals, ok := parsedLabels[name]; ok {
116117
for _, v := range vals {
117-
values[v] = struct{}{}
118+
// special case bytes values, so they can be directly inserted into a query
119+
if bs, err := humanize.ParseBytes(v); err == nil {
120+
bsString := strings.Replace(humanize.Bytes(bs), " ", "", 1)
121+
values[bsString] = struct{}{}
122+
} else {
123+
values[v] = struct{}{}
124+
}
118125
}
119126
}
120127
}

‎pkg/querier/queryrange/detected_fields_test.go

+65-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
"github.com/grafana/loki/pkg/push"
2525
)
2626

27-
func Test_parseDetectedFeilds(t *testing.T) {
27+
func Test_parseDetectedFields(t *testing.T) {
2828
now := time.Now()
2929

3030
t.Run("when no parsers are supplied", func(t *testing.T) {
@@ -1317,6 +1317,70 @@ func TestQuerier_DetectedFields(t *testing.T) {
13171317
}, secondValues)
13181318
},
13191319
)
1320+
1321+
t.Run("correctly formats bytes values for detected fields", func(t *testing.T) {
1322+
lbls := `{cluster="us-east-1", namespace="mimir-dev", pod="mimir-ruler-nfb37", service_name="mimir-ruler"}`
1323+
metric, err := parser.ParseMetric(lbls)
1324+
require.NoError(t, err)
1325+
now := time.Now()
1326+
1327+
infoDetectdFiledMetadata := []push.LabelAdapter{
1328+
{
1329+
Name: "detected_level",
1330+
Value: "info",
1331+
},
1332+
}
1333+
1334+
lines := []push.Entry{
1335+
{
1336+
Timestamp: now,
1337+
Line: "ts=2024-09-05T15:36:38.757788067Z caller=metrics.go:66 tenant=2419 level=info bytes=1,024",
1338+
StructuredMetadata: infoDetectdFiledMetadata,
1339+
},
1340+
{
1341+
Timestamp: now,
1342+
Line: `ts=2024-09-05T15:36:38.698375619Z caller=grpc_logging.go:66 tenant=29 level=info bytes="1024 MB"`,
1343+
StructuredMetadata: infoDetectdFiledMetadata,
1344+
},
1345+
{
1346+
Timestamp: now,
1347+
Line: "ts=2024-09-05T15:36:38.629424175Z caller=grpc_logging.go:66 tenant=2919 level=info bytes=1024KB",
1348+
StructuredMetadata: infoDetectdFiledMetadata,
1349+
},
1350+
}
1351+
stream := push.Stream{
1352+
Labels: lbls,
1353+
Entries: lines,
1354+
Hash: metric.Hash(),
1355+
}
1356+
1357+
handler := NewDetectedFieldsHandler(
1358+
limitedHandler(stream),
1359+
logHandler(stream),
1360+
limits,
1361+
)
1362+
1363+
request := DetectedFieldsRequest{
1364+
logproto.DetectedFieldsRequest{
1365+
Start: time.Now().Add(-1 * time.Minute),
1366+
End: time.Now(),
1367+
Query: `{cluster="us-east-1"} | logfmt`,
1368+
LineLimit: 1000,
1369+
Limit: 3,
1370+
Values: true,
1371+
Name: "bytes",
1372+
},
1373+
"/loki/api/v1/detected_field/bytes/values",
1374+
}
1375+
1376+
detectedFieldValues := handleRequest(handler, request).Values
1377+
slices.Sort(detectedFieldValues)
1378+
require.Equal(t, []string{
1379+
"1.0GB",
1380+
"1.0MB",
1381+
"1.0kB",
1382+
}, detectedFieldValues)
1383+
})
13201384
}
13211385

13221386
func BenchmarkQuerierDetectedFields(b *testing.B) {

0 commit comments

Comments
 (0)