From cb28213f1d1e40a16071b27bf3519d486de4f77f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mustafa=20Sencer=20=C3=96zcan?= <32759850+mustafasencer@users.noreply.github.com> Date: Mon, 12 May 2025 09:18:06 +0200 Subject: [PATCH] chore(unified-storage): add dual writer metric to track instance modes (#105144) --- pkg/services/apiserver/builder/helper.go | 5 ++++ pkg/services/apiserver/builder/metrics.go | 30 +++++++++++++++++++++++ pkg/services/apiserver/service.go | 4 +-- 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 pkg/services/apiserver/builder/metrics.go diff --git a/pkg/services/apiserver/builder/helper.go b/pkg/services/apiserver/builder/helper.go index bfd9040e9c2..3b0f0a45eb8 100644 --- a/pkg/services/apiserver/builder/helper.go +++ b/pkg/services/apiserver/builder/helper.go @@ -298,6 +298,7 @@ func InstallAPIs( // this is needed to support setting a default RESTOptionsGetter for new APIs that don't // support the legacy storage type. var dualWrite grafanarest.DualWriteBuilder + metrics := newBuilderMetrics(reg) // nolint:staticcheck if storageOpts.StorageType != options.StorageTypeLegacy { @@ -359,6 +360,9 @@ func InstallAPIs( if err != nil { return nil, err } + + metrics.recordDualWriterModes(gr.Resource, gr.Group, mode, currentMode) + switch currentMode { case grafanarest.Mode0: return legacy, nil @@ -366,6 +370,7 @@ func InstallAPIs( return storage, nil default: } + if dualWriterPeriodicDataSyncJobEnabled { // The mode might have changed in SetDualWritingMode, so apply current mode first. syncerCfg.Mode = currentMode diff --git a/pkg/services/apiserver/builder/metrics.go b/pkg/services/apiserver/builder/metrics.go new file mode 100644 index 00000000000..663c24902c1 --- /dev/null +++ b/pkg/services/apiserver/builder/metrics.go @@ -0,0 +1,30 @@ +package builder + +import ( + grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +type builderMetrics struct { + dualWriterTargetMode *prometheus.GaugeVec + dualWriterCurrentMode *prometheus.GaugeVec +} + +func newBuilderMetrics(reg prometheus.Registerer) *builderMetrics { + return &builderMetrics{ + dualWriterTargetMode: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ + Name: "unified_storage_dual_writer_target_mode", + Help: "Unified Storage dual writer target mode", + }, []string{"resource", "group"}), + dualWriterCurrentMode: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ + Name: "unified_storage_dual_writer_current_mode", + Help: "Unified storage dual writer current mode", + }, []string{"resource", "group"}), + } +} + +func (m *builderMetrics) recordDualWriterModes(resource, group string, targetMode, currentMode grafanarest.DualWriterMode) { + m.dualWriterTargetMode.WithLabelValues(resource, group).Set(float64(targetMode)) + m.dualWriterCurrentMode.WithLabelValues(resource, group).Set(float64(currentMode)) +} diff --git a/pkg/services/apiserver/service.go b/pkg/services/apiserver/service.go index ee82a148919..56a33f6f98f 100644 --- a/pkg/services/apiserver/service.go +++ b/pkg/services/apiserver/service.go @@ -27,7 +27,6 @@ import ( "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/kvstore" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/infra/serverlock" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/middleware" @@ -122,6 +121,7 @@ func ProvideService( restConfigProvider RestConfigProvider, buildHandlerChainFuncFromBuilders builder.BuildHandlerChainFuncFromBuilders, eventualRestConfigProvider *eventualRestConfigProvider, + reg prometheus.Registerer, ) (*service, error) { scheme := builder.ProvideScheme() codecs := builder.ProvideCodecFactory(scheme) @@ -137,7 +137,7 @@ func ProvideService( authorizer: authorizer.NewGrafanaAuthorizer(cfg), tracing: tracing, db: db, // For Unified storage - metrics: metrics.ProvideRegisterer(), + metrics: reg, kvStore: kvStore, pluginClient: pluginClient, datasources: datasources,