Align admission metric names with prometheus guidelines

This commit is contained in:
Joe Betz 2017-11-14 11:18:31 -08:00
parent 375e2d03ab
commit 369fd81ca1
5 changed files with 46 additions and 46 deletions

View File

@ -18,7 +18,7 @@ package admission
import "time" import "time"
// chainAdmissionHandler is an instance of admission.Interface that performs admission control using // chainAdmissionHandler is an instance of admission.NamedHandler that performs admission control using
// a chain of admission handlers // a chain of admission handlers
type chainAdmissionHandler []NamedHandler type chainAdmissionHandler []NamedHandler
@ -35,15 +35,15 @@ func NewNamedHandler(name string, i Interface) NamedHandler {
} }
const ( const (
stepValidating = "validating" stepValidate = "validate"
stepMutating = "mutating" stepAdmit = "admit"
) )
// Admit performs an admission control check using a chain of handlers, and returns immediately on first error // Admit performs an admission control check using a chain of handlers, and returns immediately on first error
func (admissionHandler chainAdmissionHandler) Admit(a Attributes) error { func (admissionHandler chainAdmissionHandler) Admit(a Attributes) error {
start := time.Now() start := time.Now()
err := admissionHandler.admit(a) err := admissionHandler.admit(a)
Metrics.ObserveAdmissionStep(time.Since(start), err != nil, a, stepMutating) Metrics.ObserveAdmissionStep(time.Since(start), err != nil, a, stepAdmit)
return err return err
} }
@ -55,7 +55,7 @@ func (admissionHandler chainAdmissionHandler) admit(a Attributes) error {
if mutator, ok := handler.Interface().(MutationInterface); ok { if mutator, ok := handler.Interface().(MutationInterface); ok {
t := time.Now() t := time.Now()
err := mutator.Admit(a) err := mutator.Admit(a)
Metrics.ObserveAdmissionController(time.Since(t), err != nil, handler, a, stepMutating) Metrics.ObserveAdmissionController(time.Since(t), err != nil, handler, a, stepAdmit)
if err != nil { if err != nil {
return err return err
} }
@ -68,7 +68,7 @@ func (admissionHandler chainAdmissionHandler) admit(a Attributes) error {
func (admissionHandler chainAdmissionHandler) Validate(a Attributes) error { func (admissionHandler chainAdmissionHandler) Validate(a Attributes) error {
start := time.Now() start := time.Now()
err := admissionHandler.validate(a) err := admissionHandler.validate(a)
Metrics.ObserveAdmissionStep(time.Since(start), err != nil, a, stepValidating) Metrics.ObserveAdmissionStep(time.Since(start), err != nil, a, stepValidate)
return err return err
} }
@ -80,7 +80,7 @@ func (admissionHandler chainAdmissionHandler) validate(a Attributes) (err error)
if validator, ok := handler.Interface().(ValidationInterface); ok { if validator, ok := handler.Interface().(ValidationInterface); ok {
t := time.Now() t := time.Now()
err := validator.Validate(a) err := validator.Validate(a)
Metrics.ObserveAdmissionController(time.Since(t), err != nil, handler, a, stepValidating) Metrics.ObserveAdmissionController(time.Since(t), err != nil, handler, a, stepValidate)
if err != nil { if err != nil {
return err return err
} }

View File

@ -103,12 +103,12 @@ func TestAdmitAndValidate(t *testing.T) {
t.Errorf("validate handler %s called during admit", h.Name()) t.Errorf("validate handler %s called during admit", h.Name())
} }
// reset value for validation test // reset value for validation test
fake.admitCalled = false fake.admitCalled = false
} }
labelFilter := map[string]string{ labelFilter := map[string]string{
"type": "mutating", "type": "admit",
} }
checkAdmitAndValidateMetrics(t, labelFilter, test.accept, test.calls) checkAdmitAndValidateMetrics(t, labelFilter, test.accept, test.calls)
@ -134,7 +134,7 @@ func TestAdmitAndValidate(t *testing.T) {
} }
labelFilter = map[string]string{ labelFilter = map[string]string{
"type": "validating", "type": "validate",
} }
checkAdmitAndValidateMetrics(t, labelFilter, test.accept, test.calls) checkAdmitAndValidateMetrics(t, labelFilter, test.accept, test.calls)
@ -154,22 +154,22 @@ func checkAdmitAndValidateMetrics(t *testing.T, labelFilter map[string]string, a
if accept { if accept {
// Ensure exactly one admission end-to-end admission accept should have been recorded. // Ensure exactly one admission end-to-end admission accept should have been recorded.
expectHistogramCountTotal(t, "apiserver_admission_step_latencies", acceptFilter, 1) expectHistogramCountTotal(t, "apiserver_admission_step_admission_latencies_seconds", acceptFilter, 1)
// Ensure the expected count of admission controllers have been executed. // Ensure the expected count of admission controllers have been executed.
expectHistogramCountTotal(t, "apiserver_admission_controller_latencies", acceptFilter, len(calls)) expectHistogramCountTotal(t, "apiserver_admission_controller_admission_latencies_seconds", acceptFilter, len(calls))
} else { } else {
// When not accepted, ensure exactly one end-to-end rejection has been recorded. // When not accepted, ensure exactly one end-to-end rejection has been recorded.
expectHistogramCountTotal(t, "apiserver_admission_step_latencies", rejectFilter, 1) expectHistogramCountTotal(t, "apiserver_admission_step_admission_latencies_seconds", rejectFilter, 1)
if len(calls) > 0 { if len(calls) > 0 {
if len(calls) > 1 { if len(calls) > 1 {
// When not accepted, ensure that all but the last controller had been accepted, since // When not accepted, ensure that all but the last controller had been accepted, since
// the chain stops execution at the first rejection. // the chain stops execution at the first rejection.
expectHistogramCountTotal(t, "apiserver_admission_controller_latencies", acceptFilter, len(calls)-1) expectHistogramCountTotal(t, "apiserver_admission_controller_admission_latencies_seconds", acceptFilter, len(calls)-1)
} }
// When not accepted, ensure exactly one controller has been rejected. // When not accepted, ensure exactly one controller has been rejected.
expectHistogramCountTotal(t, "apiserver_admission_controller_latencies", rejectFilter, 1) expectHistogramCountTotal(t, "apiserver_admission_controller_admission_latencies_seconds", rejectFilter, 1)
} }
} }
} }

View File

@ -47,9 +47,9 @@ type NamedHandler interface {
// AdmissionMetrics instruments admission with prometheus metrics. // AdmissionMetrics instruments admission with prometheus metrics.
type AdmissionMetrics struct { type AdmissionMetrics struct {
step *metricSet step *metricSet
controller *metricSet controller *metricSet
externalWebhook *metricSet webhook *metricSet
} }
// newAdmissionMetrics create a new AdmissionMetrics, configured with default metric names. // newAdmissionMetrics create a new AdmissionMetrics, configured with default metric names.
@ -58,28 +58,28 @@ func newAdmissionMetrics() *AdmissionMetrics {
// Each step is identified by a distinct type label value. // Each step is identified by a distinct type label value.
step := newMetricSet("step", step := newMetricSet("step",
[]string{"type", "operation", "group", "version", "resource", "subresource", "rejected"}, []string{"type", "operation", "group", "version", "resource", "subresource", "rejected"},
"Admission sub-step %s, broken out for each operation and API resource and step type (validating or mutating).") "Admission sub-step %s, broken out for each operation and API resource and step type (validate or admit).")
// Built-in admission controller metrics. Each admission controller is identified by name. // Built-in admission controller metrics. Each admission controller is identified by name.
controller := newMetricSet("controller", controller := newMetricSet("controller",
[]string{"name", "type", "operation", "group", "version", "resource", "subresource", "rejected"}, []string{"name", "type", "operation", "group", "version", "resource", "subresource", "rejected"},
"Admission controller %s, identified by name and broken out for each operation and API resource and type (validating or mutating).") "Admission controller %s, identified by name and broken out for each operation and API resource and type (validate or admit).")
// External admission webhook metrics. Each webhook is identified by name. // Admission webhook metrics. Each webhook is identified by name.
externalWebhook := newMetricSet("external_webhook", webhook := newMetricSet("webhook",
[]string{"name", "type", "operation", "group", "version", "resource", "subresource", "rejected"}, []string{"name", "type", "operation", "group", "version", "resource", "subresource", "rejected"},
"External admission webhook %s, identified by name and broken out for each operation and API resource and type (validating or mutating).") "Admission webhook %s, identified by name and broken out for each operation and API resource and type (validate or admit).")
step.mustRegister() step.mustRegister()
controller.mustRegister() controller.mustRegister()
externalWebhook.mustRegister() webhook.mustRegister()
return &AdmissionMetrics{step: step, controller: controller, externalWebhook: externalWebhook} return &AdmissionMetrics{step: step, controller: controller, webhook: webhook}
} }
func (m *AdmissionMetrics) reset() { func (m *AdmissionMetrics) reset() {
m.step.reset() m.step.reset()
m.controller.reset() m.controller.reset()
m.externalWebhook.reset() m.webhook.reset()
} }
// ObserveAdmissionStep records admission related metrics for a admission step, identified by step type. // ObserveAdmissionStep records admission related metrics for a admission step, identified by step type.
@ -94,11 +94,11 @@ func (m *AdmissionMetrics) ObserveAdmissionController(elapsed time.Duration, rej
m.controller.observe(elapsed, handler.Name(), stepType, string(attr.GetOperation()), gvr.Group, gvr.Version, gvr.Resource, attr.GetSubresource(), strconv.FormatBool(rejected)) m.controller.observe(elapsed, handler.Name(), stepType, string(attr.GetOperation()), gvr.Group, gvr.Version, gvr.Resource, attr.GetSubresource(), strconv.FormatBool(rejected))
} }
// ObserveExternalWebhook records admission related metrics for a external admission webhook. // ObserveWebhook records admission related metrics for a admission webhook.
func (m *AdmissionMetrics) ObserveExternalWebhook(elapsed time.Duration, rejected bool, hook *v1alpha1.Webhook, attr Attributes) { func (m *AdmissionMetrics) ObserveWebhook(elapsed time.Duration, rejected bool, hook *v1alpha1.Webhook, attr Attributes) {
t := "validating" // TODO: pass in type (validating|mutating) once mutating webhook functionality has been implemented t := "admit" // TODO: pass in type (validate|admit) once mutating webhook functionality has been implemented
gvr := attr.GetResource() gvr := attr.GetResource()
m.externalWebhook.observe(elapsed, hook.Name, t, string(attr.GetOperation()), gvr.Group, gvr.Version, gvr.Resource, attr.GetSubresource(), strconv.FormatBool(rejected)) m.webhook.observe(elapsed, hook.Name, t, string(attr.GetOperation()), gvr.Group, gvr.Version, gvr.Resource, attr.GetSubresource(), strconv.FormatBool(rejected))
} }
type metricSet struct { type metricSet struct {
@ -112,7 +112,7 @@ func newMetricSet(name string, labels []string, helpTemplate string) *metricSet
prometheus.HistogramOpts{ prometheus.HistogramOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: subsystem, Subsystem: subsystem,
Name: fmt.Sprintf("%s_latencies", name), Name: fmt.Sprintf("%s_admission_latencies_seconds", name),
Help: fmt.Sprintf(helpTemplate, "latency histogram"), Help: fmt.Sprintf(helpTemplate, "latency histogram"),
Buckets: latencyBuckets, Buckets: latencyBuckets,
}, },
@ -122,7 +122,7 @@ func newMetricSet(name string, labels []string, helpTemplate string) *metricSet
prometheus.SummaryOpts{ prometheus.SummaryOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: subsystem, Subsystem: subsystem,
Name: fmt.Sprintf("%s_latencies_summary", name), Name: fmt.Sprintf("%s_admission_latencies_seconds_summary", name),
Help: fmt.Sprintf(helpTemplate, "latency summary"), Help: fmt.Sprintf(helpTemplate, "latency summary"),
MaxAge: latencySummaryMaxAge, MaxAge: latencySummaryMaxAge,
}, },

View File

@ -33,24 +33,24 @@ var (
func TestObserveAdmissionStep(t *testing.T) { func TestObserveAdmissionStep(t *testing.T) {
Metrics.reset() Metrics.reset()
Metrics.ObserveAdmissionStep(2*time.Second, false, attr, "mutating") Metrics.ObserveAdmissionStep(2*time.Second, false, attr, "admit")
wantLabels := map[string]string{ wantLabels := map[string]string{
"operation": string(Create), "operation": string(Create),
"group": resource.Group, "group": resource.Group,
"version": resource.Version, "version": resource.Version,
"resource": resource.Resource, "resource": resource.Resource,
"subresource": "subresource", "subresource": "subresource",
"type": "mutating", "type": "admit",
"rejected": "false", "rejected": "false",
} }
expectHistogramCountTotal(t, "apiserver_admission_step_latencies", wantLabels, 1) expectHistogramCountTotal(t, "apiserver_admission_step_admission_latencies_seconds", wantLabels, 1)
expectFindMetric(t, "apiserver_admission_step_latencies_summary", wantLabels) expectFindMetric(t, "apiserver_admission_step_admission_latencies_seconds_summary", wantLabels)
} }
func TestObserveAdmissionController(t *testing.T) { func TestObserveAdmissionController(t *testing.T) {
Metrics.reset() Metrics.reset()
handler := makeValidatingNamedHandler("a", true, Create) handler := makeValidatingNamedHandler("a", true, Create)
Metrics.ObserveAdmissionController(2*time.Second, false, handler, attr, "validating") Metrics.ObserveAdmissionController(2*time.Second, false, handler, attr, "validate")
wantLabels := map[string]string{ wantLabels := map[string]string{
"name": "a", "name": "a",
"operation": string(Create), "operation": string(Create),
@ -58,17 +58,17 @@ func TestObserveAdmissionController(t *testing.T) {
"version": resource.Version, "version": resource.Version,
"resource": resource.Resource, "resource": resource.Resource,
"subresource": "subresource", "subresource": "subresource",
"type": "validating", "type": "validate",
"rejected": "false", "rejected": "false",
} }
expectHistogramCountTotal(t, "apiserver_admission_controller_latencies", wantLabels, 1) expectHistogramCountTotal(t, "apiserver_admission_controller_admission_latencies_seconds", wantLabels, 1)
expectFindMetric(t, "apiserver_admission_controller_latencies_summary", wantLabels) expectFindMetric(t, "apiserver_admission_controller_admission_latencies_seconds_summary", wantLabels)
} }
func TestObserveExternalWebhook(t *testing.T) { func TestObserveWebhook(t *testing.T) {
Metrics.reset() Metrics.reset()
hook := &v1alpha1.Webhook{Name: "x"} hook := &v1alpha1.Webhook{Name: "x"}
Metrics.ObserveExternalWebhook(2*time.Second, false, hook, attr) Metrics.ObserveWebhook(2*time.Second, false, hook, attr)
wantLabels := map[string]string{ wantLabels := map[string]string{
"name": "x", "name": "x",
"operation": string(Create), "operation": string(Create),
@ -76,9 +76,9 @@ func TestObserveExternalWebhook(t *testing.T) {
"version": resource.Version, "version": resource.Version,
"resource": resource.Resource, "resource": resource.Resource,
"subresource": "subresource", "subresource": "subresource",
"type": "validating", "type": "admit",
"rejected": "false", "rejected": "false",
} }
expectHistogramCountTotal(t, "apiserver_admission_external_webhook_latencies", wantLabels, 1) expectHistogramCountTotal(t, "apiserver_admission_webhook_admission_latencies_seconds", wantLabels, 1)
expectFindMetric(t, "apiserver_admission_external_webhook_latencies_summary", wantLabels) expectFindMetric(t, "apiserver_admission_webhook_admission_latencies_seconds_summary", wantLabels)
} }

View File

@ -309,7 +309,7 @@ func (a *GenericAdmissionWebhook) Admit(attr admission.Attributes) error {
t := time.Now() t := time.Now()
err := a.callHook(ctx, hook, versionedAttr) err := a.callHook(ctx, hook, versionedAttr)
admission.Metrics.ObserveExternalWebhook(time.Since(t), err != nil, hook, attr) admission.Metrics.ObserveWebhook(time.Since(t), err != nil, hook, attr)
if err == nil { if err == nil {
return return
} }