Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Native-Specific Metrics to Prebid Server #930

Merged
merged 19 commits into from
Jul 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
guscarreon marked this conversation as resolved.
Show resolved Hide resolved
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