Skip to content
This repository has been archived by the owner on Dec 22, 2022. It is now read-only.

Commit

Permalink
Add Native-Specific Metrics to Prebid Server (prebid#930)
Browse files Browse the repository at this point in the history
* going out real quick, brb

* brb to attend 395

* Test cases still not ready, but touching base to see if we are on the right track here

* removed some commented lines

* Counting Imp types inside go_metrics.RecordImps function

* Added >0 check in go_metrics.RecordImps

* working on the prometheus part

* going out real quick

* Finally working as a counterVector for banner. Replicate for the others

* Prometheus implemented

* Test case for RecordImps() function

* refactored imp types to be boolean values inside a new ImpLabels type

* refactoring prometheus.go

* Hans' refactoring and RecordLegacyImps() implemented

* corrected .travis.yml

* trying to fix travis issue

* Small changes after Mansi's review
  • Loading branch information
guscarreon authored Jul 18, 2019
1 parent 1ab2760 commit 332ee37
Show file tree
Hide file tree
Showing 12 changed files with 294 additions and 46 deletions.
4 changes: 2 additions & 2 deletions endpoints/auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ func (a *auction) auction(w http.ResponseWriter, r *http.Request, _ httprouter.P
defer func() {
if req == nil {
a.metricsEngine.RecordRequest(labels)
a.metricsEngine.RecordImps(labels, 0)
a.metricsEngine.RecordLegacyImps(labels, 0)
} else {
// handles the case that ParsePBSRequest returns an error, so req.Start is not defined
a.metricsEngine.RecordRequest(labels)
a.metricsEngine.RecordImps(labels, len(req.AdUnits))
a.metricsEngine.RecordLegacyImps(labels, len(req.AdUnits))
a.metricsEngine.RecordRequestTime(labels, time.Since(req.Start))
}
}()
Expand Down
1 change: 0 additions & 1 deletion endpoints/openrtb2/amp_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h
}
defer func() {
deps.metricsEngine.RecordRequest(labels)
deps.metricsEngine.RecordImps(labels, 1)
deps.metricsEngine.RecordRequestTime(labels, time.Since(start))
deps.analytics.LogAmpObject(&ao)
}()
Expand Down
3 changes: 0 additions & 3 deletions endpoints/openrtb2/auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,8 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http
CookieFlag: pbsmetrics.CookieFlagUnknown,
RequestStatus: pbsmetrics.RequestStatusOK,
}
numImps := 0
defer func() {
deps.metricsEngine.RecordRequest(labels)
deps.metricsEngine.RecordImps(labels, numImps)
deps.metricsEngine.RecordRequestTime(labels, time.Since(start))
deps.analytics.LogAuctionObject(&ao)
}()
Expand Down Expand Up @@ -138,7 +136,6 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http
labels.PubID = effectivePubID(req.Site.Publisher)
}

numImps = len(req.Imp)
response, err := deps.ex.HoldAuction(ctx, req, usersyncs, labels, &deps.categories)
ao.Request = req
ao.Response = response
Expand Down
4 changes: 0 additions & 4 deletions endpoints/openrtb2/video_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,8 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
CookieFlag: pbsmetrics.CookieFlagUnknown,
RequestStatus: pbsmetrics.RequestStatusOK,
}
numImps := 0
defer func() {
deps.metricsEngine.RecordRequest(labels)
deps.metricsEngine.RecordImps(labels, numImps)
deps.metricsEngine.RecordRequestTime(labels, time.Since(start))
deps.analytics.LogAuctionObject(&ao)
}()
Expand Down Expand Up @@ -201,8 +199,6 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
labels.PubID = effectivePubID(bidReq.Site.Publisher)
}

numImps = len(bidReq.Imp)

//execute auction logic
response, err := deps.ex.HoldAuction(ctx, bidReq, usersyncs, labels, &deps.categories)
ao.Request = bidReq
Expand Down
10 changes: 10 additions & 0 deletions exchange/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque
}
}

for _, impInRequest := range bidRequest.Imp {
var impLabels pbsmetrics.ImpLabels = pbsmetrics.ImpLabels{
BannerImps: impInRequest.Banner != nil,
VideoImps: impInRequest.Video != nil,
AudioImps: impInRequest.Audio != nil,
NativeImps: impInRequest.Native != nil,
}
e.me.RecordImps(impLabels)
}

// Slice of BidRequests, each a copy of the original cleaned to only contain bidder data for the named bidder
blabels := make(map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels)
cleanRequests, aliases, errs := cleanOpenRTBRequests(ctx, bidRequest, usersyncs, blabels, labels, e.gDPR, e.UsersyncIfAmbiguous)
Expand Down
20 changes: 16 additions & 4 deletions pbsmetrics/config/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,17 @@ func (me *MultiMetricsEngine) RecordConnectionClose(success bool) {
}
}

// RecordImps across all engines
func (me *MultiMetricsEngine) RecordImps(labels pbsmetrics.Labels, numImps int) {
//RecordsImps records imps with imp types across all metric engines
func (me *MultiMetricsEngine) RecordImps(implabels pbsmetrics.ImpLabels) {
for _, thisME := range *me {
thisME.RecordImps(labels, numImps)
thisME.RecordImps(implabels)
}
}

// RecordImps for the legacy endpoint
func (me *MultiMetricsEngine) RecordLegacyImps(labels pbsmetrics.Labels, numImps int) {
for _, thisME := range *me {
thisME.RecordLegacyImps(labels, numImps)
}
}

Expand Down Expand Up @@ -186,7 +193,12 @@ func (me *DummyMetricsEngine) RecordConnectionClose(success bool) {
}

// RecordImps as a noop
func (me *DummyMetricsEngine) RecordImps(labels pbsmetrics.Labels, numImps int) {
func (me *DummyMetricsEngine) RecordImps(implabels pbsmetrics.ImpLabels) {
return
}

// RecordLegacyImps as a noop
func (me *DummyMetricsEngine) RecordLegacyImps(labels pbsmetrics.Labels, numImps int) {
return
}

Expand Down
26 changes: 24 additions & 2 deletions pbsmetrics/config/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,31 @@ func TestMultiMetricsEngine(t *testing.T) {
CookieFlag: pbsmetrics.CookieFlagYes,
AdapterBids: pbsmetrics.AdapterBidPresent,
}
impTypeLabels := pbsmetrics.ImpLabels{
BannerImps: true,
VideoImps: false,
AudioImps: true,
NativeImps: true,
}
for i := 0; i < 5; i++ {
metricsEngine.RecordRequest(labels)
metricsEngine.RecordImps(labels, 2)
metricsEngine.RecordImps(impTypeLabels)
metricsEngine.RecordLegacyImps(labels, 2)
metricsEngine.RecordRequestTime(labels, 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)
}
impTypeLabels.BannerImps = false
impTypeLabels.VideoImps = true
impTypeLabels.AudioImps = false
impTypeLabels.NativeImps = false
for i := 0; i < 3; i++ {
metricsEngine.RecordImps(impTypeLabels)
}
//Make the metrics engine, instantiated here with goEngine, fill its RequestStatuses[RequestType][pbsmetrics.RequestStatusXX] with the new boolean values added to pbsmetrics.Labels
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)
Expand All @@ -87,8 +102,15 @@ func TestMultiMetricsEngine(t *testing.T) {
VerifyMetrics(t, "RequestStatuses.Video.BadInput", goEngine.RequestStatuses[pbsmetrics.ReqTypeVideo][pbsmetrics.RequestStatusBadInput].Count(), 0)
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, "ImpsTypeBanner", goEngine.ImpsTypeBanner.Count(), 5)
VerifyMetrics(t, "ImpsTypeVideo", goEngine.ImpsTypeVideo.Count(), 3)
VerifyMetrics(t, "ImpsTypeAudio", goEngine.ImpsTypeAudio.Count(), 5)
VerifyMetrics(t, "ImpsTypeNative", goEngine.ImpsTypeNative.Count(), 5)

VerifyMetrics(t, "Request", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2Web][pbsmetrics.RequestStatusOK].Count(), 5)
VerifyMetrics(t, "ImpMeter", goEngine.ImpMeter.Count(), 10)
VerifyMetrics(t, "ImpMeter", goEngine.ImpMeter.Count(), 8)
VerifyMetrics(t, "LegacyImpMeter", goEngine.LegacyImpMeter.Count(), 10)
VerifyMetrics(t, "NoCookieMeter", goEngine.NoCookieMeter.Count(), 0)
VerifyMetrics(t, "SafariRequestMeter", goEngine.SafariRequestMeter.Count(), 5)
VerifyMetrics(t, "SafariNoCookieMeter", goEngine.SafariNoCookieMeter.Count(), 0)
Expand Down
40 changes: 38 additions & 2 deletions pbsmetrics/go_metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Metrics struct {
ConnectionAcceptErrorMeter metrics.Meter
ConnectionCloseErrorMeter metrics.Meter
ImpMeter metrics.Meter
LegacyImpMeter metrics.Meter
AppRequestMeter metrics.Meter
NoCookieMeter metrics.Meter
SafariRequestMeter metrics.Meter
Expand All @@ -37,6 +38,12 @@ type Metrics struct {
userSyncSet map[openrtb_ext.BidderName]metrics.Meter
userSyncGDPRPrevent map[openrtb_ext.BidderName]metrics.Meter

// Media types found in the "imp" JSON object
ImpsTypeBanner metrics.Meter
ImpsTypeVideo metrics.Meter
ImpsTypeAudio metrics.Meter
ImpsTypeNative metrics.Meter

AdapterMetrics map[openrtb_ext.BidderName]*AdapterMetrics
// Don't export accountMetrics because we need helper functions here to insure its properly populated dynamically
accountMetrics map[string]*accountMetrics
Expand Down Expand Up @@ -91,6 +98,7 @@ func NewBlankMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderNa
ConnectionAcceptErrorMeter: blankMeter,
ConnectionCloseErrorMeter: blankMeter,
ImpMeter: blankMeter,
LegacyImpMeter: blankMeter,
AppRequestMeter: blankMeter,
NoCookieMeter: blankMeter,
SafariRequestMeter: blankMeter,
Expand All @@ -107,6 +115,11 @@ func NewBlankMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderNa
userSyncSet: make(map[openrtb_ext.BidderName]metrics.Meter),
userSyncGDPRPrevent: make(map[openrtb_ext.BidderName]metrics.Meter),

ImpsTypeBanner: blankMeter,
ImpsTypeVideo: blankMeter,
ImpsTypeAudio: blankMeter,
ImpsTypeNative: blankMeter,

AdapterMetrics: make(map[openrtb_ext.BidderName]*AdapterMetrics, len(exchanges)),
accountMetrics: make(map[string]*accountMetrics),

Expand Down Expand Up @@ -137,6 +150,13 @@ func NewMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderName) *
newMetrics.ConnectionAcceptErrorMeter = metrics.GetOrRegisterMeter("connection_accept_errors", registry)
newMetrics.ConnectionCloseErrorMeter = metrics.GetOrRegisterMeter("connection_close_errors", registry)
newMetrics.ImpMeter = metrics.GetOrRegisterMeter("imps_requested", registry)
newMetrics.LegacyImpMeter = metrics.GetOrRegisterMeter("legacy_imps_requested", registry)

newMetrics.ImpsTypeBanner = metrics.GetOrRegisterMeter("imp_banner", registry)
newMetrics.ImpsTypeVideo = metrics.GetOrRegisterMeter("imp_video", registry)
newMetrics.ImpsTypeAudio = metrics.GetOrRegisterMeter("imp_audio", registry)
newMetrics.ImpsTypeNative = metrics.GetOrRegisterMeter("imp_native", registry)

newMetrics.SafariRequestMeter = metrics.GetOrRegisterMeter("safari_requests", registry)
newMetrics.NoCookieMeter = metrics.GetOrRegisterMeter("no_cookie_requests", registry)
newMetrics.AppRequestMeter = metrics.GetOrRegisterMeter("app_requests", registry)
Expand Down Expand Up @@ -297,8 +317,24 @@ func (me *Metrics) RecordRequest(labels Labels) {
am.requestMeter.Mark(1)
}

func (me *Metrics) RecordImps(labels Labels, numImps int) {
me.ImpMeter.Mark(int64(numImps))
func (me *Metrics) RecordImps(labels ImpLabels) {
me.ImpMeter.Mark(int64(1))
if labels.BannerImps {
me.ImpsTypeBanner.Mark(int64(1))
}
if labels.VideoImps {
me.ImpsTypeVideo.Mark(int64(1))
}
if labels.AudioImps {
me.ImpsTypeAudio.Mark(int64(1))
}
if labels.NativeImps {
me.ImpsTypeNative.Mark(int64(1))
}
}

func (me *Metrics) RecordLegacyImps(labels Labels, numImps int) {
me.LegacyImpMeter.Mark(int64(numImps))
}

func (me *Metrics) RecordConnectionAccept(success bool) {
Expand Down
31 changes: 30 additions & 1 deletion pbsmetrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,22 @@ type AdapterLabels struct {
AdapterErrors map[AdapterError]struct{}
}

// ImpLabels
type ImpLabels struct {
BannerImps bool
VideoImps bool
AudioImps bool
NativeImps bool
}

// Label typecasting. Se below the type definitions for possible values

// DemandSource : Demand source enumeration
type DemandSource string

// ImpMediaType : Media type described in the "imp" JSON object TODO is this still needed?
type ImpMediaType string

// RequestType : Request type enumeration
type RequestType string

Expand Down Expand Up @@ -81,6 +92,14 @@ const (
ReqTypeVideo RequestType = "video"
)

// The media types described in the "imp" json objects
const (
ImpTypeBanner ImpMediaType = "banner"
ImpTypeVideo ImpMediaType = "video"
ImpTypeAudio ImpMediaType = "audio"
ImpTypeNative ImpMediaType = "native"
)

func RequestTypes() []RequestType {
return []RequestType{
ReqTypeLegacy,
Expand All @@ -91,6 +110,15 @@ func RequestTypes() []RequestType {
}
}

func ImpTypes() []ImpMediaType {
return []ImpMediaType{
ImpTypeBanner,
ImpTypeVideo,
ImpTypeAudio,
ImpTypeNative,
}
}

// Browser flag; at this point we only care about identifying Safari
const (
BrowserSafari Browser = "safari"
Expand Down Expand Up @@ -211,7 +239,8 @@ type MetricsEngine interface {
RecordConnectionAccept(success bool)
RecordConnectionClose(success bool)
RecordRequest(labels Labels) // ignores adapter. only statusOk and statusErr fom status
RecordImps(labels Labels, numImps int) // ignores adapter. only statusOk and statusErr fom status
RecordImps(labels ImpLabels) // RecordImps across openRTB2 engines that support the 'Native' Imp Type
RecordLegacyImps(labels Labels, numImps int) // RecordImps for the legacy engine
RecordRequestTime(labels Labels, length time.Duration) // ignores adapter. only statusOk and statusErr fom status
RecordAdapterRequest(labels AdapterLabels)
RecordAdapterPanic(labels AdapterLabels)
Expand Down
8 changes: 7 additions & 1 deletion pbsmetrics/metrics_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ func (me *MetricsEngineMock) RecordConnectionClose(success bool) {
}

// RecordImps mock
func (me *MetricsEngineMock) RecordImps(labels Labels, numImps int) {
func (me *MetricsEngineMock) RecordImps(labels ImpLabels) {
me.Called(labels)
return
}

// RecordLegacyImps mock
func (me *MetricsEngineMock) RecordLegacyImps(labels Labels, numImps int) {
me.Called(labels, numImps)
return
}
Expand Down
Loading

0 comments on commit 332ee37

Please sign in to comment.