-
Notifications
You must be signed in to change notification settings - Fork 748
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
Debug Metrics Implementation #2246
Conversation
endpoints/openrtb2/auction_test.go
Outdated
@@ -3702,7 +3702,7 @@ type warningsCheckExchange struct { | |||
auctionRequest exchange.AuctionRequest | |||
} | |||
|
|||
func (e *warningsCheckExchange) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb2.BidResponse, error) { | |||
func (e *warningsCheckExchange) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog, labels *metrics.Labels) (*openrtb2.BidResponse, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not necessary to add a new labels
argument. The labels are already present in the r exchange.AuctionRequest
argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored and removed in latest commit
metrics/metrics.go
Outdated
CookieFlag CookieFlag | ||
RequestStatus RequestStatus | ||
DebugFlag bool | ||
AccountDebugFlag bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you'll be fine with a single debug flag, perhaps naming DebugEnabed
or DebugRequested
or perhaps even Debug
. We don't care how debug is enabled, just that it is is enabled. With the implementation of the debug permissions, I can easily see how you arrived at this though. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah this makes sense! I'll update accordingly.
metrics/prometheus/prometheus.go
Outdated
metrics.requestsDebug = newCounter(cfg, reg, | ||
"requests_debug", | ||
"Count of total requests to Prebid Server that have debug enabled labled by type, status.", | ||
[]string{requestTypeLabel, requestStatusLabel}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not believe we need to have any labels on this metric. I personally don't see any value in the status label and only minimal value in the types label. I won't put up a fight it you want to keep the type label, but I'll need convincing on why this is important for the status label.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I struggled to think of reasons to have the labels, but I initially just matched the format of metrics.requests
. But I feel comfortable with removing both
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed during stand up, both labels have been removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Let's try to improve the flow of the debug flag, or put it off for a future update if we think of a good idea and decide it's too much work to include here.
endpoints/openrtb2/amp_auction.go
Outdated
@@ -219,6 +220,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |||
ao.Errors = append(ao.Errors, err) | |||
return | |||
} | |||
labels.DebugEnabled = debugLog.DebugFlag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of this line? ... since it occurs after the HoldAuction
call. Wouldn't the metrics for an incoming request have been recorded before hitting this line? Same applies to openrtb/auction.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand this correctly, metrics will be written at the end of endpoint execution. It's defined in defer section, L122:
defer func() {
deps.metricsEngine.RecordRequest(labels)
deps.metricsEngine.RecordRequestTime(labels, time.Since(start))
deps.analytics.LogAmpObject(&ao)
}()
Auction, video and amp endpoints have this approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah exactly like Veronika said above! And when I sent test postman requests, it acted like this as well!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah. Got it. This code is a bit too clever IMHO, but I agree it's beyond the scope of this PR to fix. Can you add a comment before these lines to make it clear what's going on to my future self?
endpoints/openrtb2/amp_auction.go
Outdated
@@ -219,6 +220,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |||
ao.Errors = append(ao.Errors, err) | |||
return | |||
} | |||
labels.DebugEnabled = debugLog.DebugFlag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I consider it a "code smell" that debugLog
is instantiated here just to return the DebugFlag to the outer scope. It would be preferable IMHO to either calculate the debug flag prior to calling HoldAuction
or include it as a return argument somehow. I know you didn't create this situation, but I believe it's worth an investigation to try and make this flow a bit nicer now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better if labels.DebugEnabled will be passed in auctionRequest
downstrem to getDebugInfo
and modified there?
I cannot think about better solution...
endpoints/openrtb2/amp_auction.go
Outdated
@@ -219,6 +220,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |||
ao.Errors = append(ao.Errors, err) | |||
return | |||
} | |||
labels.DebugEnabled = debugLog.DebugFlag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I consider it a "code smell" that debugLog
is instantiated here just to return the DebugFlag to the outer scope. It would be preferable IMHO to either calculate the debug flag prior to calling HoldAuction
or include it as a return argument somehow. I know you didn't create this situation, but I believe it's worth an investigation to try and make this flow a bit nicer now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Scott here. This definitely seems odd to instantiate the debugLog
struct here just to return the DebugFlag
to the outer scope. How about making debugLog
a part of the AuctionRequest
struct? That way you can read and modify it in HoldAuction
as needed and you can again access it outside of HoldAuction
for setting the metrics label and such
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that code smell call out makes total sense! I wrote up some code just now to put debugLog
in the AuctionRequest
struct, and that solution worked! I need to run some more tests, but I think that would be a valid solution to this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That way you can read and modify it in HoldAuction as needed and you can again access it outside of HoldAuction for setting the metrics label and such
A step in the right direction, but modifying it as a way to pass information upstream is still an undesirable design. We might have to tackle that later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good to me. Please resolve Scott's comments.
endpoints/openrtb2/amp_auction.go
Outdated
@@ -219,6 +220,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |||
ao.Errors = append(ao.Errors, err) | |||
return | |||
} | |||
labels.DebugEnabled = debugLog.DebugFlag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of this line? ... since it occurs after the HoldAuction
call. Wouldn't the metrics for an incoming request have been recorded before hitting this line?
endpoints/openrtb2/amp_auction.go
Outdated
@@ -219,6 +220,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |||
ao.Errors = append(ao.Errors, err) | |||
return | |||
} | |||
labels.DebugEnabled = debugLog.DebugFlag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah. Got it. This code is a bit too clever IMHO, but I agree it's beyond the scope of this PR to fix. Can you add a comment before these lines to make it clear what's going on to my future self?
endpoints/openrtb2/amp_auction.go
Outdated
@@ -219,6 +220,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |||
ao.Errors = append(ao.Errors, err) | |||
return | |||
} | |||
labels.DebugEnabled = debugLog.DebugFlag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That way you can read and modify it in HoldAuction as needed and you can again access it outside of HoldAuction for setting the metrics label and such
A step in the right direction, but modifying it as a way to pass information upstream is still an undesirable design. We might have to tackle that later on.
There's one other thing I think we should do here that is perhaps create a new function for recording debug enabled requests rather than using the current record request method. Then you can just call that record method in |
The latest commit I pushed is the one where I implemented a function And as a heads up, I wrongfully titled the name of this commit to be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
metrics/go_metrics.go
Outdated
} | ||
|
||
am := me.getAccountMetrics(pubID) | ||
if !me.MetricsDisabled.AccountDebug && debugEnabled { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can simplify this by moving this block of code into the if condition on L438 as well. This will help get rid of the debugEnabled
check here. Also, shouldn't we check that the publisher ID isn't unknown
here as well like you're doing for Prometheus's record debug function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I'll refactor this and add the unknown check as well!
metrics/prometheus/prometheus.go
Outdated
@@ -182,6 +184,10 @@ func NewMetrics(cfg config.PrometheusMetrics, disabledMetrics config.DisabledMet | |||
"Count of total requests to Prebid Server labeled by type and status.", | |||
[]string{requestTypeLabel, requestStatusLabel}) | |||
|
|||
metrics.requestsDebug = newCounterWithoutLabels(cfg, reg, | |||
"requests_debug", | |||
"Count of total requests to Prebid Server that have debug enabled labled by type, status.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are not going to be labeled by type and status so please update the description accordingly
metrics/prometheus/prometheus.go
Outdated
@@ -370,6 +376,11 @@ func NewMetrics(cfg config.PrometheusMetrics, disabledMetrics config.DisabledMet | |||
"Count of total requests to Prebid Server labeled by account.", | |||
[]string{accountLabel}) | |||
|
|||
metrics.accountDebugRequests = newCounter(cfg, reg, | |||
"account_requests_debug", | |||
"Count of total requests to Prebid Server where the account has debug enabled labeled by account.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please update the description here to be something along the lines of:
Count of total requests to Prebid Server that have debug enabled labled by account
@@ -487,6 +487,9 @@ type DisabledMetrics struct { | |||
// True if we want to stop collecting account-to-adapter metrics | |||
AccountAdapterDetails bool `mapstructure:"account_adapter_details"` | |||
|
|||
// True if we want to stop collecting account debug request metrics | |||
AccountDebug bool `mapstructure:"account_debug"` | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add tests for this new config option in config_test.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is looking pretty close. Thanks for addressing all the feedback. I have one major comment about the different types being used for account vs non-account metric in Prometheus. The other two are quite minor
expectedDebugCount float64 | ||
}{ | ||
{ | ||
description: "Boolean flags should result in both metrics being updated", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please specify what the boolean flags are set to in the description. For readability purposes and for when tests fail these descriptions help us easily understand what was passed in and what was expected. I like the descriptions you have for the last two test cases. Could you please update these to have the same format as well?
I noticed the same thing in the go_metrics_test.go
file as well
config/config_test.go
Outdated
@@ -611,6 +612,7 @@ func TestFullConfig(t *testing.T) { | |||
cmpBools(t, "account_required", cfg.AccountRequired, true) | |||
cmpBools(t, "auto_gen_source_tid", cfg.AutoGenSourceTID, false) | |||
cmpBools(t, "account_adapter_details", cfg.Metrics.Disabled.AccountAdapterDetails, true) | |||
cmpBools(t, "account_debug", cfg.Metrics.Disabled.AccountDebug, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the TestFullConfig
I would suggest setting the value for account_debug
to be false
(different from the default value) in the above fullConfig
value and assert it here to be false
as well. This just helps us test through both the flow with default values and non-default values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
This PR implements the feature/issue #1474
The goal is to add new metrics to PBS related to debug
The first new debug metric, is one that counts the number of requests we receive that has debug enabled.
The second new debug metric, is one that counts the number of requests from an account that has debug enabled.
This second metric is controlled by a config flag
"metrics.disabled_metrics.account_debug"
because of concerns of high cardinalityThese metrics are implemented for both
prometheus
andinflux
, by creating/implementing a new record functionRecordDebugRequest()
within both metrics' frameworks.This function is then called within
HoldAuction()
after we receive debug information from thegetDebugInfo()
call.For influx, I added two new meters to represent the new metrics in the
Metrics
andAccountMetrics
struct,DebugRequestMeter
andaccountMetrics.DebugRequestMeter
For prometheus, I added two new metrics to the prometheus specific Metrics struct
debugRequests
andaccountDebugRequests
New tests were included to test these updated metrics
Other metrics engines like nil metrics, multi metrics, and metrics mock, only need to be updated with a simple handling of how they implement/call
RecordDebugRequest()