From 1545cbf0e52c8412458d2603026ca8634e786d93 Mon Sep 17 00:00:00 2001 From: Gerrit Date: Thu, 11 Jul 2024 11:32:26 +0200 Subject: [PATCH 1/3] Provide custom metrics. --- main.go | 10 +++++--- metrics.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 metrics.go diff --git a/main.go b/main.go index 2c6bad6..c589bcb 100644 --- a/main.go +++ b/main.go @@ -21,7 +21,7 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" - controllerclient "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" @@ -40,12 +40,12 @@ const ( metalAuthHMACEnvVar = "METAL_AUTH_HMAC" ) -func healthCheckFunc(log *slog.Logger, seedClient controllerclient.Client, namespace string) func(req *http.Request) error { +func healthCheckFunc(log *slog.Logger, seedClient client.Client, namespace string) func(req *http.Request) error { return func(req *http.Request) error { log.Debug("health check called") fws := &v2.FirewallList{} - err := seedClient.List(req.Context(), fws, controllerclient.InNamespace(namespace)) + err := seedClient.List(req.Context(), fws, client.InNamespace(namespace)) if err != nil { return fmt.Errorf("unable to list firewalls in namespace %s", namespace) } @@ -150,7 +150,7 @@ func main() { // cannot use seedMgr.GetClient() because it gets initialized at a later point in time // we have to create an own client - seedClient, err := controllerclient.New(seedMgr.GetConfig(), controllerclient.Options{ + seedClient, err := client.New(seedMgr.GetConfig(), client.Options{ Scheme: scheme, }) if err != nil { @@ -164,6 +164,8 @@ func main() { log.Fatalf("unable to set up ready check %v", err) } + mustRegisterCustomMetrics(l.WithGroup("metrics"), seedClient) + var ( externalShootAccess = &v2.ShootAccess{ GenericKubeconfigSecretName: shootKubeconfigSecret, diff --git a/metrics.go b/metrics.go new file mode 100644 index 0000000..aacca4f --- /dev/null +++ b/metrics.go @@ -0,0 +1,74 @@ +package main + +import ( + "context" + "log/slog" + "time" + + v2 "github.com/metal-stack/firewall-controller-manager/api/v2" + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var ( + firewallDeploymentReadyReplicasDesc = prometheus.NewDesc( + "firewall_deployment_ready_replicas", + "provide information on firewall deployment ready replicas", + []string{"name", "namespace"}, + nil, + ) + firewallDeploymentTargetReplicasDesc = prometheus.NewDesc( + "firewall_deployment_target_replicas", + "provide information on firewall deployment target replicas", + []string{"name", "namespace"}, + nil, + ) +) + +type collector struct { + log *slog.Logger + seedClient client.Client + namespace string +} + +func mustRegisterCustomMetrics(log *slog.Logger, seedClient client.Client) { + c := &collector{ + log: log, + seedClient: seedClient, + } + + metrics.Registry.MustRegister(c) +} + +func (c *collector) Describe(ch chan<- *prometheus.Desc) { + ch <- firewallDeploymentReadyReplicasDesc + ch <- firewallDeploymentTargetReplicasDesc +} + +func (c *collector) Collect(ch chan<- prometheus.Metric) { + c.log.Info("collecting custom metrics") + + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + deploys := &v2.FirewallDeploymentList{} + err := c.seedClient.List(ctx, deploys, client.InNamespace(c.namespace)) + if err != nil { + c.log.Error("unable to list firewall deployments", "error", err) + return + } + + for _, deploy := range deploys.Items { + ch <- prometheus.MustNewConstMetric(firewallDeploymentReadyReplicasDesc, prometheus.GaugeValue, + float64(deploy.Status.ReadyReplicas), + deploy.Name, + deploy.Namespace, + ) + ch <- prometheus.MustNewConstMetric(firewallDeploymentTargetReplicasDesc, prometheus.GaugeValue, + float64(deploy.Status.TargetReplicas), + deploy.Name, + deploy.Namespace, + ) + } +} From 2f836a53602492a257dd36c59e6166260dd3a9ad Mon Sep 17 00:00:00 2001 From: Gerrit Date: Thu, 11 Jul 2024 11:34:05 +0200 Subject: [PATCH 2/3] Update. --- main.go | 2 +- metrics.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index c589bcb..1a2337c 100644 --- a/main.go +++ b/main.go @@ -164,7 +164,7 @@ func main() { log.Fatalf("unable to set up ready check %v", err) } - mustRegisterCustomMetrics(l.WithGroup("metrics"), seedClient) + mustRegisterCustomMetrics(l.WithGroup("metrics"), seedClient, namespace) var ( externalShootAccess = &v2.ShootAccess{ diff --git a/metrics.go b/metrics.go index aacca4f..fdf9574 100644 --- a/metrics.go +++ b/metrics.go @@ -32,10 +32,11 @@ type collector struct { namespace string } -func mustRegisterCustomMetrics(log *slog.Logger, seedClient client.Client) { +func mustRegisterCustomMetrics(log *slog.Logger, seedClient client.Client, namespace string) { c := &collector{ log: log, seedClient: seedClient, + namespace: namespace, } metrics.Registry.MustRegister(c) From 0fdf88a5cf3b67f121b19f41d8c4f24e4e2363da Mon Sep 17 00:00:00 2001 From: Gerrit Date: Thu, 11 Jul 2024 11:41:29 +0200 Subject: [PATCH 3/3] Fix. --- Makefile | 2 +- health.go | 23 +++++++++++++++++++++++ main.go | 14 -------------- 3 files changed, 24 insertions(+), 15 deletions(-) create mode 100644 health.go diff --git a/Makefile b/Makefile index 94982c1..3863ccb 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ manager: generate fmt vet -X 'github.com/metal-stack/v.Revision=$(GITVERSION)' \ -X 'github.com/metal-stack/v.GitSHA1=$(SHA)' \ -X 'github.com/metal-stack/v.BuildDate=$(BUILDDATE)'" \ - -o bin/firewall-controller-manager main.go + -o bin/firewall-controller-manager . strip bin/firewall-controller-manager # Run against the mini-lab diff --git a/health.go b/health.go new file mode 100644 index 0000000..1f0ba4b --- /dev/null +++ b/health.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "log/slog" + "net/http" + + v2 "github.com/metal-stack/firewall-controller-manager/api/v2" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func healthCheckFunc(log *slog.Logger, seedClient client.Client, namespace string) func(req *http.Request) error { + return func(req *http.Request) error { + log.Debug("health check called") + + fws := &v2.FirewallList{} + err := seedClient.List(req.Context(), fws, client.InNamespace(namespace)) + if err != nil { + return fmt.Errorf("unable to list firewalls in namespace %s", namespace) + } + return nil + } +} diff --git a/main.go b/main.go index 1a2337c..f1b9f67 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,6 @@ import ( "fmt" "log" "log/slog" - "net/http" "os" "time" @@ -40,19 +39,6 @@ const ( metalAuthHMACEnvVar = "METAL_AUTH_HMAC" ) -func healthCheckFunc(log *slog.Logger, seedClient client.Client, namespace string) func(req *http.Request) error { - return func(req *http.Request) error { - log.Debug("health check called") - - fws := &v2.FirewallList{} - err := seedClient.List(req.Context(), fws, client.InNamespace(namespace)) - if err != nil { - return fmt.Errorf("unable to list firewalls in namespace %s", namespace) - } - return nil - } -} - func main() { var ( scheme = helper.MustNewFirewallScheme()