grafana/pkg/services/searchV2/usage.go

79 lines
2.4 KiB
Go

package searchV2
import (
"context"
"github.com/blugelabs/bluge"
"github.com/blugelabs/bluge/search"
"github.com/blugelabs/bluge/search/aggregations"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
)
type usageGauge struct {
field string
gauge *prometheus.GaugeVec
}
var (
infoPanelUsage = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "panel_type_usage",
Help: "a metric indicating how many panels across all dashboards use each plugin panel type",
Namespace: "grafana",
}, []string{"name"})
infoDatasourceUsage = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "panel_datasource_usage",
Help: "indicates how many panels across all dashboards reference each datasource type",
Namespace: "grafana",
}, []string{"name"})
infoTransformerUsage = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "panel_transformer_usage",
Help: "indicates how many panels use each transformer type",
Namespace: "grafana",
}, []string{"name"})
panelUsage = []usageGauge{
{field: documentFieldDSType, gauge: infoDatasourceUsage},
{field: documentFieldPanelType, gauge: infoPanelUsage},
{field: documentFieldTransformer, gauge: infoTransformerUsage},
}
)
func updateUsageStats(ctx context.Context, reader *bluge.Reader, logger log.Logger, tracer tracing.Tracer) {
ctx, span := tracer.Start(ctx, "searchV2 updateUsageStats")
defer span.End()
req := bluge.NewAllMatches(bluge.NewTermQuery("panel").SetField(documentFieldKind))
for _, usage := range panelUsage {
req.AddAggregation(usage.field, aggregations.NewTermsAggregation(search.Field(usage.field), 50))
}
// execute this search on the reader
documentMatchIterator, err := reader.Search(ctx, req)
if err != nil {
logger.Error("Error executing search", "err", err)
return
}
// need to iterate through the document matches, otherwise the aggregations are empty?
match, err := documentMatchIterator.Next()
for err == nil && match != nil {
match, err = documentMatchIterator.Next()
}
aggs := documentMatchIterator.Aggregations()
for _, usage := range panelUsage {
bucket := aggs.Buckets(usage.field)
for _, v := range bucket {
if v.Name() == "" {
continue
}
usage.gauge.WithLabelValues(v.Name()).Set(float64(v.Count()))
}
}
}