diff --git a/pbsmetrics/config/metrics.go b/pbsmetrics/config/metrics.go index 903b17bfe6c..7fd048e1b2b 100644 --- a/pbsmetrics/config/metrics.go +++ b/pbsmetrics/config/metrics.go @@ -189,6 +189,13 @@ func (me *MultiMetricsEngine) RecordStoredImpCacheResult(cacheResult pbsmetrics. } } +// RecordAccountCacheResult across all engines +func (me *MultiMetricsEngine) RecordAccountCacheResult(cacheResult pbsmetrics.CacheResult, inc int) { + for _, thisME := range *me { + thisME.RecordAccountCacheResult(cacheResult, inc) + } +} + // RecordAdapterCookieSync across all engines func (me *MultiMetricsEngine) RecordAdapterCookieSync(adapter openrtb_ext.BidderName, gdprBlocked bool) { for _, thisME := range *me { @@ -314,6 +321,10 @@ func (me *DummyMetricsEngine) RecordStoredReqCacheResult(cacheResult pbsmetrics. func (me *DummyMetricsEngine) RecordStoredImpCacheResult(cacheResult pbsmetrics.CacheResult, inc int) { } +// RecordAccountCacheResult as a noop +func (me *DummyMetricsEngine) RecordAccountCacheResult(cacheResult pbsmetrics.CacheResult, inc int) { +} + // RecordPrebidCacheRequestTime as a noop func (me *DummyMetricsEngine) RecordPrebidCacheRequestTime(success bool, length time.Duration) { } diff --git a/pbsmetrics/config/metrics_test.go b/pbsmetrics/config/metrics_test.go index d2374f95195..c95a7827ebb 100644 --- a/pbsmetrics/config/metrics_test.go +++ b/pbsmetrics/config/metrics_test.go @@ -116,6 +116,13 @@ func TestMultiMetricsEngine(t *testing.T) { metricsEngine.RecordImps(impTypeLabels) } + metricsEngine.RecordStoredReqCacheResult(pbsmetrics.CacheMiss, 1) + metricsEngine.RecordStoredImpCacheResult(pbsmetrics.CacheMiss, 2) + metricsEngine.RecordAccountCacheResult(pbsmetrics.CacheMiss, 3) + metricsEngine.RecordStoredReqCacheResult(pbsmetrics.CacheHit, 4) + metricsEngine.RecordStoredImpCacheResult(pbsmetrics.CacheHit, 5) + metricsEngine.RecordAccountCacheResult(pbsmetrics.CacheHit, 6) + metricsEngine.RecordRequestQueueTime(false, pbsmetrics.ReqTypeVideo, time.Duration(1)) //Make the metrics engine, instantiated here with goEngine, fill its RequestStatuses[RequestType][pbsmetrics.RequestStatusXX] with the new boolean values added to pbsmetrics.Labels @@ -154,6 +161,13 @@ func TestMultiMetricsEngine(t *testing.T) { VerifyMetrics(t, "RecordRequestQueueTime.Video.Rejected", goEngine.RequestsQueueTimer[pbsmetrics.ReqTypeVideo][false].Count(), 1) VerifyMetrics(t, "RecordRequestQueueTime.Video.Accepted", goEngine.RequestsQueueTimer[pbsmetrics.ReqTypeVideo][true].Count(), 0) + + VerifyMetrics(t, "StoredReqCache.Miss", goEngine.StoredReqCacheMeter[pbsmetrics.CacheMiss].Count(), 1) + VerifyMetrics(t, "StoredImpCache.Miss", goEngine.StoredImpCacheMeter[pbsmetrics.CacheMiss].Count(), 2) + VerifyMetrics(t, "AccountCache.Miss", goEngine.AccountCacheMeter[pbsmetrics.CacheMiss].Count(), 3) + VerifyMetrics(t, "StoredReqCache.Hit", goEngine.StoredReqCacheMeter[pbsmetrics.CacheHit].Count(), 4) + VerifyMetrics(t, "StoredImpCache.Hit", goEngine.StoredImpCacheMeter[pbsmetrics.CacheHit].Count(), 5) + VerifyMetrics(t, "AccountCache.Hit", goEngine.AccountCacheMeter[pbsmetrics.CacheHit].Count(), 6) } func VerifyMetrics(t *testing.T, name string, actual int64, expected int64) { diff --git a/pbsmetrics/go_metrics.go b/pbsmetrics/go_metrics.go index 3842bfd246a..f3c6c1d2818 100644 --- a/pbsmetrics/go_metrics.go +++ b/pbsmetrics/go_metrics.go @@ -31,6 +31,7 @@ type Metrics struct { StoredDataErrorMeter map[StoredDataType]map[StoredDataError]metrics.Meter StoredReqCacheMeter map[CacheResult]metrics.Meter StoredImpCacheMeter map[CacheResult]metrics.Meter + AccountCacheMeter map[CacheResult]metrics.Meter DNSLookupTimer metrics.Timer // Metrics for OpenRTB requests specifically. So we can track what % of RequestsMeter are OpenRTB @@ -137,6 +138,7 @@ func NewBlankMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderNa StoredDataErrorMeter: make(map[StoredDataType]map[StoredDataError]metrics.Meter), StoredReqCacheMeter: make(map[CacheResult]metrics.Meter), StoredImpCacheMeter: make(map[CacheResult]metrics.Meter), + AccountCacheMeter: make(map[CacheResult]metrics.Meter), AmpNoCookieMeter: blankMeter, CookieSyncMeter: blankMeter, CookieSyncGen: make(map[openrtb_ext.BidderName]metrics.Meter), @@ -181,6 +183,7 @@ func NewBlankMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderNa for _, c := range CacheResults() { newMetrics.StoredReqCacheMeter[c] = blankMeter newMetrics.StoredImpCacheMeter[c] = blankMeter + newMetrics.AccountCacheMeter[c] = blankMeter } for _, v := range TCFVersions() { @@ -264,6 +267,7 @@ func NewMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderName, d for _, cacheRes := range CacheResults() { newMetrics.StoredReqCacheMeter[cacheRes] = metrics.GetOrRegisterMeter(fmt.Sprintf("stored_request_cache_%s", string(cacheRes)), registry) newMetrics.StoredImpCacheMeter[cacheRes] = metrics.GetOrRegisterMeter(fmt.Sprintf("stored_imp_cache_%s", string(cacheRes)), registry) + newMetrics.AccountCacheMeter[cacheRes] = metrics.GetOrRegisterMeter(fmt.Sprintf("account_cache_%s", string(cacheRes)), registry) } newMetrics.RequestsQueueTimer["video"][true] = metrics.GetOrRegisterTimer("queued_requests.video.accepted", registry) @@ -647,6 +651,12 @@ func (me *Metrics) RecordStoredImpCacheResult(cacheResult CacheResult, inc int) me.StoredImpCacheMeter[cacheResult].Mark(int64(inc)) } +// RecordAccountCacheResult implements a part of the MetricsEngine interface. Records the +// cache hits and misses when looking up accounts. +func (me *Metrics) RecordAccountCacheResult(cacheResult CacheResult, inc int) { + me.AccountCacheMeter[cacheResult].Mark(int64(inc)) +} + // RecordPrebidCacheRequestTime implements a part of the MetricsEngine interface. Records the // amount of time taken to store the auction result in Prebid Cache. func (me *Metrics) RecordPrebidCacheRequestTime(success bool, length time.Duration) { diff --git a/pbsmetrics/metrics.go b/pbsmetrics/metrics.go index 7f9d66b55ad..13e937e35c7 100644 --- a/pbsmetrics/metrics.go +++ b/pbsmetrics/metrics.go @@ -368,6 +368,7 @@ type MetricsEngine interface { RecordUserIDSet(userLabels UserLabels) // Function should verify bidder values RecordStoredReqCacheResult(cacheResult CacheResult, inc int) RecordStoredImpCacheResult(cacheResult CacheResult, inc int) + RecordAccountCacheResult(cacheResult CacheResult, inc int) RecordStoredDataFetchTime(labels StoredDataLabels, length time.Duration) RecordStoredDataError(labels StoredDataLabels) RecordPrebidCacheRequestTime(success bool, length time.Duration) diff --git a/pbsmetrics/metrics_mock.go b/pbsmetrics/metrics_mock.go index 63b05196be0..6871f92bf05 100644 --- a/pbsmetrics/metrics_mock.go +++ b/pbsmetrics/metrics_mock.go @@ -112,6 +112,11 @@ func (me *MetricsEngineMock) RecordStoredImpCacheResult(cacheResult CacheResult, me.Called(cacheResult, inc) } +// RecordAccountCacheResult mock +func (me *MetricsEngineMock) RecordAccountCacheResult(cacheResult CacheResult, inc int) { + me.Called(cacheResult, inc) +} + // RecordPrebidCacheRequestTime mock func (me *MetricsEngineMock) RecordPrebidCacheRequestTime(success bool, length time.Duration) { me.Called(success, length) diff --git a/pbsmetrics/prometheus/preload.go b/pbsmetrics/prometheus/preload.go index 52620bc657c..2f54de385e2 100644 --- a/pbsmetrics/prometheus/preload.go +++ b/pbsmetrics/prometheus/preload.go @@ -98,6 +98,10 @@ func preloadLabelValues(m *Metrics) { cacheResultLabel: cacheResultValues, }) + preloadLabelValuesForCounter(m.accountCacheResult, map[string][]string{ + cacheResultLabel: cacheResultValues, + }) + preloadLabelValuesForCounter(m.adapterBids, map[string][]string{ adapterLabel: adapterValues, markupDeliveryLabel: bidTypeValues, diff --git a/pbsmetrics/prometheus/prometheus.go b/pbsmetrics/prometheus/prometheus.go index 046d0769115..2086c935710 100644 --- a/pbsmetrics/prometheus/prometheus.go +++ b/pbsmetrics/prometheus/prometheus.go @@ -28,6 +28,7 @@ type Metrics struct { requestsWithoutCookie *prometheus.CounterVec storedImpressionsCacheResult *prometheus.CounterVec storedRequestCacheResult *prometheus.CounterVec + accountCacheResult *prometheus.CounterVec storedAccountFetchTimer *prometheus.HistogramVec storedAccountErrors *prometheus.CounterVec storedAMPFetchTimer *prometheus.HistogramVec @@ -186,6 +187,11 @@ func NewMetrics(cfg config.PrometheusMetrics, disabledMetrics config.DisabledMet "Count of stored request cache requests attempts by hits or miss.", []string{cacheResultLabel}) + metrics.accountCacheResult = newCounter(cfg, metrics.Registry, + "account_cache_performance", + "Count of account cache lookups by hits or miss.", + []string{cacheResultLabel}) + metrics.storedAccountFetchTimer = newHistogramVec(cfg, metrics.Registry, "stored_account_fetch_time_seconds", "Seconds to fetch stored accounts labeled by fetch type", @@ -613,6 +619,12 @@ func (m *Metrics) RecordStoredImpCacheResult(cacheResult pbsmetrics.CacheResult, }).Add(float64(inc)) } +func (m *Metrics) RecordAccountCacheResult(cacheResult pbsmetrics.CacheResult, inc int) { + m.accountCacheResult.With(prometheus.Labels{ + cacheResultLabel: string(cacheResult), + }).Add(float64(inc)) +} + func (m *Metrics) RecordPrebidCacheRequestTime(success bool, length time.Duration) { m.prebidCacheWriteTimer.With(prometheus.Labels{ successLabel: strconv.FormatBool(success), diff --git a/pbsmetrics/prometheus/prometheus_test.go b/pbsmetrics/prometheus/prometheus_test.go index 46be7005439..3469a44e7ed 100644 --- a/pbsmetrics/prometheus/prometheus_test.go +++ b/pbsmetrics/prometheus/prometheus_test.go @@ -1013,8 +1013,8 @@ func TestStoredReqCacheResultMetric(t *testing.T) { func TestStoredImpCacheResultMetric(t *testing.T) { m := createMetricsForTesting() - hitCount := 42 - missCount := 108 + hitCount := 41 + missCount := 107 m.RecordStoredImpCacheResult(pbsmetrics.CacheHit, hitCount) m.RecordStoredImpCacheResult(pbsmetrics.CacheMiss, missCount) @@ -1030,6 +1030,26 @@ func TestStoredImpCacheResultMetric(t *testing.T) { }) } +func TestAccountCacheResultMetric(t *testing.T) { + m := createMetricsForTesting() + + hitCount := 37 + missCount := 92 + m.RecordAccountCacheResult(pbsmetrics.CacheHit, hitCount) + m.RecordAccountCacheResult(pbsmetrics.CacheMiss, missCount) + + assertCounterVecValue(t, "", "accountCacheResult:hit", m.accountCacheResult, + float64(hitCount), + prometheus.Labels{ + cacheResultLabel: string(pbsmetrics.CacheHit), + }) + assertCounterVecValue(t, "", "accountCacheResult:miss", m.accountCacheResult, + float64(missCount), + prometheus.Labels{ + cacheResultLabel: string(pbsmetrics.CacheMiss), + }) +} + func TestCookieMetric(t *testing.T) { m := createMetricsForTesting() diff --git a/stored_requests/fetcher.go b/stored_requests/fetcher.go index 1773c966f32..096f9060b6d 100644 --- a/stored_requests/fetcher.go +++ b/stored_requests/fetcher.go @@ -195,7 +195,10 @@ func (f *fetcherWithCache) FetchAccount(ctx context.Context, accountID string) ( accountData := f.cache.Accounts.Get(ctx, []string{accountID}) // TODO: add metrics if account, ok := accountData[accountID]; ok { + f.metricsEngine.RecordAccountCacheResult(pbsmetrics.CacheHit, 1) return account, errs + } else { + f.metricsEngine.RecordAccountCacheResult(pbsmetrics.CacheMiss, 1) } account, errs = f.fetcher.FetchAccount(ctx, accountID) if len(errs) == 0 { diff --git a/stored_requests/fetcher_test.go b/stored_requests/fetcher_test.go index 7a6a06fb923..7fb56124db3 100644 --- a/stored_requests/fetcher_test.go +++ b/stored_requests/fetcher_test.go @@ -179,6 +179,7 @@ func TestAccountCacheHit(t *testing.T) { "known": json.RawMessage(`true`), }) + metricsEngine.On("RecordAccountCacheResult", pbsmetrics.CacheHit, 1) account, errs := aFetcherWithCache.FetchAccount(ctx, "known") accCache.AssertExpectations(t) @@ -200,6 +201,7 @@ func TestAccountCacheMiss(t *testing.T) { accCache.On("Get", ctx, uncachedAccounts).Return(map[string]json.RawMessage{}) accCache.On("Save", ctx, uncachedAccountsData) fetcher.On("FetchAccount", ctx, "uncached").Return(uncachedAccountsData["uncached"], []error{}) + metricsEngine.On("RecordAccountCacheResult", pbsmetrics.CacheMiss, 1) account, errs := aFetcherWithCache.FetchAccount(ctx, "uncached")