Skip to content

Commit

Permalink
Add overhead metrics (#2658)
Browse files Browse the repository at this point in the history
co-authored by @onkarvhanumante
  • Loading branch information
onkarvhanumante authored Apr 24, 2023
1 parent 754a0eb commit eb338b6
Show file tree
Hide file tree
Showing 22 changed files with 368 additions and 79 deletions.
8 changes: 8 additions & 0 deletions adapters/bidder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/base64"
"encoding/json"
"net/http"
"time"

"github.com/prebid/openrtb/v19/openrtb2"
"github.com/prebid/prebid-server/config"
Expand Down Expand Up @@ -145,8 +146,15 @@ func (r *RequestData) SetBasicAuth(username string, password string) {

type ExtraRequestInfo struct {
PbsEntryPoint metrics.RequestType
BidderRequestStartTime time.Time
GlobalPrivacyControlHeader string
CurrencyConversions currency.Conversions
MakeBidsTimeInfo MakeBidsTimeInfo
}

type MakeBidsTimeInfo struct {
AfterMakeBidsStartTime time.Time
Durations []time.Duration
}

func NewExtraRequestInfo(c currency.Conversions) ExtraRequestInfo {
Expand Down
5 changes: 4 additions & 1 deletion endpoints/openrtb2/amp_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h

secGPC := r.Header.Get("Sec-GPC")

auctionRequest := exchange.AuctionRequest{
auctionRequest := &exchange.AuctionRequest{
BidRequestWrapper: reqWrapper,
Account: *account,
UserSyncs: usersyncs,
Expand Down Expand Up @@ -266,6 +266,9 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h
}

labels, ao = sendAmpResponse(w, hookExecutor, response, reqWrapper, account, labels, ao, errL)
if len(ao.Errors) == 0 {
recordResponsePreparationMetrics(auctionRequest.MakeBidsTimeInfo, deps.metricsEngine)
}
}

func rejectAmpRequest(
Expand Down
4 changes: 2 additions & 2 deletions endpoints/openrtb2/amp_auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,7 @@ var expectedErrorsFromHoldAuction map[openrtb_ext.BidderName][]openrtb_ext.ExtBi
},
}

func (m *mockAmpExchange) HoldAuction(ctx context.Context, auctionRequest exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
func (m *mockAmpExchange) HoldAuction(ctx context.Context, auctionRequest *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
r := auctionRequest.BidRequestWrapper
m.lastRequest = r.BidRequest

Expand Down Expand Up @@ -1459,7 +1459,7 @@ func (m *mockAmpExchange) HoldAuction(ctx context.Context, auctionRequest exchan

type mockAmpExchangeWarnings struct{}

func (m *mockAmpExchangeWarnings) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
func (m *mockAmpExchangeWarnings) HoldAuction(ctx context.Context, r *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
response := &openrtb2.BidResponse{
SeatBid: []openrtb2.SeatBid{{
Bid: []openrtb2.Bid{{
Expand Down
16 changes: 15 additions & 1 deletion endpoints/openrtb2/auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
nativeRequests "github.com/prebid/openrtb/v19/native1/request"
"github.com/prebid/openrtb/v19/openrtb2"
"github.com/prebid/openrtb/v19/openrtb3"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/hooks"
"github.com/prebid/prebid-server/ortb"
"golang.org/x/net/publicsuffix"
Expand Down Expand Up @@ -213,7 +214,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http

warnings := errortypes.WarningOnly(errL)

auctionRequest := exchange.AuctionRequest{
auctionRequest := &exchange.AuctionRequest{
BidRequestWrapper: req,
Account: *account,
UserSyncs: usersyncs,
Expand Down Expand Up @@ -252,6 +253,9 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http
}

labels, ao = sendAuctionResponse(w, hookExecutor, response, req.BidRequest, account, labels, ao)
if len(ao.Errors) == 0 {
recordResponsePreparationMetrics(auctionRequest.MakeBidsTimeInfo, deps.metricsEngine)
}
}

func rejectAuctionRequest(
Expand Down Expand Up @@ -2326,3 +2330,13 @@ func validateStoredBidRespAndImpExtBidders(bidderExts map[string]json.RawMessage
func generateStoredBidResponseValidationError(impID string) error {
return fmt.Errorf("request validation failed. Stored bid responses are specified for imp %s. Bidders specified in imp.ext should match with bidders specified in imp.ext.prebid.storedbidresponse", impID)
}

func recordResponsePreparationMetrics(mbti map[openrtb_ext.BidderName]adapters.MakeBidsTimeInfo, me metrics.MetricsEngine) {
for _, info := range mbti {
duration := time.Since(info.AfterMakeBidsStartTime)
for _, makeBidsDuration := range info.Durations {
duration += makeBidsDuration
}
me.RecordOverheadTime(metrics.MakeAuctionResponse, duration)
}
}
11 changes: 11 additions & 0 deletions endpoints/openrtb2/auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ import (
"github.com/prebid/openrtb/v19/native1"
nativeRequests "github.com/prebid/openrtb/v19/native1/request"
"github.com/prebid/openrtb/v19/openrtb2"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/analytics"
"github.com/prebid/prebid-server/hooks"
"github.com/prebid/prebid-server/hooks/hookexecution"
"github.com/prebid/prebid-server/hooks/hookstage"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

analyticsConf "github.com/prebid/prebid-server/analytics/config"
"github.com/prebid/prebid-server/config"
Expand Down Expand Up @@ -5335,3 +5337,12 @@ type mockStageExecutor struct {
func (e mockStageExecutor) GetOutcomes() []hookexecution.StageOutcome {
return e.outcomes
}

func TestRecordResponsePreparationMetrics(t *testing.T) {
mbi := map[openrtb_ext.BidderName]adapters.MakeBidsTimeInfo{
openrtb_ext.BidderAppnexus: {Durations: []time.Duration{10, 15}, AfterMakeBidsStartTime: time.Now()},
}
mockMetricEngine := &metrics.MetricsEngineMock{}
mockMetricEngine.On("RecordOverheadTime", metrics.MakeAuctionResponse, mock.Anything)
recordResponsePreparationMetrics(mbi, mockMetricEngine)
}
12 changes: 6 additions & 6 deletions endpoints/openrtb2/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ type testConfigValues struct {

type brokenExchange struct{}

func (e *brokenExchange) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
func (e *brokenExchange) HoldAuction(ctx context.Context, r *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
return nil, errors.New("Critical, unrecoverable error.")
}

Expand Down Expand Up @@ -848,7 +848,7 @@ type mockExchange struct {
lastRequest *openrtb2.BidRequest
}

func (m *mockExchange) HoldAuction(ctx context.Context, auctionRequest exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
func (m *mockExchange) HoldAuction(ctx context.Context, auctionRequest *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
r := auctionRequest.BidRequestWrapper
m.lastRequest = r.BidRequest
return &openrtb2.BidResponse{
Expand Down Expand Up @@ -885,8 +885,8 @@ type warningsCheckExchange struct {
auctionRequest exchange.AuctionRequest
}

func (e *warningsCheckExchange) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
e.auctionRequest = r
func (e *warningsCheckExchange) HoldAuction(ctx context.Context, r *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
e.auctionRequest = *r
return nil, nil
}

Expand All @@ -896,7 +896,7 @@ type nobidExchange struct {
gotRequest *openrtb2.BidRequest
}

func (e *nobidExchange) HoldAuction(ctx context.Context, auctionRequest exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
func (e *nobidExchange) HoldAuction(ctx context.Context, auctionRequest *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
r := auctionRequest.BidRequestWrapper
e.gotRequest = r.BidRequest
return &openrtb2.BidResponse{
Expand Down Expand Up @@ -1181,7 +1181,7 @@ type exchangeTestWrapper struct {
actualValidatedBidReq *openrtb2.BidRequest
}

func (te *exchangeTestWrapper) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
func (te *exchangeTestWrapper) HoldAuction(ctx context.Context, r *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {

// rebuild/resync the request in the request wrapper.
if err := r.BidRequestWrapper.RebuildRequest(); err != nil {
Expand Down
6 changes: 5 additions & 1 deletion endpoints/openrtb2/video_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
}

secGPC := r.Header.Get("Sec-GPC")
auctionRequest := exchange.AuctionRequest{
auctionRequest := &exchange.AuctionRequest{
BidRequestWrapper: bidReqWrapper,
Account: *account,
UserSyncs: usersyncs,
Expand Down Expand Up @@ -354,6 +354,10 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
return
}

if len(vo.Errors) == 0 {
recordResponsePreparationMetrics(auctionRequest.MakeBidsTimeInfo, deps.metricsEngine)
}

w.Header().Set("Content-Type", "application/json")
w.Write(resp)

Expand Down
6 changes: 3 additions & 3 deletions endpoints/openrtb2/video_auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,7 @@ type mockExchangeVideo struct {
cache *mockCacheClient
}

func (m *mockExchangeVideo) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
func (m *mockExchangeVideo) HoldAuction(ctx context.Context, r *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
if err := r.BidRequestWrapper.RebuildRequest(); err != nil {
return nil, err
}
Expand Down Expand Up @@ -1394,7 +1394,7 @@ type mockExchangeAppendBidderNames struct {
cache *mockCacheClient
}

func (m *mockExchangeAppendBidderNames) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
func (m *mockExchangeAppendBidderNames) HoldAuction(ctx context.Context, r *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
m.lastRequest = r.BidRequestWrapper.BidRequest
if debugLog != nil && debugLog.Enabled {
m.cache.called = true
Expand Down Expand Up @@ -1430,7 +1430,7 @@ type mockExchangeVideoNoBids struct {
cache *mockCacheClient
}

func (m *mockExchangeVideoNoBids) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
func (m *mockExchangeVideoNoBids) HoldAuction(ctx context.Context, r *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) {
m.lastRequest = r.BidRequestWrapper.BidRequest
return &openrtb2.BidResponse{
SeatBid: []openrtb2.SeatBid{{}},
Expand Down
23 changes: 14 additions & 9 deletions exchange/bidder.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,11 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde
return nil, []error{reject}
}

var reqData []*adapters.RequestData
var errs []error
var responseChannel chan *httpCallInfo
var (
reqData []*adapters.RequestData
errs []error
responseChannel chan *httpCallInfo
)

//check if real request exists for this bidder or it only has stored responses
dataLen := 0
Expand Down Expand Up @@ -169,11 +171,11 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde
dataLen = len(reqData) + len(bidderRequest.BidderStoredResponses)
responseChannel = make(chan *httpCallInfo, dataLen)
if len(reqData) == 1 {
responseChannel <- bidder.doRequest(ctx, reqData[0])
responseChannel <- bidder.doRequest(ctx, reqData[0], reqInfo.BidderRequestStartTime)
} else {
for _, oneReqData := range reqData {
go func(data *adapters.RequestData) {
responseChannel <- bidder.doRequest(ctx, data)
responseChannel <- bidder.doRequest(ctx, data, reqInfo.BidderRequestStartTime)
}(oneReqData) // Method arg avoids a race condition on oneReqData
}
}
Expand Down Expand Up @@ -227,6 +229,7 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde
}

if httpInfo.err == nil {
startTime := time.Now()
bidResponse, moreErrs := bidder.Bidder.MakeBids(bidderRequest.BidRequest, httpInfo.request, httpInfo.response)
errs = append(errs, moreErrs...)

Expand Down Expand Up @@ -363,11 +366,12 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde
errs = append(errs, err)
}
}
reqInfo.MakeBidsTimeInfo.Durations = append(reqInfo.MakeBidsTimeInfo.Durations, time.Since(startTime))
} else {
errs = append(errs, httpInfo.err)
}
}

reqInfo.MakeBidsTimeInfo.AfterMakeBidsStartTime = time.Now()
seatBids := make([]*entities.PbsOrtbSeatBid, 0, len(seatBidMap))
for _, seatBid := range seatBidMap {
seatBids = append(seatBids, seatBid)
Expand Down Expand Up @@ -487,11 +491,11 @@ func makeExt(httpInfo *httpCallInfo) *openrtb_ext.ExtHttpCall {

// doRequest makes a request, handles the response, and returns the data needed by the
// Bidder interface.
func (bidder *bidderAdapter) doRequest(ctx context.Context, req *adapters.RequestData) *httpCallInfo {
return bidder.doRequestImpl(ctx, req, glog.Warningf)
func (bidder *bidderAdapter) doRequest(ctx context.Context, req *adapters.RequestData, pbsRequestStartTime time.Time) *httpCallInfo {
return bidder.doRequestImpl(ctx, req, glog.Warningf, pbsRequestStartTime)
}

func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.RequestData, logger util.LogMsg) *httpCallInfo {
func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.RequestData, logger util.LogMsg, pbsRequestStartTime time.Time) *httpCallInfo {
var requestBody []byte

switch strings.ToUpper(bidder.config.EndpointCompression) {
Expand All @@ -515,6 +519,7 @@ func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.Re
if !bidder.config.DisableConnMetrics {
ctx = bidder.addClientTrace(ctx)
}
bidder.me.RecordOverheadTime(metrics.PreBidder, time.Since(pbsRequestStartTime))
httpResp, err := ctxhttp.Do(ctx, bidder.Client, httpReq)
if err != nil {
if err == context.DeadlineExceeded {
Expand Down
Loading

0 comments on commit eb338b6

Please sign in to comment.