From 7aa399750a99c7962cf763ab3f69867689006080 Mon Sep 17 00:00:00 2001 From: shengaoy Date: Mon, 4 Dec 2023 22:17:13 +0800 Subject: [PATCH] feat(config): add support for Metrics PerUnitHistogramBoundaries config. --- api/v1beta1/temporalcluster_types.go | 9 +++++++++ .../bases/temporal.io_temporalclusters.yaml | 7 +++++++ internal/resource/config/configmap_builder.go | 20 +++++++++++++++++++ webhooks/temporalcluster_webhook.go | 18 +++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/api/v1beta1/temporalcluster_types.go b/api/v1beta1/temporalcluster_types.go index 77789850..8eef5045 100644 --- a/api/v1beta1/temporalcluster_types.go +++ b/api/v1beta1/temporalcluster_types.go @@ -743,6 +743,15 @@ type PrometheusSpec struct { type MetricsSpec struct { // Enabled defines if the operator should enable metrics exposition on temporal components. Enabled bool `json:"enabled"` + // PerUnitHistogramBoundaries defines the default histogram bucket boundaries. + // Configuration of histogram boundaries for given metric unit. + // + // Supported values: + // - "dimensionless" + // - "milliseconds" + // - "bytes" + // +optional + PerUnitHistogramBoundaries map[string][]string `json:"perUnitHistogramBoundaries,omitempty"` // Prometheus reporter configuration. // +optional Prometheus *PrometheusSpec `json:"prometheus,omitempty"` diff --git a/config/crd/bases/temporal.io_temporalclusters.yaml b/config/crd/bases/temporal.io_temporalclusters.yaml index 4497fa94..cf3bb397 100644 --- a/config/crd/bases/temporal.io_temporalclusters.yaml +++ b/config/crd/bases/temporal.io_temporalclusters.yaml @@ -501,6 +501,13 @@ spec: enabled: description: Enabled defines if the operator should enable metrics exposition on temporal components. type: boolean + perUnitHistogramBoundaries: + additionalProperties: + items: + type: string + type: array + description: "PerUnitHistogramBoundaries defines the default histogram bucket boundaries. Configuration of histogram boundaries for given metric unit. \n Supported values: - \"dimensionless\" - \"milliseconds\" - \"bytes\"" + type: object prometheus: description: Prometheus reporter configuration. properties: diff --git a/internal/resource/config/configmap_builder.go b/internal/resource/config/configmap_builder.go index 5d66d739..90c33a66 100644 --- a/internal/resource/config/configmap_builder.go +++ b/internal/resource/config/configmap_builder.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "path" + "strconv" "time" "github.com/alexandrevilain/controller-tools/pkg/resource" @@ -314,6 +315,25 @@ func (b *ConfigmapBuilder) Update(object client.Object) error { Tags: map[string]string{"type": "{{ .Env.SERVICES }}"}, }, } + + if b.instance.Spec.Metrics.PerUnitHistogramBoundaries != nil { + buckets := make(map[string][]float64) + p := b.instance.Spec.Metrics.PerUnitHistogramBoundaries + // Convert map[string][]string to map[string][]float64 + for key, value := range p { + var floatSlice []float64 + for _, str := range value { + floatVal, err := strconv.ParseFloat(str, 64) + if err != nil { + return fmt.Errorf("can't build metrics config: Error converting %s to float: %w", str, err) + } + floatSlice = append(floatSlice, floatVal) + } + buckets[key] = floatSlice + } + temporalCfg.Global.Metrics.ClientConfig.PerUnitHistogramBoundaries = buckets + } + if b.instance.Spec.Metrics.Prometheus != nil && b.instance.Spec.Metrics.Prometheus.ListenPort != nil { temporalCfg.Global.Metrics.Prometheus = &metrics.PrometheusConfig{ TimerType: "histogram", diff --git a/webhooks/temporalcluster_webhook.go b/webhooks/temporalcluster_webhook.go index ba37c06c..abe2f20d 100644 --- a/webhooks/temporalcluster_webhook.go +++ b/webhooks/temporalcluster_webhook.go @@ -273,6 +273,24 @@ func (w *TemporalClusterWebhook) validateCluster(cluster *v1beta1.TemporalCluste } } + // Check for per unit histogram boundaries if metrics is enabled + if cluster.Spec.Metrics.IsEnabled() && cluster.Spec.Metrics.PerUnitHistogramBoundaries != nil { + p := cluster.Spec.Metrics.PerUnitHistogramBoundaries + for _, value := range p { + for _, str := range value { + _, err := strconv.ParseFloat(str, 64) + if err != nil { + errs = append(errs, + field.Forbidden( + field.NewPath("spec", "metrics", "perUnitHistogramBoundaries"), + fmt.Sprintf("can't parse this strings value to float64: %s ", str), + ), + ) + } + } + } + } + return warns, errs }