From b214f9cc3a2fc07593baf7f678ab941312e6bcc7 Mon Sep 17 00:00:00 2001 From: Leonor Oliveira <9090754+leonorfmartins@users.noreply.github.com> Date: Mon, 13 May 2024 10:36:24 +0100 Subject: [PATCH] Add metrics utils to the dualwriter (#87693) * Add metrics utils * Ignore lint temporarily * Lint --- pkg/apiserver/rest/dualwriter_mode1.go | 5 ++- pkg/apiserver/rest/dualwriter_mode2.go | 5 ++- pkg/apiserver/rest/dualwriter_mode3.go | 5 ++- pkg/apiserver/rest/dualwriter_mode4.go | 5 ++- pkg/apiserver/rest/metrics.go | 54 ++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 pkg/apiserver/rest/metrics.go diff --git a/pkg/apiserver/rest/dualwriter_mode1.go b/pkg/apiserver/rest/dualwriter_mode1.go index 75651998784..6fbb350a95d 100644 --- a/pkg/apiserver/rest/dualwriter_mode1.go +++ b/pkg/apiserver/rest/dualwriter_mode1.go @@ -14,12 +14,15 @@ type DualWriterMode1 struct { Legacy LegacyStorage Storage Storage Log klog.Logger + *dualWriterMetrics } // NewDualWriterMode1 returns a new DualWriter in mode 1. // Mode 1 represents writing to and reading from LegacyStorage. func NewDualWriterMode1(legacy LegacyStorage, storage Storage) *DualWriterMode1 { - return &DualWriterMode1{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode1")} + metrics := &dualWriterMetrics{} + metrics.init() + return &DualWriterMode1{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode1"), dualWriterMetrics: metrics} } // Create overrides the behavior of the generic DualWriter and writes only to LegacyStorage. diff --git a/pkg/apiserver/rest/dualwriter_mode2.go b/pkg/apiserver/rest/dualwriter_mode2.go index 7fa8d2b0199..6be6797ec16 100644 --- a/pkg/apiserver/rest/dualwriter_mode2.go +++ b/pkg/apiserver/rest/dualwriter_mode2.go @@ -19,12 +19,15 @@ type DualWriterMode2 struct { Storage Storage Legacy LegacyStorage Log klog.Logger + *dualWriterMetrics } // NewDualWriterMode2 returns a new DualWriter in mode 2. // Mode 2 represents writing to LegacyStorage and Storage and reading from LegacyStorage. func NewDualWriterMode2(legacy LegacyStorage, storage Storage) *DualWriterMode2 { - return &DualWriterMode2{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode2")} + metrics := &dualWriterMetrics{} + metrics.init() + return &DualWriterMode2{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode2"), dualWriterMetrics: metrics} } // Create overrides the behavior of the generic DualWriter and writes to LegacyStorage and Storage. diff --git a/pkg/apiserver/rest/dualwriter_mode3.go b/pkg/apiserver/rest/dualwriter_mode3.go index 3520d302f52..b0f2630143d 100644 --- a/pkg/apiserver/rest/dualwriter_mode3.go +++ b/pkg/apiserver/rest/dualwriter_mode3.go @@ -15,12 +15,15 @@ type DualWriterMode3 struct { Legacy LegacyStorage Storage Storage Log klog.Logger + *dualWriterMetrics } // NewDualWriterMode3 returns a new DualWriter in mode 3. // Mode 3 represents writing to LegacyStorage and Storage and reading from Storage. func NewDualWriterMode3(legacy LegacyStorage, storage Storage) *DualWriterMode3 { - return &DualWriterMode3{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode3")} + metrics := &dualWriterMetrics{} + metrics.init() + return &DualWriterMode3{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode3"), dualWriterMetrics: metrics} } // Create overrides the behavior of the generic DualWriter and writes to LegacyStorage and Storage. diff --git a/pkg/apiserver/rest/dualwriter_mode4.go b/pkg/apiserver/rest/dualwriter_mode4.go index d562c73f042..ef0847cfcaf 100644 --- a/pkg/apiserver/rest/dualwriter_mode4.go +++ b/pkg/apiserver/rest/dualwriter_mode4.go @@ -14,12 +14,15 @@ type DualWriterMode4 struct { Legacy LegacyStorage Storage Storage Log klog.Logger + *dualWriterMetrics } // NewDualWriterMode4 returns a new DualWriter in mode 4. // Mode 4 represents writing and reading from Storage. func NewDualWriterMode4(legacy LegacyStorage, storage Storage) *DualWriterMode4 { - return &DualWriterMode4{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode4")} + metrics := &dualWriterMetrics{} + metrics.init() + return &DualWriterMode4{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode4"), dualWriterMetrics: metrics} } // #TODO remove all DualWriterMode4 methods once we remove the generic DualWriter implementation diff --git a/pkg/apiserver/rest/metrics.go b/pkg/apiserver/rest/metrics.go new file mode 100644 index 00000000000..36706efeec7 --- /dev/null +++ b/pkg/apiserver/rest/metrics.go @@ -0,0 +1,54 @@ +package rest + +import "github.com/prometheus/client_golang/prometheus" + +type dualWriterMetrics struct { + legacy *prometheus.HistogramVec + storage *prometheus.HistogramVec + outcome *prometheus.HistogramVec +} + +// DualWriterStorageDuration is a metric summary for dual writer storage duration per mode +var DualWriterStorageDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Name: "dual_writer_storage_duration_seconds", + Help: "Histogram for the runtime of dual writer storage duration per mode", + Namespace: "grafana", + NativeHistogramBucketFactor: 1.1, +}, []string{"status_code", "mode", "name", "method"}) + +// DualWriterLegacyDuration is a metric summary for dual writer legacy duration per mode +var DualWriterLegacyDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Name: "dual_writer_legacy_duration_seconds", + Help: "Histogram for the runtime of dual writer legacy duration per mode", + Namespace: "grafana", + NativeHistogramBucketFactor: 1.1, +}, []string{"status_code", "mode", "name", "method"}) + +// DualWriterOutcome is a metric summary for dual writer outcome comparison between the 2 stores per mode +var DualWriterOutcome = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Name: "dual_writer_outcome", + Help: "Histogram for the runtime of dual writer outcome comparison between the 2 stores per mode", + Namespace: "grafana", + NativeHistogramBucketFactor: 1.1, +}, []string{"mode", "name", "outcome", "method"}) + +func (m *dualWriterMetrics) init() { + m.legacy = DualWriterLegacyDuration + m.storage = DualWriterStorageDuration + m.outcome = DualWriterOutcome +} + +// nolint:unused +func (m *dualWriterMetrics) recordLegacyDuration(statusCode string, mode string, name string, method string, duration float64) { + m.legacy.WithLabelValues(statusCode, mode, name, method).Observe(duration) +} + +// nolint:unused +func (m *dualWriterMetrics) recordStorageDuration(statusCode string, mode string, name string, method string, duration float64) { + m.storage.WithLabelValues(statusCode, mode, name, method).Observe(duration) +} + +// nolint:unused +func (m *dualWriterMetrics) recordOutcome(mode string, name string, outcome string, method string) { + m.outcome.WithLabelValues(mode, name, outcome, method).Observe(1) +}