loki: backend-mode: add stats support (#46526)
* loki: backend-mode: add stats support * refactor: rename variable
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/loki/pkg/loghttp"
|
||||
"github.com/grafana/loki/pkg/logqlmodel/stats"
|
||||
)
|
||||
|
||||
func parseResponse(value *loghttp.QueryResponse, query *lokiQuery) (data.Frames, error) {
|
||||
@@ -23,19 +24,20 @@ func parseResponse(value *loghttp.QueryResponse, query *lokiQuery) (data.Frames,
|
||||
}
|
||||
|
||||
func lokiResponseToDataFrames(value *loghttp.QueryResponse, query *lokiQuery) (data.Frames, error) {
|
||||
stats := parseStats(value.Data.Statistics)
|
||||
switch res := value.Data.Result.(type) {
|
||||
case loghttp.Matrix:
|
||||
return lokiMatrixToDataFrames(res, query), nil
|
||||
return lokiMatrixToDataFrames(res, query, stats), nil
|
||||
case loghttp.Vector:
|
||||
return lokiVectorToDataFrames(res, query), nil
|
||||
return lokiVectorToDataFrames(res, query, stats), nil
|
||||
case loghttp.Streams:
|
||||
return lokiStreamsToDataFrames(res, query), nil
|
||||
return lokiStreamsToDataFrames(res, query, stats), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("resultType %T not supported{", res)
|
||||
}
|
||||
}
|
||||
|
||||
func lokiMatrixToDataFrames(matrix loghttp.Matrix, query *lokiQuery) data.Frames {
|
||||
func lokiMatrixToDataFrames(matrix loghttp.Matrix, query *lokiQuery, stats []data.QueryStat) data.Frames {
|
||||
frames := data.Frames{}
|
||||
|
||||
for _, v := range matrix {
|
||||
@@ -56,6 +58,9 @@ func lokiMatrixToDataFrames(matrix loghttp.Matrix, query *lokiQuery) data.Frames
|
||||
valueField := data.NewField("", tags, values)
|
||||
|
||||
frame := data.NewFrame("", timeField, valueField)
|
||||
frame.SetMeta(&data.FrameMeta{
|
||||
Stats: stats,
|
||||
})
|
||||
|
||||
frames = append(frames, frame)
|
||||
}
|
||||
@@ -63,7 +68,7 @@ func lokiMatrixToDataFrames(matrix loghttp.Matrix, query *lokiQuery) data.Frames
|
||||
return frames
|
||||
}
|
||||
|
||||
func lokiVectorToDataFrames(vector loghttp.Vector, query *lokiQuery) data.Frames {
|
||||
func lokiVectorToDataFrames(vector loghttp.Vector, query *lokiQuery, stats []data.QueryStat) data.Frames {
|
||||
frames := data.Frames{}
|
||||
|
||||
for _, v := range vector {
|
||||
@@ -78,6 +83,9 @@ func lokiVectorToDataFrames(vector loghttp.Vector, query *lokiQuery) data.Frames
|
||||
valueField := data.NewField("", tags, values)
|
||||
|
||||
frame := data.NewFrame("", timeField, valueField)
|
||||
frame.SetMeta(&data.FrameMeta{
|
||||
Stats: stats,
|
||||
})
|
||||
|
||||
frames = append(frames, frame)
|
||||
}
|
||||
@@ -85,7 +93,7 @@ func lokiVectorToDataFrames(vector loghttp.Vector, query *lokiQuery) data.Frames
|
||||
return frames
|
||||
}
|
||||
|
||||
func lokiStreamsToDataFrames(streams loghttp.Streams, query *lokiQuery) data.Frames {
|
||||
func lokiStreamsToDataFrames(streams loghttp.Streams, query *lokiQuery, stats []data.QueryStat) data.Frames {
|
||||
frames := data.Frames{}
|
||||
|
||||
for _, v := range streams {
|
||||
@@ -106,9 +114,68 @@ func lokiStreamsToDataFrames(streams loghttp.Streams, query *lokiQuery) data.Fra
|
||||
valueField := data.NewField("", tags, values)
|
||||
|
||||
frame := data.NewFrame("", timeField, valueField)
|
||||
frame.SetMeta(&data.FrameMeta{
|
||||
Stats: stats,
|
||||
})
|
||||
|
||||
frames = append(frames, frame)
|
||||
}
|
||||
|
||||
return frames
|
||||
}
|
||||
|
||||
func parseStats(result stats.Result) []data.QueryStat {
|
||||
data := []data.QueryStat{
|
||||
makeStat("Summary: bytes processed per second", float64(result.Summary.BytesProcessedPerSecond), "Bps"),
|
||||
makeStat("Summary: lines processed per second", float64(result.Summary.LinesProcessedPerSecond), ""),
|
||||
makeStat("Summary: total bytes processed", float64(result.Summary.TotalBytesProcessed), "decbytes"),
|
||||
makeStat("Summary: total lines processed", float64(result.Summary.TotalLinesProcessed), ""),
|
||||
makeStat("Summary: exec time", result.Summary.ExecTime, "s"),
|
||||
makeStat("Store: total chunks ref", float64(result.Store.TotalChunksRef), ""),
|
||||
makeStat("Store: total chunks downloaded", float64(result.Store.TotalChunksDownloaded), ""),
|
||||
makeStat("Store: chunks download time", result.Store.ChunksDownloadTime, "s"),
|
||||
makeStat("Store: head chunk bytes", float64(result.Store.HeadChunkBytes), "decbytes"),
|
||||
makeStat("Store: head chunk lines", float64(result.Store.HeadChunkLines), ""),
|
||||
makeStat("Store: decompressed bytes", float64(result.Store.DecompressedBytes), "decbytes"),
|
||||
makeStat("Store: decompressed lines", float64(result.Store.DecompressedLines), ""),
|
||||
makeStat("Store: compressed bytes", float64(result.Store.CompressedBytes), "decbytes"),
|
||||
makeStat("Store: total duplicates", float64(result.Store.TotalDuplicates), ""),
|
||||
makeStat("Ingester: total reached", float64(result.Ingester.TotalReached), ""),
|
||||
makeStat("Ingester: total chunks matched", float64(result.Ingester.TotalChunksMatched), ""),
|
||||
makeStat("Ingester: total batches", float64(result.Ingester.TotalBatches), ""),
|
||||
makeStat("Ingester: total lines sent", float64(result.Ingester.TotalLinesSent), ""),
|
||||
makeStat("Ingester: head chunk bytes", float64(result.Ingester.HeadChunkBytes), "decbytes"),
|
||||
makeStat("Ingester: head chunk lines", float64(result.Ingester.HeadChunkLines), ""),
|
||||
makeStat("Ingester: decompressed bytes", float64(result.Ingester.DecompressedBytes), "decbytes"),
|
||||
makeStat("Ingester: decompressed lines", float64(result.Ingester.DecompressedLines), ""),
|
||||
makeStat("Ingester: compressed bytes", float64(result.Ingester.CompressedBytes), "decbytes"),
|
||||
makeStat("Ingester: total duplicates", float64(result.Ingester.TotalDuplicates), ""),
|
||||
}
|
||||
|
||||
// it is not possible to know whether the given statistics was missing, or
|
||||
// it's value was zero.
|
||||
// we do a heuristic here, if every stat-value is zero, we assume we got no stats-data
|
||||
allStatsZero := true
|
||||
for _, stat := range data {
|
||||
if stat.Value > 0 {
|
||||
allStatsZero = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if allStatsZero {
|
||||
return nil
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func makeStat(name string, value float64, unit string) data.QueryStat {
|
||||
return data.QueryStat{
|
||||
FieldConfig: data.FieldConfig{
|
||||
DisplayName: name,
|
||||
Unit: unit,
|
||||
},
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user