-
Notifications
You must be signed in to change notification settings - Fork 40k
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
Collect prometheus metrics for custom resources #57682
Collect prometheus metrics for custom resources #57682
Conversation
/area custom-resources |
e373ba4
to
3fd9f50
Compare
httpCode = rw.Status() | ||
} | ||
} | ||
metrics.Record(req, requestInfo, w.Header().Get("Content-Type"), httpCode, responseLength, time.Now().Sub(reqStart)) |
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.
is this go func duplicated from the normal endpoints? Any chance to factor out the later and reuse it here?
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, will do. 👍
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.
Done.
3fd9f50
to
6ccdd75
Compare
6ccdd75
to
5cdf4ec
Compare
@@ -57,16 +57,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { | |||
|
|||
var httpCode int | |||
var requestInfo *request.RequestInfo | |||
defer func() { |
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.
this is only the special proxy handler. Something similar must be in the other endpoints.
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.
Just one comment, otherwise lgtm
@@ -152,6 +154,9 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { | |||
return | |||
} | |||
|
|||
var httpCode int | |||
defer handlers.RecordMetrics(w, req, requestInfo, httpCode, reqStart) |
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.
Do we really want to add this code to each and every handler? Seems like it would make sense to wrap each handler in a handler that records 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.
You probably overestimate the number of handlers. We have the proxy handler, the crd handler and basically all other API handlers (impemented in a generic way).
Though having this as a decorator would be better. Not sure that's feasible code-wise?
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 see, then I'm fine with this, I just thought we're doing this for every API avilable.
Is the crdHandler handling CRDs or CRs? |
CRs. |
To be precise, it is named as |
CRDs use the normal code-path of native resources. Do we have metrics problems as well for CRDs? |
I think we already collect metrics for CRDs but personally I am not interested in those. User CRD requests to the k8s API are almost zero (one per resource during registration). I just wanted to make sure because the name of the handler type is confusing. |
No, metrics for CRDs works fine. |
/retest |
5cdf4ec
to
86c2aee
Compare
@@ -283,3 +274,14 @@ func singleJoiningSlash(a, b string) string { | |||
} | |||
return a + b | |||
} | |||
|
|||
func RecordMetrics(w http.ResponseWriter, req *http.Request, requestInfo *request.RequestInfo, httpCode int, reqStart time.Time) { |
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.
Compare
func InstrumentRouteFunc(verb, resource, subresource, scope string, routeFunc restful.RouteFunction) restful.RouteFunction { |
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.
Any blockers here?
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.
Any blockers here?
We don't have a restful.RouteFunction
here in this handler. Any reason why the RecordMetrics
is incorrect?
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.
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.
@sttts updated to use InstrumentHandlerFunc
. ptal, thanks.
86c2aee
to
336f33b
Compare
} | ||
} | ||
|
||
func CleanScope(requestInfo *request.RequestInfo) string { |
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.
godoc
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.
Done.
@brancz do you know the metrics code in the apiserver? Can you take a look? |
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.
@sttts I wouldn't say I'm intimately familiar with it, but from a general metrics perspective and digging through the code for some time now, I think this looks good.
handler(w, req) | ||
return | ||
case "deletecollection": | ||
checkBody := true | ||
handler := handlers.DeleteCollection(storage, checkBody, requestScope, r.admission) | ||
handler = metrics.InstrumentHandlerFunc(verb, resource, subresource, scope, handler) |
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 metrics.InstrumentHandlerFunc calls seem duplicated, maybe we can just set the handler in each of these blocks and call this once?
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.
with a global handler var, we could remove the instrumentation call, the handler(w,req)
call and the return and do those uniformely for all non-default cases below the switch.
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.
Done.
e03a11b
to
6043876
Compare
Since we have a custom handler for apiextensions-apiserver, we need to record the metrics here.
/retest |
/lgtm |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: brancz, nikhita, sttts The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these OWNERS Files:
Approvers can indicate their approval by writing |
/test all [submit-queue is verifying that this PR is safe to merge] |
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions here. |
Enables apiserver metrics for custom resources.
Fixes #55146
Release note:
/cc sttts deads2k kargakis brancz