mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
add metrics for rootcacertpublisher controller
This commit is contained in:
parent
c0841211fd
commit
bbce0468d4
@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["publisher.go"],
|
||||
srcs = [
|
||||
"metrics.go",
|
||||
"publisher.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/controller/certificates/rootcacertpublisher",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
@ -16,6 +19,8 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/workqueue:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics/prometheus/ratelimiter:go_default_library",
|
||||
"//vendor/k8s.io/klog/v2:go_default_library",
|
||||
],
|
||||
@ -23,15 +28,21 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["publisher_test.go"],
|
||||
srcs = [
|
||||
"metrics_test.go",
|
||||
"publisher_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/controller:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics/testutil:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
72
pkg/controller/certificates/rootcacertpublisher/metrics.go
Normal file
72
pkg/controller/certificates/rootcacertpublisher/metrics.go
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package rootcacertpublisher
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/component-base/metrics"
|
||||
"k8s.io/component-base/metrics/legacyregistry"
|
||||
)
|
||||
|
||||
// RootCACertPublisher - subsystem name used by root_ca_cert_publisher
|
||||
const RootCACertPublisher = "root_ca_cert_publisher"
|
||||
|
||||
var (
|
||||
syncCounter = metrics.NewCounterVec(
|
||||
&metrics.CounterOpts{
|
||||
Subsystem: RootCACertPublisher,
|
||||
Name: "sync_total",
|
||||
Help: "Number of namespace syncs happened in root ca cert publisher.",
|
||||
StabilityLevel: metrics.ALPHA,
|
||||
},
|
||||
[]string{"namespace", "code"},
|
||||
)
|
||||
syncLatency = metrics.NewHistogramVec(
|
||||
&metrics.HistogramOpts{
|
||||
Subsystem: RootCACertPublisher,
|
||||
Name: "sync_duration_seconds",
|
||||
Help: "Number of namespace syncs happened in root ca cert publisher.",
|
||||
Buckets: metrics.ExponentialBuckets(0.001, 2, 15),
|
||||
StabilityLevel: metrics.ALPHA,
|
||||
},
|
||||
[]string{"namespace", "code"},
|
||||
)
|
||||
)
|
||||
|
||||
func recordMetrics(start time.Time, ns string, err error) {
|
||||
code := "500"
|
||||
if err == nil {
|
||||
code = "200"
|
||||
} else if se, ok := err.(*apierrors.StatusError); ok && se.Status().Code != 0 {
|
||||
code = strconv.Itoa(int(se.Status().Code))
|
||||
}
|
||||
syncLatency.WithLabelValues(ns, code).Observe(time.Since(start).Seconds())
|
||||
syncCounter.WithLabelValues(ns, code).Inc()
|
||||
}
|
||||
|
||||
var once sync.Once
|
||||
|
||||
func registerMetrics() {
|
||||
once.Do(func() {
|
||||
legacyregistry.MustRegister(syncCounter)
|
||||
legacyregistry.MustRegister(syncLatency)
|
||||
})
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package rootcacertpublisher
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/component-base/metrics/legacyregistry"
|
||||
"k8s.io/component-base/metrics/testutil"
|
||||
)
|
||||
|
||||
func TestSyncCounter(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
err error
|
||||
metrics []string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
desc: "nil error",
|
||||
err: nil,
|
||||
metrics: []string{
|
||||
"root_ca_cert_publisher_sync_total",
|
||||
},
|
||||
want: `
|
||||
# HELP root_ca_cert_publisher_sync_total [ALPHA] Number of namespace syncs happened in root ca cert publisher.
|
||||
# TYPE root_ca_cert_publisher_sync_total counter
|
||||
root_ca_cert_publisher_sync_total{code="200",namespace="test-ns"} 1
|
||||
`,
|
||||
},
|
||||
{
|
||||
desc: "kube api error",
|
||||
err: apierrors.NewNotFound(corev1.Resource("configmap"), "test-configmap"),
|
||||
metrics: []string{
|
||||
"root_ca_cert_publisher_sync_total",
|
||||
},
|
||||
want: `
|
||||
# HELP root_ca_cert_publisher_sync_total [ALPHA] Number of namespace syncs happened in root ca cert publisher.
|
||||
# TYPE root_ca_cert_publisher_sync_total counter
|
||||
root_ca_cert_publisher_sync_total{code="404",namespace="test-ns"} 1
|
||||
`,
|
||||
},
|
||||
{
|
||||
desc: "kube api error without code",
|
||||
err: &apierrors.StatusError{},
|
||||
metrics: []string{
|
||||
"root_ca_cert_publisher_sync_total",
|
||||
},
|
||||
want: `
|
||||
# HELP root_ca_cert_publisher_sync_total [ALPHA] Number of namespace syncs happened in root ca cert publisher.
|
||||
# TYPE root_ca_cert_publisher_sync_total counter
|
||||
root_ca_cert_publisher_sync_total{code="500",namespace="test-ns"} 1
|
||||
`,
|
||||
},
|
||||
{
|
||||
desc: "general error",
|
||||
err: errors.New("test"),
|
||||
metrics: []string{
|
||||
"root_ca_cert_publisher_sync_total",
|
||||
},
|
||||
want: `
|
||||
# HELP root_ca_cert_publisher_sync_total [ALPHA] Number of namespace syncs happened in root ca cert publisher.
|
||||
# TYPE root_ca_cert_publisher_sync_total counter
|
||||
root_ca_cert_publisher_sync_total{code="500",namespace="test-ns"} 1
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
recordMetrics(time.Now(), "test-ns", tc.err)
|
||||
defer syncCounter.Reset()
|
||||
if err := testutil.GatherAndCompare(legacyregistry.DefaultGatherer, strings.NewReader(tc.want), tc.metrics...); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -40,6 +40,10 @@ import (
|
||||
// to access api-server
|
||||
const RootCACertConfigMapName = "kube-root-ca.crt"
|
||||
|
||||
func init() {
|
||||
registerMetrics()
|
||||
}
|
||||
|
||||
// NewPublisher construct a new controller which would manage the configmap
|
||||
// which stores certificates in each namespace. It will make sure certificate
|
||||
// configmap exists in each namespace.
|
||||
@ -170,16 +174,17 @@ func (c *Publisher) processNextWorkItem() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Publisher) syncNamespace(ns string) error {
|
||||
func (c *Publisher) syncNamespace(ns string) (err error) {
|
||||
startTime := time.Now()
|
||||
defer func() {
|
||||
recordMetrics(startTime, ns, err)
|
||||
klog.V(4).Infof("Finished syncing namespace %q (%v)", ns, time.Since(startTime))
|
||||
}()
|
||||
|
||||
cm, err := c.cmLister.ConfigMaps(ns).Get(RootCACertConfigMapName)
|
||||
switch {
|
||||
case apierrors.IsNotFound(err):
|
||||
_, err := c.client.CoreV1().ConfigMaps(ns).Create(context.TODO(), &v1.ConfigMap{
|
||||
_, err = c.client.CoreV1().ConfigMaps(ns).Create(context.TODO(), &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: RootCACertConfigMapName,
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user