mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
Align admission metric names with prometheus guidelines
This commit is contained in:
parent
375e2d03ab
commit
369fd81ca1
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user