Add request body size metric
Change-Id: Ica5d9b5457d4f844c4500b2c05b2f0631c27454c Kubernetes-commit: 43c95cbf0682895cf5bb79452b1f011123ac4513
This commit is contained in:
parent
270d177e30
commit
ce7b4d6e8c
|
@ -37,6 +37,7 @@ import (
|
|||
"k8s.io/apiserver/pkg/audit"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/finisher"
|
||||
requestmetrics "k8s.io/apiserver/pkg/endpoints/handlers/metrics"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
@ -86,7 +87,7 @@ func createHandler(r rest.NamedCreater, scope *RequestScope, admit admission.Int
|
|||
return
|
||||
}
|
||||
|
||||
body, err := limitedReadBody(req, scope.MaxRequestBodyBytes)
|
||||
body, err := limitedReadBodyWithRecordMetric(ctx, req, scope.MaxRequestBodyBytes, scope.Resource.GroupResource().String(), requestmetrics.Create)
|
||||
trace.Step("limitedReadBody done", utiltrace.Field{"len", len(body)}, utiltrace.Field{"err", err})
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/audit"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/finisher"
|
||||
requestmetrics "k8s.io/apiserver/pkg/endpoints/handlers/metrics"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
@ -70,7 +71,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope *RequestSc
|
|||
|
||||
options := &metav1.DeleteOptions{}
|
||||
if allowsOptions {
|
||||
body, err := limitedReadBody(req, scope.MaxRequestBodyBytes)
|
||||
body, err := limitedReadBodyWithRecordMetric(ctx, req, scope.MaxRequestBodyBytes, scope.Resource.GroupResource().String(), requestmetrics.Patch)
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
|
|
|
@ -17,9 +17,19 @@ limitations under the License.
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"k8s.io/component-base/metrics"
|
||||
)
|
||||
|
||||
type RequestBodyVerb string
|
||||
|
||||
const (
|
||||
Patch RequestBodyVerb = "patch"
|
||||
Delete RequestBodyVerb = "delete"
|
||||
Update RequestBodyVerb = "update"
|
||||
Create RequestBodyVerb = "create"
|
||||
)
|
||||
|
||||
var (
|
||||
RequestBodySizes = metrics.NewHistogramVec(
|
||||
&metrics.HistogramOpts{
|
||||
|
@ -34,3 +44,7 @@ var (
|
|||
[]string{"resource", "verb"},
|
||||
)
|
||||
)
|
||||
|
||||
func RecordRequestBodySize(ctx context.Context, resource string, verb RequestBodyVerb, size int) {
|
||||
RequestBodySizes.WithContext(ctx).WithLabelValues(resource, string(verb)).Observe(float64(size))
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
kjson "sigs.k8s.io/json"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metainternalversionscheme "k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme"
|
||||
|
@ -45,6 +45,7 @@ import (
|
|||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/finisher"
|
||||
requestmetrics "k8s.io/apiserver/pkg/endpoints/handlers/metrics"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
@ -98,7 +99,7 @@ func PatchResource(r rest.Patcher, scope *RequestScope, admit admission.Interfac
|
|||
return
|
||||
}
|
||||
|
||||
patchBytes, err := limitedReadBody(req, scope.MaxRequestBodyBytes)
|
||||
patchBytes, err := limitedReadBodyWithRecordMetric(ctx, req, scope.MaxRequestBodyBytes, scope.Resource.GroupResource().String(), requestmetrics.Patch)
|
||||
trace.Step("limitedReadBody done", utiltrace.Field{"len", len(patchBytes)}, utiltrace.Field{"err", err})
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
|
|
|
@ -41,6 +41,7 @@ import (
|
|||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
|
||||
requestmetrics "k8s.io/apiserver/pkg/endpoints/handlers/metrics"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
||||
"k8s.io/apiserver/pkg/endpoints/metrics"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
|
@ -390,6 +391,15 @@ func limitedReadBody(req *http.Request, limit int64) ([]byte, error) {
|
|||
return data, nil
|
||||
}
|
||||
|
||||
func limitedReadBodyWithRecordMetric(ctx context.Context, req *http.Request, limit int64, resourceGroup string, verb requestmetrics.RequestBodyVerb) ([]byte, error) {
|
||||
readBody, err := limitedReadBody(req, limit)
|
||||
if err == nil {
|
||||
// only record if we've read successfully
|
||||
requestmetrics.RecordRequestBodySize(ctx, resourceGroup, verb, len(readBody))
|
||||
}
|
||||
return readBody, err
|
||||
}
|
||||
|
||||
func isDryRun(url *url.URL) bool {
|
||||
return len(url.Query()["dryRun"]) != 0
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ func TestLimitedReadBody(t *testing.T) {
|
|||
apiserver_request_body_sizes_bucket{resource="resource.group",verb="create",le="2.95e+06"} 1
|
||||
apiserver_request_body_sizes_bucket{resource="resource.group",verb="create",le="3.05e+06"} 1
|
||||
apiserver_request_body_sizes_bucket{resource="resource.group",verb="create",le="+Inf"} 1
|
||||
apiserver_request_body_sizes_sum{resource="resource.group",verb="create"} 3
|
||||
apiserver_request_body_sizes_sum{resource="resource.group",verb="create"} 4
|
||||
apiserver_request_body_sizes_count{resource="resource.group",verb="create"} 1
|
||||
`,
|
||||
expectedErr: false,
|
||||
|
@ -185,7 +185,7 @@ func TestLimitedReadBody(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("err not expected: got %v", err)
|
||||
}
|
||||
_, err = limitedReadBody(context.Background(), req, tc.limit, "resource.group", "create")
|
||||
_, err = limitedReadBodyWithRecordMetric(context.Background(), req, tc.limit, "resource.group", metrics.Create)
|
||||
if tc.expectedErr {
|
||||
if err == nil {
|
||||
t.Errorf("err expected: got nil")
|
||||
|
|
|
@ -35,6 +35,7 @@ import (
|
|||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/finisher"
|
||||
requestmetrics "k8s.io/apiserver/pkg/endpoints/handlers/metrics"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
@ -69,7 +70,7 @@ func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interfa
|
|||
return
|
||||
}
|
||||
|
||||
body, err := limitedReadBody(req, scope.MaxRequestBodyBytes)
|
||||
body, err := limitedReadBodyWithRecordMetric(ctx, req, scope.MaxRequestBodyBytes, scope.Resource.GroupResource().String(), requestmetrics.Update)
|
||||
trace.Step("limitedReadBody done", utiltrace.Field{"len", len(body)}, utiltrace.Field{"err", err})
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
|
|
Loading…
Reference in New Issue