diff --git a/modules/pubmatic/openwrap/metrics/config/multimetrics.go b/modules/pubmatic/openwrap/metrics/config/multimetrics.go index 8cc83fe9f0..2b2d282dbc 100644 --- a/modules/pubmatic/openwrap/metrics/config/multimetrics.go +++ b/modules/pubmatic/openwrap/metrics/config/multimetrics.go @@ -536,3 +536,17 @@ func (me *MultiMetricsEngine) RecordEndpointResponseSize(endpoint string, bodySi thisME.RecordEndpointResponseSize(endpoint, bodySize) } } + +// 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 db5276c638..fb5ef32cae 100644 --- a/modules/pubmatic/openwrap/metrics/config/multimetrics_test.go +++ b/modules/pubmatic/openwrap/metrics/config/multimetrics_test.go @@ -221,6 +221,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{} @@ -288,4 +290,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 fd740ee1cf..4f97931245 100644 --- a/modules/pubmatic/openwrap/metrics/metrics.go +++ b/modules/pubmatic/openwrap/metrics/metrics.go @@ -24,6 +24,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 41fd706e8f..fcd72ae30b 100644 --- a/modules/pubmatic/openwrap/metrics/mock/mock.go +++ b/modules/pubmatic/openwrap/metrics/mock/mock.go @@ -826,7 +826,31 @@ func (mr *MockMetricsEngineMockRecorder) RecordVideoInstlImpsStats(arg0, arg1 in return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordVideoInstlImpsStats", reflect.TypeOf((*MockMetricsEngine)(nil).RecordVideoInstlImpsStats), arg0, arg1) } -// Shutdown mocks base method +// 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() m.ctrl.Call(m, "Shutdown") diff --git a/modules/pubmatic/openwrap/metrics/prometheus/prometheus.go b/modules/pubmatic/openwrap/metrics/prometheus/prometheus.go index 0ee232cfea..d5dad53355 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 @@ -378,6 +380,19 @@ func newMetrics(cfg *config.PrometheusMetrics, promRegistry *prometheus.Registry responseSizeBuckets, ) + 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 @@ -700,6 +715,21 @@ func (m *Metrics) RecordPrebidCacheRequestTime(success bool, length time.Duratio }).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())) +} + func (m *Metrics) RecordEndpointResponseSize(endpoint string, bodySize float64) { m.endpointResponseSize.With(prometheus.Labels{ endpointLabel: endpoint, diff --git a/modules/pubmatic/openwrap/metrics/prometheus/prometheus_test.go b/modules/pubmatic/openwrap/metrics/prometheus/prometheus_test.go index d388ae9d67..2503dfd357 100644 --- a/modules/pubmatic/openwrap/metrics/prometheus/prometheus_test.go +++ b/modules/pubmatic/openwrap/metrics/prometheus/prometheus_test.go @@ -361,6 +361,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 6782ab4cf9..88275c5bde 100644 --- a/modules/pubmatic/openwrap/metrics/stats/tcp_stats.go +++ b/modules/pubmatic/openwrap/metrics/stats/tcp_stats.go @@ -345,6 +345,9 @@ 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) { } func (st *StatsTCP) RecordFailedParsingItuneID(pubId, profId string) {}