From b91c7f8854799882bee9144f7cc2067202471d73 Mon Sep 17 00:00:00 2001 From: dbemiller <27972385+dbemiller@users.noreply.github.com> Date: Tue, 26 Jun 2018 10:57:20 -0400 Subject: [PATCH] More granular adapter error metrics (#550) * Split the adapter error metrics up by purpose. Fixed some bugs. * Renamed some more metrics, and fixed some issues. * Split the openrtb2 request type into web and app. --- endpoints/openrtb2/auction.go | 9 ++-- exchange/bidder.go | 4 +- exchange/exchange.go | 70 +++++++++++++++++++++---------- exchange/utils.go | 14 +++---- pbs_light.go | 32 +++++++------- pbsmetrics/config/metrics_test.go | 53 ++++++++++++++--------- pbsmetrics/go_metrics.go | 46 ++++++++++---------- pbsmetrics/go_metrics_test.go | 20 +++++---- pbsmetrics/metrics.go | 43 ++++++++++++++----- pbsmetrics/metrics_test.go | 1 - 10 files changed, 186 insertions(+), 106 deletions(-) delete mode 100644 pbsmetrics/metrics_test.go diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index c19e55fbf8a..63294914ce6 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -65,7 +65,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http start := time.Now() labels := pbsmetrics.Labels{ Source: pbsmetrics.DemandUnknown, - RType: pbsmetrics.ReqTypeORTB2, + RType: pbsmetrics.ReqTypeORTB2Web, PubID: "", Browser: pbsmetrics.BrowserOther, CookieFlag: pbsmetrics.CookieFlagUnknown, @@ -94,8 +94,11 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http if req.Site != nil && req.Site.Publisher != nil { labels.PubID = req.Site.Publisher.ID } - if req.App != nil && req.App.Publisher != nil { - labels.PubID = req.App.Publisher.ID + if req.App != nil { + labels.RType = pbsmetrics.ReqTypeORTB2App + if req.App.Publisher != nil { + labels.PubID = req.App.Publisher.ID + } } ctx := context.Background() diff --git a/exchange/bidder.go b/exchange/bidder.go index 802accbaf34..575ddd743ff 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -186,7 +186,9 @@ func (bidder *bidderAdapter) doRequest(ctx context.Context, req *adapters.Reques defer httpResp.Body.Close() if httpResp.StatusCode < 200 || httpResp.StatusCode >= 400 { - err = fmt.Errorf("Server responded with failure status: %d. Set request.test = 1 for debugging info.", httpResp.StatusCode) + err = &adapters.BadServerResponseError{ + Message: fmt.Sprintf("Server responded with failure status: %d. Set request.test = 1 for debugging info.", httpResp.StatusCode), + } } return &httpCallInfo{ diff --git a/exchange/exchange.go b/exchange/exchange.go index 4f033fb3cff..96922d12764 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -7,6 +7,8 @@ import ( "net/http" "time" + "github.com/prebid/prebid-server/adapters" + "github.com/golang/glog" "github.com/mxmCherry/openrtb" @@ -176,31 +178,17 @@ func (e *exchange) getAllBids(ctx context.Context, cleanRequests map[openrtb_ext ae.ResponseTimeMillis = int(elapsed / time.Millisecond) // Timing statistics e.me.RecordAdapterTime(*bidlabels, time.Since(start)) - serr := make([]string, len(err)) - for i := 0; i < len(err); i++ { - serr[i] = err[i].Error() - // TODO: #142: for a bidder that return multiple errors, we will log multiple errors for that request - // in the metrics. Need to remember that in analyzing the data. - switch err[i] { - case context.DeadlineExceeded: - bidlabels.AdapterStatus = pbsmetrics.AdapterStatusTimeout - default: - bidlabels.AdapterStatus = pbsmetrics.AdapterStatusErr - } - } + serr := errsToStrings(err) + bidlabels.AdapterBids = bidsToMetric(bids) + bidlabels.AdapterErrors = errorsToMetric(err) // Append any bid validation errors to the error list ae.Errors = serr brw.adapterExtra = ae - if len(err) == 0 { - if bids == nil || len(bids.bids) == 0 { - // Don't want to mark no bids on error topreserve legacy behavior. - bidlabels.AdapterStatus = pbsmetrics.AdapterStatusNoBid - } else { - for _, bid := range bids.bids { - var cpm = float64(bid.bid.Price * 1000) - e.me.RecordAdapterPrice(*bidlabels, cpm) - e.me.RecordAdapterBidReceived(*bidlabels, bid.bidType, bid.bid.AdM != "") - } + if bids != nil { + for _, bid := range bids.bids { + var cpm = float64(bid.bid.Price * 1000) + e.me.RecordAdapterPrice(*bidlabels, cpm) + e.me.RecordAdapterBidReceived(*bidlabels, bid.bidType, bid.bid.AdM != "") } } chBids <- brw @@ -216,6 +204,44 @@ func (e *exchange) getAllBids(ctx context.Context, cleanRequests map[openrtb_ext return adapterBids, adapterExtra } +func bidsToMetric(bids *pbsOrtbSeatBid) pbsmetrics.AdapterBid { + if bids == nil || len(bids.bids) == 0 { + return pbsmetrics.AdapterBidNone + } + return pbsmetrics.AdapterBidPresent +} + +func errorsToMetric(errs []error) map[pbsmetrics.AdapterError]struct{} { + if len(errs) == 0 { + return nil + } + ret := make(map[pbsmetrics.AdapterError]struct{}, len(errs)) + var s struct{} + for _, err := range errs { + if err == context.DeadlineExceeded { + ret[pbsmetrics.AdapterErrorTimeout] = s + } else { + switch err.(type) { + case *adapters.BadInputError: + ret[pbsmetrics.AdapterErrorBadInput] = s + case *adapters.BadServerResponseError: + ret[pbsmetrics.AdapterErrorBadServerResponse] = s + default: + ret[pbsmetrics.AdapterErrorUnknown] = s + } + } + } + return ret +} + +func errsToStrings(errs []error) []string { + serr := make([]string, len(errs)) + for i := 0; i < len(errs); i++ { + serr[i] = errs[i].Error() + } + return serr +} + // This piece takes all the bids supplied by the adapters and crafts an openRTB response to send back to the requester func (e *exchange) buildBidResponse(ctx context.Context, liveAdapters []openrtb_ext.BidderName, adapterBids map[openrtb_ext.BidderName]*pbsOrtbSeatBid, bidRequest *openrtb.BidRequest, resolvedRequest json.RawMessage, adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra, errList []error) (*openrtb.BidResponse, error) { bidResponse := new(openrtb.BidResponse) diff --git a/exchange/utils.go b/exchange/utils.go index 35bbb1b6bf2..66d27246a13 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -41,13 +41,13 @@ func splitBidRequest(req *openrtb.BidRequest, impsByBidder map[string][]openrtb. reqCopy := *req coreBidder := resolveBidder(bidder, aliases) newLabel := pbsmetrics.AdapterLabels{ - Source: labels.Source, - RType: labels.RType, - Adapter: coreBidder, - PubID: labels.PubID, - Browser: labels.Browser, - CookieFlag: labels.CookieFlag, - AdapterStatus: pbsmetrics.AdapterStatusOK, + Source: labels.Source, + RType: labels.RType, + Adapter: coreBidder, + PubID: labels.PubID, + Browser: labels.Browser, + CookieFlag: labels.CookieFlag, + AdapterBids: pbsmetrics.AdapterBidPresent, } blabels[coreBidder] = &newLabel if hadSync := prepareUser(&reqCopy, bidder, coreBidder, explicitBuyerUIDs, usersyncs); !hadSync && req.App == nil { diff --git a/pbs_light.go b/pbs_light.go index 3c9109999b4..5104c4a921d 100644 --- a/pbs_light.go +++ b/pbs_light.go @@ -204,13 +204,13 @@ func (deps *auctionDeps) auction(w http.ResponseWriter, r *http.Request, _ httpr if ex, ok := exchanges[bidder.BidderCode]; ok { // Make sure we have an independent label struct for each bidder. We don't want to run into issues with the goroutine below. blabels := pbsmetrics.AdapterLabels{ - Source: labels.Source, - RType: labels.RType, - Adapter: openrtb_ext.BidderMap[bidder.BidderCode], - PubID: labels.PubID, - Browser: labels.Browser, - CookieFlag: labels.CookieFlag, - AdapterStatus: pbsmetrics.AdapterStatusOK, + Source: labels.Source, + RType: labels.RType, + Adapter: openrtb_ext.BidderMap[bidder.BidderCode], + PubID: labels.PubID, + Browser: labels.Browser, + CookieFlag: labels.CookieFlag, + AdapterBids: pbsmetrics.AdapterBidPresent, } if blabels.Adapter == "" { // "districtm" is legal, but not in BidderMap. Other values will log errors in the go_metrics code @@ -249,19 +249,23 @@ func (deps *auctionDeps) auction(w http.ResponseWriter, r *http.Request, _ httpr deps.metricsEngine.RecordAdapterTime(blabels, time.Since(start)) bidder.ResponseTime = int(time.Since(start) / time.Millisecond) if err != nil { + var s struct{} switch err { case context.DeadlineExceeded: - blabels.AdapterStatus = pbsmetrics.AdapterStatusTimeout + blabels.AdapterErrors = map[pbsmetrics.AdapterError]struct{}{pbsmetrics.AdapterErrorTimeout: s} bidder.Error = "Timed out" case context.Canceled: fallthrough default: - blabels.AdapterStatus = pbsmetrics.AdapterStatusErr bidder.Error = err.Error() - if _, isBadInput := err.(*adapters.BadInputError); !isBadInput { - if _, isBadServer := err.(*adapters.BadServerResponseError); !isBadServer { - glog.Warningf("Error from bidder %v. Ignoring all bids: %v", bidder.BidderCode, err) - } + switch err.(type) { + case *adapters.BadInputError: + blabels.AdapterErrors = map[pbsmetrics.AdapterError]struct{}{pbsmetrics.AdapterErrorBadInput: s} + case *adapters.BadServerResponseError: + blabels.AdapterErrors = map[pbsmetrics.AdapterError]struct{}{pbsmetrics.AdapterErrorBadServerResponse: s} + default: + glog.Warningf("Error from bidder %v. Ignoring all bids: %v", bidder.BidderCode, err) + blabels.AdapterErrors = map[pbsmetrics.AdapterError]struct{}{pbsmetrics.AdapterErrorUnknown: s} } } } else if bid_list != nil { @@ -280,7 +284,7 @@ func (deps *auctionDeps) auction(w http.ResponseWriter, r *http.Request, _ httpr } } else { bidder.NoBid = true - blabels.AdapterStatus = pbsmetrics.AdapterStatusNoBid + blabels.AdapterBids = pbsmetrics.AdapterBidNone } ch <- bidResult{ diff --git a/pbsmetrics/config/metrics_test.go b/pbsmetrics/config/metrics_test.go index 09473f07cd6..56b901e7246 100644 --- a/pbsmetrics/config/metrics_test.go +++ b/pbsmetrics/config/metrics_test.go @@ -45,42 +45,57 @@ func TestMultiMetricsEngine(t *testing.T) { metricsEngine = &engineList labels := pbsmetrics.Labels{ Source: pbsmetrics.DemandWeb, - RType: pbsmetrics.ReqTypeORTB2, + RType: pbsmetrics.ReqTypeORTB2Web, PubID: "test1", Browser: pbsmetrics.BrowserSafari, CookieFlag: pbsmetrics.CookieFlagYes, RequestStatus: pbsmetrics.RequestStatusOK, } - blabels := pbsmetrics.AdapterLabels{ - Source: pbsmetrics.DemandWeb, - RType: pbsmetrics.ReqTypeORTB2, - Adapter: openrtb_ext.BidderPubmatic, - PubID: "test1", - Browser: pbsmetrics.BrowserSafari, - CookieFlag: pbsmetrics.CookieFlagYes, - AdapterStatus: pbsmetrics.AdapterStatusOK, + apnLabels := pbsmetrics.AdapterLabels{ + Source: pbsmetrics.DemandWeb, + RType: pbsmetrics.ReqTypeORTB2Web, + Adapter: openrtb_ext.BidderAppnexus, + PubID: "test1", + Browser: pbsmetrics.BrowserSafari, + CookieFlag: pbsmetrics.CookieFlagYes, + AdapterBids: pbsmetrics.AdapterBidNone, + } + pubLabels := pbsmetrics.AdapterLabels{ + Source: pbsmetrics.DemandWeb, + RType: pbsmetrics.ReqTypeORTB2Web, + Adapter: openrtb_ext.BidderPubmatic, + PubID: "test1", + Browser: pbsmetrics.BrowserSafari, + CookieFlag: pbsmetrics.CookieFlagYes, + AdapterBids: pbsmetrics.AdapterBidPresent, } for i := 0; i < 5; i++ { metricsEngine.RecordRequest(labels) metricsEngine.RecordImps(labels, 2) metricsEngine.RecordRequestTime(labels, time.Millisecond*20) - metricsEngine.RecordAdapterRequest(blabels) - metricsEngine.RecordAdapterPrice(blabels, 1.34) - metricsEngine.RecordAdapterTime(blabels, time.Millisecond*20) + metricsEngine.RecordAdapterRequest(pubLabels) + metricsEngine.RecordAdapterRequest(apnLabels) + metricsEngine.RecordAdapterPrice(pubLabels, 1.34) + metricsEngine.RecordAdapterBidReceived(pubLabels, openrtb_ext.BidTypeBanner, true) + metricsEngine.RecordAdapterTime(pubLabels, time.Millisecond*20) } - VerifyMetrics(t, "RequestStatuses.OpenRTB2.OK", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2][pbsmetrics.RequestStatusOK].Count(), 5) + VerifyMetrics(t, "RequestStatuses.OpenRTB2.OK", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2Web][pbsmetrics.RequestStatusOK].Count(), 5) VerifyMetrics(t, "RequestStatuses.Legacy.OK", goEngine.RequestStatuses[pbsmetrics.ReqTypeLegacy][pbsmetrics.RequestStatusOK].Count(), 0) VerifyMetrics(t, "RequestStatuses.AMP.OK", goEngine.RequestStatuses[pbsmetrics.ReqTypeAMP][pbsmetrics.RequestStatusOK].Count(), 0) - VerifyMetrics(t, "RequestStatuses.OpenRTB2.Error", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2][pbsmetrics.RequestStatusErr].Count(), 0) - VerifyMetrics(t, "RequestStatuses.OpenRTB2.BadInput", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2][pbsmetrics.RequestStatusBadInput].Count(), 0) - VerifyMetrics(t, "Request", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2][pbsmetrics.RequestStatusOK].Count(), 5) + VerifyMetrics(t, "RequestStatuses.OpenRTB2.Error", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2Web][pbsmetrics.RequestStatusErr].Count(), 0) + VerifyMetrics(t, "RequestStatuses.OpenRTB2.BadInput", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2Web][pbsmetrics.RequestStatusBadInput].Count(), 0) + VerifyMetrics(t, "Request", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2Web][pbsmetrics.RequestStatusOK].Count(), 5) VerifyMetrics(t, "ImpMeter", goEngine.ImpMeter.Count(), 10) VerifyMetrics(t, "NoCookieMeter", goEngine.NoCookieMeter.Count(), 0) VerifyMetrics(t, "SafariRequestMeter", goEngine.SafariRequestMeter.Count(), 5) VerifyMetrics(t, "SafariNoCookieMeter", goEngine.SafariNoCookieMeter.Count(), 0) - VerifyMetrics(t, "AdapterMetrics.Pubmatic.RequestMeter", goEngine.AdapterMetrics[openrtb_ext.BidderPubmatic].RequestMeter.Count(), 5) - VerifyMetrics(t, "AdapterMetrics.Pubmatic.ErrorMeter", goEngine.AdapterMetrics[openrtb_ext.BidderPubmatic].ErrorMeter.Count(), 0) - VerifyMetrics(t, "AdapterMetrics.AppNexus.RequestMeter", goEngine.AdapterMetrics[openrtb_ext.BidderAppnexus].RequestMeter.Count(), 0) + VerifyMetrics(t, "AdapterMetrics.Pubmatic.GotBidsMeter", goEngine.AdapterMetrics[openrtb_ext.BidderPubmatic].GotBidsMeter.Count(), 5) + VerifyMetrics(t, "AdapterMetrics.Pubmatic.NoBidMeter", goEngine.AdapterMetrics[openrtb_ext.BidderPubmatic].NoBidMeter.Count(), 0) + for _, err := range pbsmetrics.AdapterErrors() { + VerifyMetrics(t, "AdapterMetrics.Pubmatic.Request.ErrorMeter."+string(err), goEngine.AdapterMetrics[openrtb_ext.BidderPubmatic].ErrorMeters[err].Count(), 0) + } + VerifyMetrics(t, "AdapterMetrics.AppNexus.GotBidsMeter", goEngine.AdapterMetrics[openrtb_ext.BidderAppnexus].GotBidsMeter.Count(), 0) + VerifyMetrics(t, "AdapterMetrics.AppNexus.NoBidMeter", goEngine.AdapterMetrics[openrtb_ext.BidderAppnexus].NoBidMeter.Count(), 5) } func VerifyMetrics(t *testing.T, name string, expected int64, actual int64) { diff --git a/pbsmetrics/go_metrics.go b/pbsmetrics/go_metrics.go index 68df75da7ef..b171e403f4c 100644 --- a/pbsmetrics/go_metrics.go +++ b/pbsmetrics/go_metrics.go @@ -44,10 +44,9 @@ type Metrics struct { // AdapterMetrics houses the metrics for a particular adapter type AdapterMetrics struct { NoCookieMeter metrics.Meter - ErrorMeter metrics.Meter + ErrorMeters map[AdapterError]metrics.Meter NoBidMeter metrics.Meter - TimeoutMeter metrics.Meter - RequestMeter metrics.Meter + GotBidsMeter metrics.Meter RequestTimer metrics.Timer PriceHistogram metrics.Histogram BidsReceivedMeter metrics.Meter @@ -157,15 +156,17 @@ func makeBlankAdapterMetrics() *AdapterMetrics { blankMeter := &metrics.NilMeter{} newAdapter := &AdapterMetrics{ NoCookieMeter: blankMeter, - ErrorMeter: blankMeter, + ErrorMeters: make(map[AdapterError]metrics.Meter), NoBidMeter: blankMeter, - TimeoutMeter: blankMeter, - RequestMeter: blankMeter, + GotBidsMeter: blankMeter, RequestTimer: &metrics.NilTimer{}, PriceHistogram: &metrics.NilHistogram{}, BidsReceivedMeter: blankMeter, MarkupMetrics: makeBlankBidMarkupMetrics(), } + for _, err := range AdapterErrors() { + newAdapter.ErrorMeters[err] = blankMeter + } return newAdapter } @@ -187,10 +188,8 @@ func makeBlankMarkupDeliveryMetrics() *MarkupDeliveryMetrics { func registerAdapterMetrics(registry metrics.Registry, adapterOrAccount string, exchange string, am *AdapterMetrics) { am.NoCookieMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("%[1]s.%[2]s.no_cookie_requests", adapterOrAccount, exchange), registry) - am.ErrorMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("%[1]s.%[2]s.error_requests", adapterOrAccount, exchange), registry) - am.NoBidMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("%[1]s.%[2]s.no_bid_requests", adapterOrAccount, exchange), registry) - am.TimeoutMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("%[1]s.%[2]s.timeout_requests", adapterOrAccount, exchange), registry) - am.RequestMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("%[1]s.%[2]s.requests", adapterOrAccount, exchange), registry) + am.NoBidMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("%[1]s.%[2]s.requests.nobid", adapterOrAccount, exchange), registry) + am.GotBidsMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("%[1]s.%[2]s.requests.gotbids", adapterOrAccount, exchange), registry) am.RequestTimer = metrics.GetOrRegisterTimer(fmt.Sprintf("%[1]s.%[2]s.request_time", adapterOrAccount, exchange), registry) am.PriceHistogram = metrics.GetOrRegisterHistogram(fmt.Sprintf("%[1]s.%[2]s.prices", adapterOrAccount, exchange), registry, metrics.NewExpDecaySample(1028, 0.015)) am.MarkupMetrics = map[openrtb_ext.BidType]*MarkupDeliveryMetrics{ @@ -199,6 +198,9 @@ func registerAdapterMetrics(registry metrics.Registry, adapterOrAccount string, openrtb_ext.BidTypeAudio: makeDeliveryMetrics(registry, adapterOrAccount+"."+exchange, openrtb_ext.BidTypeAudio), openrtb_ext.BidTypeNative: makeDeliveryMetrics(registry, adapterOrAccount+"."+exchange, openrtb_ext.BidTypeNative), } + for err := range am.ErrorMeters { + am.ErrorMeters[err] = metrics.GetOrRegisterMeter(fmt.Sprintf("%s.%s.requests.%s", adapterOrAccount, exchange, err), registry) + } if adapterOrAccount != "adapter" { am.BidsReceivedMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("%[1]s.%[2]s.bids_received", adapterOrAccount, exchange), registry) } @@ -312,20 +314,22 @@ func (me *Metrics) RecordAdapterRequest(labels AdapterLabels) { glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", string(labels.Adapter)) return } - // Adapter metrics - am.RequestMeter.Mark(1) - // Account-Adapter metrics - aam := me.getAccountMetrics(labels.PubID).adapterMetrics[labels.Adapter] - aam.RequestMeter.Mark(1) - switch labels.AdapterStatus { - case AdapterStatusErr: - am.ErrorMeter.Mark(1) - case AdapterStatusNoBid: + aam := me.getAccountMetrics(labels.PubID).adapterMetrics[labels.Adapter] + switch labels.AdapterBids { + case AdapterBidNone: am.NoBidMeter.Mark(1) - case AdapterStatusTimeout: - am.TimeoutMeter.Mark(1) + aam.NoBidMeter.Mark(1) + case AdapterBidPresent: + am.GotBidsMeter.Mark(1) + aam.GotBidsMeter.Mark(1) + default: + glog.Warningf("No go-metrics logged for AdapterBids value: %s", labels.AdapterBids) } + for errType := range labels.AdapterErrors { + am.ErrorMeters[errType].Mark(1) + } + if labels.CookieFlag == CookieFlagNo { am.NoCookieMeter.Mark(1) } diff --git a/pbsmetrics/go_metrics_test.go b/pbsmetrics/go_metrics_test.go index 91081ddad28..4714ff23282 100644 --- a/pbsmetrics/go_metrics_test.go +++ b/pbsmetrics/go_metrics_test.go @@ -26,9 +26,12 @@ func TestNewMetrics(t *testing.T) { ensureContains(t, registry, "requests.ok.legacy", m.RequestStatuses[ReqTypeLegacy][RequestStatusOK]) ensureContains(t, registry, "requests.badinput.legacy", m.RequestStatuses[ReqTypeLegacy][RequestStatusBadInput]) ensureContains(t, registry, "requests.err.legacy", m.RequestStatuses[ReqTypeLegacy][RequestStatusErr]) - ensureContains(t, registry, "requests.ok.openrtb2", m.RequestStatuses[ReqTypeORTB2][RequestStatusOK]) - ensureContains(t, registry, "requests.badinput.openrtb2", m.RequestStatuses[ReqTypeORTB2][RequestStatusBadInput]) - ensureContains(t, registry, "requests.err.openrtb2", m.RequestStatuses[ReqTypeORTB2][RequestStatusErr]) + ensureContains(t, registry, "requests.ok.openrtb2-web", m.RequestStatuses[ReqTypeORTB2Web][RequestStatusOK]) + ensureContains(t, registry, "requests.badinput.openrtb2-web", m.RequestStatuses[ReqTypeORTB2Web][RequestStatusBadInput]) + ensureContains(t, registry, "requests.err.openrtb2-web", m.RequestStatuses[ReqTypeORTB2Web][RequestStatusErr]) + ensureContains(t, registry, "requests.ok.openrtb2-app", m.RequestStatuses[ReqTypeORTB2App][RequestStatusOK]) + ensureContains(t, registry, "requests.badinput.openrtb2-app", m.RequestStatuses[ReqTypeORTB2App][RequestStatusBadInput]) + ensureContains(t, registry, "requests.err.openrtb2-app", m.RequestStatuses[ReqTypeORTB2App][RequestStatusErr]) ensureContains(t, registry, "requests.ok.amp", m.RequestStatuses[ReqTypeAMP][RequestStatusOK]) ensureContains(t, registry, "requests.badinput.amp", m.RequestStatuses[ReqTypeAMP][RequestStatusBadInput]) ensureContains(t, registry, "requests.err.amp", m.RequestStatuses[ReqTypeAMP][RequestStatusErr]) @@ -73,10 +76,13 @@ func ensureContains(t *testing.T, registry metrics.Registry, name string, metric func ensureContainsAdapterMetrics(t *testing.T, registry metrics.Registry, name string, adapterMetrics *AdapterMetrics) { t.Helper() ensureContains(t, registry, name+".no_cookie_requests", adapterMetrics.NoCookieMeter) - ensureContains(t, registry, name+".error_requests", adapterMetrics.ErrorMeter) - ensureContains(t, registry, name+".requests", adapterMetrics.RequestMeter) - ensureContains(t, registry, name+".no_bid_requests", adapterMetrics.NoBidMeter) - ensureContains(t, registry, name+".timeout_requests", adapterMetrics.TimeoutMeter) + ensureContains(t, registry, name+".requests.gotbids", adapterMetrics.GotBidsMeter) + ensureContains(t, registry, name+".requests.nobid", adapterMetrics.NoBidMeter) + ensureContains(t, registry, name+".requests.badinput", adapterMetrics.ErrorMeters[AdapterErrorBadInput]) + ensureContains(t, registry, name+".requests.badserverresponse", adapterMetrics.ErrorMeters[AdapterErrorBadServerResponse]) + ensureContains(t, registry, name+".requests.timeout", adapterMetrics.ErrorMeters[AdapterErrorTimeout]) + ensureContains(t, registry, name+".requests.unknown_error", adapterMetrics.ErrorMeters[AdapterErrorUnknown]) + ensureContains(t, registry, name+".request_time", adapterMetrics.RequestTimer) ensureContains(t, registry, name+".prices", adapterMetrics.PriceHistogram) ensureContainsBidTypeMetrics(t, registry, name, adapterMetrics.MarkupMetrics) diff --git a/pbsmetrics/metrics.go b/pbsmetrics/metrics.go index 163763d0c4a..accb0442b6c 100644 --- a/pbsmetrics/metrics.go +++ b/pbsmetrics/metrics.go @@ -24,7 +24,8 @@ type AdapterLabels struct { PubID string // exchange specific ID, so we cannot compile in values Browser Browser CookieFlag CookieFlag - AdapterStatus AdapterStatus + AdapterBids AdapterBid + AdapterErrors map[AdapterError]struct{} } // Label typecasting. Se below the type definitions for possible values @@ -44,8 +45,11 @@ type CookieFlag string // RequestStatus : The request return status type RequestStatus string -// AdapterStatus : The radapter execution status -type AdapterStatus string +// AdapterBid : Whether or not the adapter returned bids +type AdapterBid string + +// AdapterError : Errors which may have occurred during the adapter's execution +type AdapterError string // The demand sources const ( @@ -56,15 +60,17 @@ const ( // The request types (endpoints) const ( - ReqTypeLegacy RequestType = "legacy" - ReqTypeORTB2 RequestType = "openrtb2" - ReqTypeAMP RequestType = "amp" + ReqTypeLegacy RequestType = "legacy" + ReqTypeORTB2Web RequestType = "openrtb2-web" + ReqTypeORTB2App RequestType = "openrtb2-app" + ReqTypeAMP RequestType = "amp" ) func requestTypes() []RequestType { return []RequestType{ ReqTypeLegacy, - ReqTypeORTB2, + ReqTypeORTB2Web, + ReqTypeORTB2App, ReqTypeAMP, } } @@ -97,14 +103,29 @@ func requestStatuses() []RequestStatus { } } +// Adapter bid repsonse status. +const ( + AdapterBidPresent AdapterBid = "bid" + AdapterBidNone AdapterBid = "nobid" +) + // Adapter execution status const ( - AdapterStatusOK AdapterStatus = "ok" - AdapterStatusErr AdapterStatus = "err" - AdapterStatusNoBid AdapterStatus = "nobid" - AdapterStatusTimeout AdapterStatus = "timeout" + AdapterErrorBadInput AdapterError = "badinput" + AdapterErrorBadServerResponse AdapterError = "badserverresponse" + AdapterErrorTimeout AdapterError = "timeout" + AdapterErrorUnknown AdapterError = "unknown_error" ) +func AdapterErrors() []AdapterError { + return []AdapterError{ + AdapterErrorBadInput, + AdapterErrorBadServerResponse, + AdapterErrorTimeout, + AdapterErrorUnknown, + } +} + // UserLabels : Labels for /setuid endpoint type UserLabels struct { Action RequestAction diff --git a/pbsmetrics/metrics_test.go b/pbsmetrics/metrics_test.go deleted file mode 100644 index 344d5affe12..00000000000 --- a/pbsmetrics/metrics_test.go +++ /dev/null @@ -1 +0,0 @@ -package pbsmetrics