From 1246ad20f61602540f2a18dd56b1d0aeb5640785 Mon Sep 17 00:00:00 2001 From: Saurabh Narkhede <108730956+pm-saurabh-narkhede@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:59:11 +0530 Subject: [PATCH] UOE-10822: Prometheus Stat for Bid Recovery (#851) * stat for bid recovery * change buckets * introduce new stat --- .../openwrap/metrics/config/multimetrics.go | 14 +++++++++ .../metrics/config/multimetrics_test.go | 4 +++ modules/pubmatic/openwrap/metrics/metrics.go | 2 ++ .../pubmatic/openwrap/metrics/mock/mock.go | 24 +++++++++++++++ .../openwrap/metrics/prometheus/prometheus.go | 30 +++++++++++++++++++ .../metrics/prometheus/prometheus_test.go | 24 +++++++++++++++ .../openwrap/metrics/stats/tcp_stats.go | 3 ++ 7 files changed, 101 insertions(+) diff --git a/modules/pubmatic/openwrap/metrics/config/multimetrics.go b/modules/pubmatic/openwrap/metrics/config/multimetrics.go index 72a31262ea5..405a15cb20e 100644 --- a/modules/pubmatic/openwrap/metrics/config/multimetrics.go +++ b/modules/pubmatic/openwrap/metrics/config/multimetrics.go @@ -529,3 +529,17 @@ func (me *MultiMetricsEngine) RecordSignalDataStatus(pubid, profileid, signalTyp thisME.RecordSignalDataStatus(pubid, profileid, signalType) } } + +// RecordBidRecoveryStatus across all engines +func (me *MultiMetricsEngine) RecordBidRecoveryStatus(publisher, profile string, success bool) { + for _, thisME := range *me { + thisME.RecordBidRecoveryStatus(publisher, profile, success) + } +} + +// RecordBidRecoveryResponseTime across all engines +func (me *MultiMetricsEngine) RecordBidRecoveryResponseTime(publisher, profile string, responseTime time.Duration) { + for _, thisME := range *me { + thisME.RecordBidRecoveryResponseTime(publisher, profile, responseTime) + } +} diff --git a/modules/pubmatic/openwrap/metrics/config/multimetrics_test.go b/modules/pubmatic/openwrap/metrics/config/multimetrics_test.go index 2b206de8715..554ae4dc438 100644 --- a/modules/pubmatic/openwrap/metrics/config/multimetrics_test.go +++ b/modules/pubmatic/openwrap/metrics/config/multimetrics_test.go @@ -223,6 +223,8 @@ func TestRecordFunctionForMultiMetricsEngine(t *testing.T) { mockEngine.EXPECT().RecordOWServerPanic("endpoint", "methodName", "nodeName", "podName") mockEngine.EXPECT().RecordAmpVideoRequests("pubid", "profileid") mockEngine.EXPECT().RecordAmpVideoResponses("pubid", "profileid") + mockEngine.EXPECT().RecordBidRecoveryStatus(publisher, profile, true) + mockEngine.EXPECT().RecordBidRecoveryResponseTime(publisher, profile, time.Duration(200)) // create the multi-metric engine multiMetricEngine := MultiMetricsEngine{} @@ -291,4 +293,6 @@ func TestRecordFunctionForMultiMetricsEngine(t *testing.T) { multiMetricEngine.RecordOWServerPanic("endpoint", "methodName", "nodeName", "podName") multiMetricEngine.RecordAmpVideoRequests("pubid", "profileid") multiMetricEngine.RecordAmpVideoResponses("pubid", "profileid") + multiMetricEngine.RecordBidRecoveryStatus(publisher, profile, true) + multiMetricEngine.RecordBidRecoveryResponseTime(publisher, profile, time.Duration(200)) } diff --git a/modules/pubmatic/openwrap/metrics/metrics.go b/modules/pubmatic/openwrap/metrics/metrics.go index dfe45a8d500..6af13a88689 100644 --- a/modules/pubmatic/openwrap/metrics/metrics.go +++ b/modules/pubmatic/openwrap/metrics/metrics.go @@ -25,6 +25,8 @@ type MetricsEngine interface { RecordPublisherRequests(endpoint string, publisher string, platform string) RecordReqImpsWithContentCount(publisher, contentType string) RecordInjectTrackerErrorCount(adformat, publisher, partner string) + RecordBidRecoveryStatus(publisher, profile string, success bool) + RecordBidRecoveryResponseTime(publisher, profile string, responseTime time.Duration) // not-captured in openwrap module, dont provide enough insights RecordPBSAuctionRequestsStats() diff --git a/modules/pubmatic/openwrap/metrics/mock/mock.go b/modules/pubmatic/openwrap/metrics/mock/mock.go index b98fde7c783..d70dc6a196c 100644 --- a/modules/pubmatic/openwrap/metrics/mock/mock.go +++ b/modules/pubmatic/openwrap/metrics/mock/mock.go @@ -815,6 +815,30 @@ func (mr *MockMetricsEngineMockRecorder) RecordVideoInstlImpsStats(arg0, arg1 in return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordVideoInstlImpsStats", reflect.TypeOf((*MockMetricsEngine)(nil).RecordVideoInstlImpsStats), arg0, arg1) } +// RecordBidRecoveryStatus mocks base method. +func (m *MockMetricsEngine) RecordBidRecoveryStatus(arg0 string, arg1 string, arg2 bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RecordBidRecoveryStatus", arg0, arg1, arg2) +} + +// RecordBidRecoveryStatus indicates an expected call of RecordBidRecoveryStatus. +func (mr *MockMetricsEngineMockRecorder) RecordBidRecoveryStatus(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordBidRecoveryStatus", reflect.TypeOf((*MockMetricsEngine)(nil).RecordBidRecoveryStatus), arg0, arg1, arg2) +} + +// RecordBidRecoveryResponseTime mocks base method. +func (m *MockMetricsEngine) RecordBidRecoveryResponseTime(arg0 string, arg1 string, arg2 time.Duration) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RecordBidRecoveryResponseTime", arg0, arg1, arg2) +} + +// RecordBidRecoveryResponseTime indicates an expected call of RecordBidRecoveryStatus. +func (mr *MockMetricsEngineMockRecorder) RecordBidRecoveryResponseTime(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordBidRecoveryResponseTime", reflect.TypeOf((*MockMetricsEngine)(nil).RecordBidRecoveryResponseTime), arg0, arg1, arg2) +} + // Shutdown mocks base method. func (m *MockMetricsEngine) Shutdown() { m.ctrl.T.Helper() diff --git a/modules/pubmatic/openwrap/metrics/prometheus/prometheus.go b/modules/pubmatic/openwrap/metrics/prometheus/prometheus.go index 2117caabaff..055cdf0a4ee 100644 --- a/modules/pubmatic/openwrap/metrics/prometheus/prometheus.go +++ b/modules/pubmatic/openwrap/metrics/prometheus/prometheus.go @@ -34,6 +34,8 @@ type Metrics struct { pubNoBidResponseErrors *prometheus.CounterVec pubResponseTime *prometheus.HistogramVec pubImpsWithContent *prometheus.CounterVec + pubBidRecoveryStatus *prometheus.CounterVec + pubBidRecoveryTime *prometheus.HistogramVec // publisher-partner-platform level metrics pubPartnerPlatformRequests *prometheus.CounterVec @@ -360,6 +362,19 @@ func newMetrics(cfg *config.PrometheusMetrics, promRegistry *prometheus.Registry []string{pubIdLabel, profileIDLabel}, ) + metrics.pubBidRecoveryTime = newHistogramVec(cfg, promRegistry, + "bid_recovery_response_time", + "Total time taken by request for secondary auction in ms at publisher profile level.", + []string{pubIDLabel, profileIDLabel}, + []float64{100, 200, 300, 400}, + ) + + metrics.pubBidRecoveryStatus = newCounter(cfg, promRegistry, + "bid_recovery_response_status", + "Count bid recovery status for secondary auction", + []string{pubIDLabel, profileIDLabel, successLabel}, + ) + newSSHBMetrics(&metrics, cfg, promRegistry) return &metrics @@ -680,3 +695,18 @@ func (m *Metrics) RecordPrebidCacheRequestTime(success bool, length time.Duratio successLabel: strconv.FormatBool(success), }).Observe(float64(length.Milliseconds())) } + +func (m *Metrics) RecordBidRecoveryStatus(publisherID, profileID string, success bool) { + m.pubBidRecoveryStatus.With(prometheus.Labels{ + pubIDLabel: publisherID, + profileIDLabel: profileID, + successLabel: strconv.FormatBool(success), + }).Inc() +} + +func (m *Metrics) RecordBidRecoveryResponseTime(publisherID, profileID string, responseTime time.Duration) { + m.pubBidRecoveryTime.With(prometheus.Labels{ + pubIDLabel: publisherID, + profileIDLabel: profileID, + }).Observe(float64(responseTime.Milliseconds())) +} diff --git a/modules/pubmatic/openwrap/metrics/prometheus/prometheus_test.go b/modules/pubmatic/openwrap/metrics/prometheus/prometheus_test.go index faff7bb23dc..9872b7356a9 100644 --- a/modules/pubmatic/openwrap/metrics/prometheus/prometheus_test.go +++ b/modules/pubmatic/openwrap/metrics/prometheus/prometheus_test.go @@ -374,6 +374,30 @@ func TestRecordAdruleValidationFailure(t *testing.T) { }) } +func TestRecordBidRecoveryStatus(t *testing.T) { + m := createMetricsForTesting() + + m.RecordBidRecoveryStatus("5890", "123", true) + + expectedCount := float64(1) + assertCounterVecValue(t, "", "bid_recovery_response_status", m.pubBidRecoveryStatus, + expectedCount, prometheus.Labels{ + pubIDLabel: "5890", + profileIDLabel: "123", + successLabel: "true", + }) +} + +func TestRecordBidRecoveryResponseTime(t *testing.T) { + m := createMetricsForTesting() + + m.RecordBidRecoveryResponseTime("5890", "12345", time.Duration(70)*time.Millisecond) + m.RecordBidRecoveryResponseTime("5890", "12345", time.Duration(130)*time.Millisecond) + resultingHistogram := getHistogramFromHistogramVecByTwoKeys(m.pubBidRecoveryTime, + pubIDLabel, "5890", profileIDLabel, "12345") + assertHistogram(t, "bid_recovery_response_time", resultingHistogram, 2, 200) +} + func getHistogramFromHistogramVec(histogram *prometheus.HistogramVec, labelKey, labelValue string) dto.Histogram { var result dto.Histogram processMetrics(histogram, func(m dto.Metric) { diff --git a/modules/pubmatic/openwrap/metrics/stats/tcp_stats.go b/modules/pubmatic/openwrap/metrics/stats/tcp_stats.go index 94ba5931eaa..82599a54489 100644 --- a/modules/pubmatic/openwrap/metrics/stats/tcp_stats.go +++ b/modules/pubmatic/openwrap/metrics/stats/tcp_stats.go @@ -350,5 +350,8 @@ func (st *StatsTCP) RecordAdruleEnabled(pubId, profId string) func (st *StatsTCP) RecordAdruleValidationFailure(pubId, profId string) {} func (st *StatsTCP) RecordSignalDataStatus(pubid, profileid, signalType string) {} func (st *StatsTCP) RecordPrebidCacheRequestTime(success bool, length time.Duration) {} +func (st *StatsTCP) RecordBidRecoveryStatus(pubID string, profile string, success bool) {} +func (st *StatsTCP) RecordBidRecoveryResponseTime(pubID string, profile string, responseTime time.Duration) { +} func (st *StatsTCP) RecordPrebidAuctionBidResponse(publisher string, partnerName string, bidderCode string, adapterCode string) { }