86 lines
2.8 KiB
Go
86 lines
2.8 KiB
Go
package usage
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/codes"
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
"k8s.io/apiserver/pkg/endpoints/request"
|
|
|
|
listers "github.com/grafana/grafana/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1"
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
|
"github.com/grafana/grafana/pkg/infra/usagestats"
|
|
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
|
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
|
)
|
|
|
|
func MetricCollector(tracer tracing.Tracer, repositoryLister listers.RepositoryLister, unified resource.ResourceClient) usagestats.MetricsFunc {
|
|
return func(ctx context.Context) (metrics map[string]any, err error) {
|
|
ctx, span := tracer.Start(ctx, "Provisioning.Usage.collectProvisioningStats")
|
|
defer func() {
|
|
span.SetStatus(codes.Error, fmt.Sprintf("failed to fetch provisioning usage stats: %v", err))
|
|
span.End()
|
|
}()
|
|
|
|
m := map[string]any{}
|
|
if unified == nil {
|
|
// FIXME: does this case make any sense? no unified storage -> no game
|
|
span.SetStatus(codes.Ok, "unified storage is not available")
|
|
return m, nil
|
|
}
|
|
|
|
// FIXME: hardcoded to "default" for now -- it works for single tenant deployments
|
|
// we could discover the set of valid namespaces, but that would count everything for
|
|
// each instance in cloud.
|
|
ns := "default"
|
|
ctx, _, err = identity.WithProvisioningIdentity(ctx, ns)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ctx = request.WithNamespace(ctx, ns)
|
|
|
|
// FIXME: hardcoded to "default" for now -- it works for single tenant deployments
|
|
// we could discover the set of valid namespaces, but that would count everything for
|
|
// each instance in cloud.
|
|
//
|
|
// We could get namespaces from the list of repos below, but that could be zero
|
|
// while we still have resources managed by terraform, etc
|
|
count, err := unified.CountManagedObjects(ctx, &resourcepb.CountManagedObjectsRequest{
|
|
Namespace: ns,
|
|
})
|
|
if err != nil {
|
|
return m, fmt.Errorf("count managed objects: %w", err)
|
|
}
|
|
counts := make(map[string]int, 10)
|
|
for _, v := range count.Items {
|
|
counts[v.Kind] = counts[v.Kind] + int(v.Count)
|
|
}
|
|
|
|
span.SetAttributes(attribute.Int("totalManagedObjectsCount", len(count.Items)))
|
|
for k, v := range counts {
|
|
m[fmt.Sprintf("stats.managed_by.%s.count", k)] = v
|
|
}
|
|
|
|
// Inspect all configs
|
|
repos, err := repositoryLister.List(labels.Everything())
|
|
if err != nil {
|
|
return m, fmt.Errorf("list repositories: %w", err)
|
|
}
|
|
clear(counts)
|
|
for _, repo := range repos {
|
|
counts[string(repo.Spec.Type)] = counts[string(repo.Spec.Type)] + 1
|
|
}
|
|
|
|
span.SetAttributes(attribute.Int("repositoryCount", len(repos)))
|
|
// Count how many items of each repository type
|
|
for k, v := range counts {
|
|
m[fmt.Sprintf("stats.repository.%s.count", k)] = v
|
|
}
|
|
|
|
return m, nil
|
|
}
|
|
}
|