Wire up data source config metrics correctly

Fix metrics for data source configuration CRUD.

Make sure to only create one histogram and only register it with prometheus once.
This commit is contained in:
beejeebus
2025-12-10 16:16:22 -05:00
parent 30045c02c0
commit e433cfa02d
2 changed files with 39 additions and 21 deletions
@@ -57,6 +57,11 @@ func (s *legacyStorage) ConvertToTable(ctx context.Context, object runtime.Objec
}
func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
start := time.Now()
defer func() {
metricutil.ObserveWithExemplar(ctx, s.dsConfigHandlerRequestsDuration.WithLabelValues("new", "List"), time.Since(start).Seconds())
}()
return s.datasources.ListDataSources(ctx)
}
+34 -21
View File
@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"maps"
"sync"
"github.com/prometheus/client_golang/prometheus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -39,15 +40,18 @@ var (
type DataSourceAPIBuilder struct {
datasourceResourceInfo utils.ResourceInfo
pluginJSON plugins.JSONData
client PluginClient // will only ever be called with the same plugin id!
datasources PluginDatasourceProvider
contextProvider PluginContextWrapper
accessControl accesscontrol.AccessControl
queryTypes *queryV0.QueryTypeDefinitionList
configCrudUseNewApis bool
pluginJSON plugins.JSONData
client PluginClient // will only ever be called with the same plugin id!
datasources PluginDatasourceProvider
contextProvider PluginContextWrapper
accessControl accesscontrol.AccessControl
queryTypes *queryV0.QueryTypeDefinitionList
configCrudUseNewApis bool
dsConfigHandlerRequestsDuration *prometheus.HistogramVec
}
var dsConfigHandlerRequestsDuration *prometheus.HistogramVec
func RegisterAPIService(
features featuremgmt.FeatureToggles,
apiRegistrar builder.APIRegistrar,
@@ -63,6 +67,15 @@ func RegisterAPIService(
return nil, nil
}
sync.OnceFunc(func() {
dsConfigHandlerRequestsDuration = metricutil.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "grafana",
Name: "ds_config_handler_k8s_requests_duration_seconds",
Help: "Duration of requests handled by datasource configuration handlers",
}, []string{"code_path", "handler"})
reg.MustRegister(dsConfigHandlerRequestsDuration)
})()
var err error
var builder *DataSourceAPIBuilder
@@ -87,6 +100,7 @@ func RegisterAPIService(
features.IsEnabledGlobally(featuremgmt.FlagDatasourceQueryTypes),
//nolint:staticcheck // not yet migrated to OpenFeature
features.IsEnabledGlobally(featuremgmt.FlagQueryServiceWithConnections),
dsConfigHandlerRequestsDuration,
)
if err != nil {
return nil, err
@@ -114,6 +128,7 @@ func NewDataSourceAPIBuilder(
accessControl accesscontrol.AccessControl,
loadQueryTypes bool,
configCrudUseNewApis bool,
dsConfigHandlerRequestsDuration *prometheus.HistogramVec,
) (*DataSourceAPIBuilder, error) {
group, err := plugins.GetDatasourceGroupNameFromPluginID(plugin.ID)
if err != nil {
@@ -121,13 +136,14 @@ func NewDataSourceAPIBuilder(
}
builder := &DataSourceAPIBuilder{
datasourceResourceInfo: datasourceV0.DataSourceResourceInfo.WithGroupAndShortName(group, plugin.ID),
pluginJSON: plugin,
client: client,
datasources: datasources,
contextProvider: contextProvider,
accessControl: accessControl,
configCrudUseNewApis: configCrudUseNewApis,
datasourceResourceInfo: datasourceV0.DataSourceResourceInfo.WithGroupAndShortName(group, plugin.ID),
pluginJSON: plugin,
client: client,
datasources: datasources,
contextProvider: contextProvider,
accessControl: accessControl,
configCrudUseNewApis: configCrudUseNewApis,
dsConfigHandlerRequestsDuration: dsConfigHandlerRequestsDuration,
}
if loadQueryTypes {
// In the future, this will somehow come from the plugin
@@ -218,14 +234,11 @@ func (b *DataSourceAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver
if b.configCrudUseNewApis {
legacyStore := &legacyStorage{
datasources: b.datasources,
resourceInfo: &ds,
dsConfigHandlerRequestsDuration: metricutil.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "grafana",
Name: "ds_config_handler_requests_duration_seconds",
Help: "Duration of requests handled by datasource configuration handlers",
}, []string{"code_path", "handler"}),
datasources: b.datasources,
resourceInfo: &ds,
dsConfigHandlerRequestsDuration: b.dsConfigHandlerRequestsDuration,
}
unified, err := grafanaregistry.NewRegistryStore(opts.Scheme, ds, opts.OptsGetter)
if err != nil {
return err