From d7f2d630efdefdebee0d06035075f5b9d85ed15c Mon Sep 17 00:00:00 2001 From: Jakub Al-Khalili Date: Mon, 9 Sep 2019 14:52:21 +0200 Subject: [PATCH] Change metrics mechanism in cmd/manager/main.go --- Dockerfile | 3 +- cmd/manager/main.go | 61 +++++++++++++++++-- ...a59390ea2e0f21481eafe4022de05a44eba88fc.js | 5 ++ ...a62a1b7c40ef1a656c462c09a03c20d5cfbb057.js | 5 ++ go.sum | 2 + .../jenkins/v1alpha2/zz_generated.deepcopy.go | 2 +- 6 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 docs/js/main.min.15ba3b50c3bd013e1b26793d1a59390ea2e0f21481eafe4022de05a44eba88fc.js create mode 100644 docs/js/main.min.e5ae77169eed324fae314e8a3a62a1b7c40ef1a656c462c09a03c20d5cfbb057.js diff --git a/Dockerfile b/Dockerfile index 79c1371e..10012e45 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,7 +21,8 @@ RUN apk update && \ make \ gcc \ libc-dev \ - git + git \ + mercurial RUN curl -O https://storage.googleapis.com/golang/go$GO_VERSION.linux-amd64.tar.gz && tar -xvf go$GO_VERSION.linux-amd64.tar.gz diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 8b40b54e..8e2ff19c 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -4,6 +4,10 @@ import ( "context" "flag" "fmt" + kubemetrics "github.com/operator-framework/operator-sdk/pkg/kube-metrics" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/rest" "os" "runtime" @@ -34,8 +38,9 @@ import ( // Change below variables to serve metrics on different host or port. var ( - metricsHost = "0.0.0.0" - metricsPort int32 = 8383 + metricsHost = "0.0.0.0" + metricsPort int32 = 8383 + operatorMetricsPort int32 = 8686 ) //var log = logf.Log.WithName("cmd") @@ -118,10 +123,32 @@ func main() { fatal(errors.Wrap(err, "failed to setup controllers"), *debug) } - // Create Service object to expose the metrics port. - _, err = metrics.ExposeMetricsPort(ctx, metricsPort) + if err = serveCRMetrics(cfg); err != nil { + log.Log.Info("Could not generate and serve custom resource metrics", "error", err.Error()) + } + + // Add to the below struct any other metrics ports you want to expose. + servicePorts := []v1.ServicePort{ + {Port: metricsPort, Name: metrics.OperatorPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: metricsPort}}, + {Port: operatorMetricsPort, Name: metrics.CRPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: operatorMetricsPort}}, + } + // Create Service object to expose the metrics port(s). + service, err := metrics.CreateMetricsService(ctx, cfg, servicePorts) if err != nil { - log.Log.Info(err.Error()) + log.Log.Info("Could not create metrics Service", "error", err.Error()) + } + + // CreateServiceMonitors will automatically create the prometheus-operator ServiceMonitor resources + // necessary to configure Prometheus to scrape metrics from this operator. + services := []*v1.Service{service} + _, err = metrics.CreateServiceMonitors(cfg, namespace, services) + if err != nil { + log.Log.Info("Could not create ServiceMonitor object", "error", err.Error()) + // If this operator is deployed to a cluster without the prometheus-operator running, it will return + // ErrServiceMonitorNotPresent, which can be used to safely skip ServiceMonitor creation. + if err == metrics.ErrServiceMonitorNotPresent { + log.Log.Info("Install prometheus-operator in your cluster to create ServiceMonitor objects", "error", err.Error()) + } } log.Log.Info("Starting the Cmd.") @@ -132,6 +159,30 @@ func main() { } } +// serveCRMetrics gets the Operator/CustomResource GVKs and generates metrics based on those types. +// It serves those metrics on "http://metricsHost:operatorMetricsPort". +func serveCRMetrics(cfg *rest.Config) error { + // Below function returns filtered operator/CustomResource specific GVKs. + // For more control override the below GVK list with your own custom logic. + filteredGVK, err := k8sutil.GetGVKsFromAddToScheme(apis.AddToScheme) + if err != nil { + return err + } + // Get the namespace the operator is currently deployed in. + operatorNs, err := k8sutil.GetOperatorNamespace() + if err != nil { + return err + } + // To generate metrics in other namespaces, add the values below. + ns := []string{operatorNs} + // Generate and serve custom resource specific metrics. + err = kubemetrics.GenerateAndServeCRMetrics(cfg, ns, filteredGVK, metricsHost, operatorMetricsPort) + if err != nil { + return err + } + return nil +} + func fatal(err error, debug bool) { if debug { log.Log.Error(nil, fmt.Sprintf("%+v", err)) diff --git a/docs/js/main.min.15ba3b50c3bd013e1b26793d1a59390ea2e0f21481eafe4022de05a44eba88fc.js b/docs/js/main.min.15ba3b50c3bd013e1b26793d1a59390ea2e0f21481eafe4022de05a44eba88fc.js new file mode 100644 index 00000000..947f3f26 --- /dev/null +++ b/docs/js/main.min.15ba3b50c3bd013e1b26793d1a59390ea2e0f21481eafe4022de05a44eba88fc.js @@ -0,0 +1,5 @@ +(function($){'use strict';$(function(){$('[data-toggle="tooltip"]').tooltip();$('[data-toggle="popover"]').popover();$('.popover-dismiss').popover({trigger:'focus'})});function bottomPos(element){return element.offset().top+element.outerHeight();} +$(function(){var promo=$(".js-td-cover");if(!promo.length){return} +var promoOffset=bottomPos(promo);var navbarOffset=$('.js-navbar-scroll').offset().top;var threshold=Math.ceil($('.js-navbar-scroll').outerHeight());if((promoOffset-navbarOffset)