Skip to content

Commit 92d91ae

Browse files
authored
Add Native-Specific Metrics to Prebid Server (#930)
* 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
1 parent 8c13c5c commit 92d91ae

File tree

12 files changed

+294
-46
lines changed

12 files changed

+294
-46
lines changed

endpoints/auction.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ func (a *auction) auction(w http.ResponseWriter, r *http.Request, _ httprouter.P
9797
defer func() {
9898
if req == nil {
9999
a.metricsEngine.RecordRequest(labels)
100-
a.metricsEngine.RecordImps(labels, 0)
100+
a.metricsEngine.RecordLegacyImps(labels, 0)
101101
} else {
102102
// handles the case that ParsePBSRequest returns an error, so req.Start is not defined
103103
a.metricsEngine.RecordRequest(labels)
104-
a.metricsEngine.RecordImps(labels, len(req.AdUnits))
104+
a.metricsEngine.RecordLegacyImps(labels, len(req.AdUnits))
105105
a.metricsEngine.RecordRequestTime(labels, time.Since(req.Start))
106106
}
107107
}()

endpoints/openrtb2/amp_auction.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h
9898
}
9999
defer func() {
100100
deps.metricsEngine.RecordRequest(labels)
101-
deps.metricsEngine.RecordImps(labels, 1)
102101
deps.metricsEngine.RecordRequestTime(labels, time.Since(start))
103102
deps.analytics.LogAmpObject(&ao)
104103
}()

endpoints/openrtb2/auction.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,8 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http
9494
CookieFlag: pbsmetrics.CookieFlagUnknown,
9595
RequestStatus: pbsmetrics.RequestStatusOK,
9696
}
97-
numImps := 0
9897
defer func() {
9998
deps.metricsEngine.RecordRequest(labels)
100-
deps.metricsEngine.RecordImps(labels, numImps)
10199
deps.metricsEngine.RecordRequestTime(labels, time.Since(start))
102100
deps.analytics.LogAuctionObject(&ao)
103101
}()
@@ -138,7 +136,6 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http
138136
labels.PubID = effectivePubID(req.Site.Publisher)
139137
}
140138

141-
numImps = len(req.Imp)
142139
response, err := deps.ex.HoldAuction(ctx, req, usersyncs, labels, &deps.categories)
143140
ao.Request = req
144141
ao.Response = response

endpoints/openrtb2/video_auction.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,8 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
7979
CookieFlag: pbsmetrics.CookieFlagUnknown,
8080
RequestStatus: pbsmetrics.RequestStatusOK,
8181
}
82-
numImps := 0
8382
defer func() {
8483
deps.metricsEngine.RecordRequest(labels)
85-
deps.metricsEngine.RecordImps(labels, numImps)
8684
deps.metricsEngine.RecordRequestTime(labels, time.Since(start))
8785
deps.analytics.LogAuctionObject(&ao)
8886
}()
@@ -201,8 +199,6 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
201199
labels.PubID = effectivePubID(bidReq.Site.Publisher)
202200
}
203201

204-
numImps = len(bidReq.Imp)
205-
206202
//execute auction logic
207203
response, err := deps.ex.HoldAuction(ctx, bidReq, usersyncs, labels, &deps.categories)
208204
ao.Request = bidReq

exchange/exchange.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque
8585
}
8686
}
8787

88+
for _, impInRequest := range bidRequest.Imp {
89+
var impLabels pbsmetrics.ImpLabels = pbsmetrics.ImpLabels{
90+
BannerImps: impInRequest.Banner != nil,
91+
VideoImps: impInRequest.Video != nil,
92+
AudioImps: impInRequest.Audio != nil,
93+
NativeImps: impInRequest.Native != nil,
94+
}
95+
e.me.RecordImps(impLabels)
96+
}
97+
8898
// Slice of BidRequests, each a copy of the original cleaned to only contain bidder data for the named bidder
8999
blabels := make(map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels)
90100
cleanRequests, aliases, errs := cleanOpenRTBRequests(ctx, bidRequest, usersyncs, blabels, labels, e.gDPR, e.UsersyncIfAmbiguous)

pbsmetrics/config/metrics.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,17 @@ func (me *MultiMetricsEngine) RecordConnectionClose(success bool) {
8383
}
8484
}
8585

86-
// RecordImps across all engines
87-
func (me *MultiMetricsEngine) RecordImps(labels pbsmetrics.Labels, numImps int) {
86+
//RecordsImps records imps with imp types across all metric engines
87+
func (me *MultiMetricsEngine) RecordImps(implabels pbsmetrics.ImpLabels) {
8888
for _, thisME := range *me {
89-
thisME.RecordImps(labels, numImps)
89+
thisME.RecordImps(implabels)
90+
}
91+
}
92+
93+
// RecordImps for the legacy endpoint
94+
func (me *MultiMetricsEngine) RecordLegacyImps(labels pbsmetrics.Labels, numImps int) {
95+
for _, thisME := range *me {
96+
thisME.RecordLegacyImps(labels, numImps)
9097
}
9198
}
9299

@@ -186,7 +193,12 @@ func (me *DummyMetricsEngine) RecordConnectionClose(success bool) {
186193
}
187194

188195
// RecordImps as a noop
189-
func (me *DummyMetricsEngine) RecordImps(labels pbsmetrics.Labels, numImps int) {
196+
func (me *DummyMetricsEngine) RecordImps(implabels pbsmetrics.ImpLabels) {
197+
return
198+
}
199+
200+
// RecordLegacyImps as a noop
201+
func (me *DummyMetricsEngine) RecordLegacyImps(labels pbsmetrics.Labels, numImps int) {
190202
return
191203
}
192204

pbsmetrics/config/metrics_test.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,31 @@ func TestMultiMetricsEngine(t *testing.T) {
6969
CookieFlag: pbsmetrics.CookieFlagYes,
7070
AdapterBids: pbsmetrics.AdapterBidPresent,
7171
}
72+
impTypeLabels := pbsmetrics.ImpLabels{
73+
BannerImps: true,
74+
VideoImps: false,
75+
AudioImps: true,
76+
NativeImps: true,
77+
}
7278
for i := 0; i < 5; i++ {
7379
metricsEngine.RecordRequest(labels)
74-
metricsEngine.RecordImps(labels, 2)
80+
metricsEngine.RecordImps(impTypeLabels)
81+
metricsEngine.RecordLegacyImps(labels, 2)
7582
metricsEngine.RecordRequestTime(labels, time.Millisecond*20)
7683
metricsEngine.RecordAdapterRequest(pubLabels)
7784
metricsEngine.RecordAdapterRequest(apnLabels)
7885
metricsEngine.RecordAdapterPrice(pubLabels, 1.34)
7986
metricsEngine.RecordAdapterBidReceived(pubLabels, openrtb_ext.BidTypeBanner, true)
8087
metricsEngine.RecordAdapterTime(pubLabels, time.Millisecond*20)
8188
}
89+
impTypeLabels.BannerImps = false
90+
impTypeLabels.VideoImps = true
91+
impTypeLabels.AudioImps = false
92+
impTypeLabels.NativeImps = false
93+
for i := 0; i < 3; i++ {
94+
metricsEngine.RecordImps(impTypeLabels)
95+
}
96+
//Make the metrics engine, instantiated here with goEngine, fill its RequestStatuses[RequestType][pbsmetrics.RequestStatusXX] with the new boolean values added to pbsmetrics.Labels
8297
VerifyMetrics(t, "RequestStatuses.OpenRTB2.OK", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2Web][pbsmetrics.RequestStatusOK].Count(), 5)
8398
VerifyMetrics(t, "RequestStatuses.Legacy.OK", goEngine.RequestStatuses[pbsmetrics.ReqTypeLegacy][pbsmetrics.RequestStatusOK].Count(), 0)
8499
VerifyMetrics(t, "RequestStatuses.AMP.OK", goEngine.RequestStatuses[pbsmetrics.ReqTypeAMP][pbsmetrics.RequestStatusOK].Count(), 0)
@@ -87,8 +102,15 @@ func TestMultiMetricsEngine(t *testing.T) {
87102
VerifyMetrics(t, "RequestStatuses.Video.BadInput", goEngine.RequestStatuses[pbsmetrics.ReqTypeVideo][pbsmetrics.RequestStatusBadInput].Count(), 0)
88103
VerifyMetrics(t, "RequestStatuses.OpenRTB2.Error", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2Web][pbsmetrics.RequestStatusErr].Count(), 0)
89104
VerifyMetrics(t, "RequestStatuses.OpenRTB2.BadInput", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2Web][pbsmetrics.RequestStatusBadInput].Count(), 0)
105+
106+
VerifyMetrics(t, "ImpsTypeBanner", goEngine.ImpsTypeBanner.Count(), 5)
107+
VerifyMetrics(t, "ImpsTypeVideo", goEngine.ImpsTypeVideo.Count(), 3)
108+
VerifyMetrics(t, "ImpsTypeAudio", goEngine.ImpsTypeAudio.Count(), 5)
109+
VerifyMetrics(t, "ImpsTypeNative", goEngine.ImpsTypeNative.Count(), 5)
110+
90111
VerifyMetrics(t, "Request", goEngine.RequestStatuses[pbsmetrics.ReqTypeORTB2Web][pbsmetrics.RequestStatusOK].Count(), 5)
91-
VerifyMetrics(t, "ImpMeter", goEngine.ImpMeter.Count(), 10)
112+
VerifyMetrics(t, "ImpMeter", goEngine.ImpMeter.Count(), 8)
113+
VerifyMetrics(t, "LegacyImpMeter", goEngine.LegacyImpMeter.Count(), 10)
92114
VerifyMetrics(t, "NoCookieMeter", goEngine.NoCookieMeter.Count(), 0)
93115
VerifyMetrics(t, "SafariRequestMeter", goEngine.SafariRequestMeter.Count(), 5)
94116
VerifyMetrics(t, "SafariNoCookieMeter", goEngine.SafariNoCookieMeter.Count(), 0)

pbsmetrics/go_metrics.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Metrics struct {
1717
ConnectionAcceptErrorMeter metrics.Meter
1818
ConnectionCloseErrorMeter metrics.Meter
1919
ImpMeter metrics.Meter
20+
LegacyImpMeter metrics.Meter
2021
AppRequestMeter metrics.Meter
2122
NoCookieMeter metrics.Meter
2223
SafariRequestMeter metrics.Meter
@@ -37,6 +38,12 @@ type Metrics struct {
3738
userSyncSet map[openrtb_ext.BidderName]metrics.Meter
3839
userSyncGDPRPrevent map[openrtb_ext.BidderName]metrics.Meter
3940

41+
// Media types found in the "imp" JSON object
42+
ImpsTypeBanner metrics.Meter
43+
ImpsTypeVideo metrics.Meter
44+
ImpsTypeAudio metrics.Meter
45+
ImpsTypeNative metrics.Meter
46+
4047
AdapterMetrics map[openrtb_ext.BidderName]*AdapterMetrics
4148
// Don't export accountMetrics because we need helper functions here to insure its properly populated dynamically
4249
accountMetrics map[string]*accountMetrics
@@ -91,6 +98,7 @@ func NewBlankMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderNa
9198
ConnectionAcceptErrorMeter: blankMeter,
9299
ConnectionCloseErrorMeter: blankMeter,
93100
ImpMeter: blankMeter,
101+
LegacyImpMeter: blankMeter,
94102
AppRequestMeter: blankMeter,
95103
NoCookieMeter: blankMeter,
96104
SafariRequestMeter: blankMeter,
@@ -107,6 +115,11 @@ func NewBlankMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderNa
107115
userSyncSet: make(map[openrtb_ext.BidderName]metrics.Meter),
108116
userSyncGDPRPrevent: make(map[openrtb_ext.BidderName]metrics.Meter),
109117

118+
ImpsTypeBanner: blankMeter,
119+
ImpsTypeVideo: blankMeter,
120+
ImpsTypeAudio: blankMeter,
121+
ImpsTypeNative: blankMeter,
122+
110123
AdapterMetrics: make(map[openrtb_ext.BidderName]*AdapterMetrics, len(exchanges)),
111124
accountMetrics: make(map[string]*accountMetrics),
112125

@@ -137,6 +150,13 @@ func NewMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderName) *
137150
newMetrics.ConnectionAcceptErrorMeter = metrics.GetOrRegisterMeter("connection_accept_errors", registry)
138151
newMetrics.ConnectionCloseErrorMeter = metrics.GetOrRegisterMeter("connection_close_errors", registry)
139152
newMetrics.ImpMeter = metrics.GetOrRegisterMeter("imps_requested", registry)
153+
newMetrics.LegacyImpMeter = metrics.GetOrRegisterMeter("legacy_imps_requested", registry)
154+
155+
newMetrics.ImpsTypeBanner = metrics.GetOrRegisterMeter("imp_banner", registry)
156+
newMetrics.ImpsTypeVideo = metrics.GetOrRegisterMeter("imp_video", registry)
157+
newMetrics.ImpsTypeAudio = metrics.GetOrRegisterMeter("imp_audio", registry)
158+
newMetrics.ImpsTypeNative = metrics.GetOrRegisterMeter("imp_native", registry)
159+
140160
newMetrics.SafariRequestMeter = metrics.GetOrRegisterMeter("safari_requests", registry)
141161
newMetrics.NoCookieMeter = metrics.GetOrRegisterMeter("no_cookie_requests", registry)
142162
newMetrics.AppRequestMeter = metrics.GetOrRegisterMeter("app_requests", registry)
@@ -297,8 +317,24 @@ func (me *Metrics) RecordRequest(labels Labels) {
297317
am.requestMeter.Mark(1)
298318
}
299319

300-
func (me *Metrics) RecordImps(labels Labels, numImps int) {
301-
me.ImpMeter.Mark(int64(numImps))
320+
func (me *Metrics) RecordImps(labels ImpLabels) {
321+
me.ImpMeter.Mark(int64(1))
322+
if labels.BannerImps {
323+
me.ImpsTypeBanner.Mark(int64(1))
324+
}
325+
if labels.VideoImps {
326+
me.ImpsTypeVideo.Mark(int64(1))
327+
}
328+
if labels.AudioImps {
329+
me.ImpsTypeAudio.Mark(int64(1))
330+
}
331+
if labels.NativeImps {
332+
me.ImpsTypeNative.Mark(int64(1))
333+
}
334+
}
335+
336+
func (me *Metrics) RecordLegacyImps(labels Labels, numImps int) {
337+
me.LegacyImpMeter.Mark(int64(numImps))
302338
}
303339

304340
func (me *Metrics) RecordConnectionAccept(success bool) {

pbsmetrics/metrics.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,22 @@ type AdapterLabels struct {
2828
AdapterErrors map[AdapterError]struct{}
2929
}
3030

31+
// ImpLabels
32+
type ImpLabels struct {
33+
BannerImps bool
34+
VideoImps bool
35+
AudioImps bool
36+
NativeImps bool
37+
}
38+
3139
// Label typecasting. Se below the type definitions for possible values
3240

3341
// DemandSource : Demand source enumeration
3442
type DemandSource string
3543

44+
// ImpMediaType : Media type described in the "imp" JSON object TODO is this still needed?
45+
type ImpMediaType string
46+
3647
// RequestType : Request type enumeration
3748
type RequestType string
3849

@@ -81,6 +92,14 @@ const (
8192
ReqTypeVideo RequestType = "video"
8293
)
8394

95+
// The media types described in the "imp" json objects
96+
const (
97+
ImpTypeBanner ImpMediaType = "banner"
98+
ImpTypeVideo ImpMediaType = "video"
99+
ImpTypeAudio ImpMediaType = "audio"
100+
ImpTypeNative ImpMediaType = "native"
101+
)
102+
84103
func RequestTypes() []RequestType {
85104
return []RequestType{
86105
ReqTypeLegacy,
@@ -91,6 +110,15 @@ func RequestTypes() []RequestType {
91110
}
92111
}
93112

113+
func ImpTypes() []ImpMediaType {
114+
return []ImpMediaType{
115+
ImpTypeBanner,
116+
ImpTypeVideo,
117+
ImpTypeAudio,
118+
ImpTypeNative,
119+
}
120+
}
121+
94122
// Browser flag; at this point we only care about identifying Safari
95123
const (
96124
BrowserSafari Browser = "safari"
@@ -211,7 +239,8 @@ type MetricsEngine interface {
211239
RecordConnectionAccept(success bool)
212240
RecordConnectionClose(success bool)
213241
RecordRequest(labels Labels) // ignores adapter. only statusOk and statusErr fom status
214-
RecordImps(labels Labels, numImps int) // ignores adapter. only statusOk and statusErr fom status
242+
RecordImps(labels ImpLabels) // RecordImps across openRTB2 engines that support the 'Native' Imp Type
243+
RecordLegacyImps(labels Labels, numImps int) // RecordImps for the legacy engine
215244
RecordRequestTime(labels Labels, length time.Duration) // ignores adapter. only statusOk and statusErr fom status
216245
RecordAdapterRequest(labels AdapterLabels)
217246
RecordAdapterPanic(labels AdapterLabels)

pbsmetrics/metrics_mock.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ func (me *MetricsEngineMock) RecordConnectionClose(success bool) {
3131
}
3232

3333
// RecordImps mock
34-
func (me *MetricsEngineMock) RecordImps(labels Labels, numImps int) {
34+
func (me *MetricsEngineMock) RecordImps(labels ImpLabels) {
35+
me.Called(labels)
36+
return
37+
}
38+
39+
// RecordLegacyImps mock
40+
func (me *MetricsEngineMock) RecordLegacyImps(labels Labels, numImps int) {
3541
me.Called(labels, numImps)
3642
return
3743
}

0 commit comments

Comments
 (0)