From 9e4448b73ee97b4858dbb360eb06f57528395e81 Mon Sep 17 00:00:00 2001 From: Ruben Vargas Date: Wed, 15 May 2024 19:39:12 -0600 Subject: [PATCH] Refactor CR metrics Signed-off-by: Ruben Vargas --- apis/v1beta1/collector_webhook.go | 30 ++-- apis/v1beta1/metrics.go | 137 ++++++++++-------- config/manager/kustomization.yaml | 6 - controllers/suite_test.go | 2 +- .../podmutation/webhookhandler_suite_test.go | 2 +- main.go | 22 ++- pkg/collector/upgrade/suite_test.go | 2 +- 7 files changed, 104 insertions(+), 97 deletions(-) diff --git a/apis/v1beta1/collector_webhook.go b/apis/v1beta1/collector_webhook.go index a75db82227..ccecd95f51 100644 --- a/apis/v1beta1/collector_webhook.go +++ b/apis/v1beta1/collector_webhook.go @@ -76,6 +76,7 @@ type CollectorWebhook struct { cfg config.Config scheme *runtime.Scheme reviewer *rbac.Reviewer + metrics *Metrics } func (c CollectorWebhook) Default(_ context.Context, obj runtime.Object) error { @@ -171,10 +172,8 @@ func (c CollectorWebhook) ValidateCreate(ctx context.Context, obj runtime.Object if err != nil { return warnings, err } - - err = IncCounters(ctx, otelcol) - if err != nil { - return warnings, err + if c.metrics != nil { + c.metrics.incCounters(ctx, otelcol) } return warnings, nil @@ -196,17 +195,13 @@ func (c CollectorWebhook) ValidateUpdate(ctx context.Context, oldObj, newObj run return warnings, err } - // Decrease all metrics related to old CR - err = DecCounters(ctx, otelcolOld) - if err != nil { - return warnings, err + if c.metrics != nil { + // Decrease all metrics related to old CR + c.metrics.decCounters(ctx, otelcolOld) + // Increase all metrics related to new CR + c.metrics.incCounters(ctx, otelcol) } - // Increase all metrics related to new CR - err = IncCounters(ctx, otelcolOld) - if err != nil { - return warnings, err - } return warnings, nil } @@ -220,9 +215,9 @@ func (c CollectorWebhook) ValidateDelete(ctx context.Context, obj runtime.Object if err != nil { return warnings, err } - err = DecCounters(ctx, otelcol) - if err != nil { - return warnings, err + + if c.metrics != nil { + c.metrics.decCounters(ctx, otelcol) } return warnings, nil @@ -462,12 +457,13 @@ func checkAutoscalerSpec(autoscaler *AutoscalerSpec) error { return nil } -func SetupCollectorWebhook(mgr ctrl.Manager, cfg config.Config, reviewer *rbac.Reviewer) error { +func SetupCollectorWebhook(mgr ctrl.Manager, cfg config.Config, reviewer *rbac.Reviewer, metrics *Metrics) error { cvw := &CollectorWebhook{ reviewer: reviewer, logger: mgr.GetLogger().WithValues("handler", "CollectorWebhook", "version", "v1beta1"), scheme: mgr.GetScheme(), cfg: cfg, + metrics: metrics, } return ctrl.NewWebhookManagedBy(mgr). For(&OpenTelemetryCollector{}). diff --git a/apis/v1beta1/metrics.go b/apis/v1beta1/metrics.go index e6e5b72b74..d648e6d8e6 100644 --- a/apis/v1beta1/metrics.go +++ b/apis/v1beta1/metrics.go @@ -48,9 +48,16 @@ type components struct { extensions []string } +type Metrics struct { + modeCounter metric.Int64UpDownCounter + receiversCounter metric.Int64UpDownCounter + exporterCounter metric.Int64UpDownCounter + processorCounter metric.Int64UpDownCounter + extensionsCounter metric.Int64UpDownCounter +} + // BootstrapMetrics configures the OpenTelemetry meter provider with the Prometheus exporter. func BootstrapMetrics() error { - exporter, err := prometheus.New(prometheus.WithRegisterer(metrics.Registry)) if err != nil { return err @@ -60,6 +67,72 @@ func BootstrapMetrics() error { return err } +func NewMetrics() (*Metrics, error) { + meter := otel.Meter(meterName) + modeCounter, err := meter.Int64UpDownCounter(mode) + if err != nil { + return nil, err + } + receiversCounter, err := meter.Int64UpDownCounter(receivers) + if err != nil { + return nil, err + } + + exporterCounter, err := meter.Int64UpDownCounter(exporters) + if err != nil { + return nil, err + } + + processorCounter, err := meter.Int64UpDownCounter(processors) + if err != nil { + return nil, err + } + + extensionsCounter, err := meter.Int64UpDownCounter(extensions) + if err != nil { + return nil, err + } + + return &Metrics{ + modeCounter: modeCounter, + receiversCounter: receiversCounter, + exporterCounter: exporterCounter, + processorCounter: processorCounter, + extensionsCounter: extensionsCounter, + }, nil + +} + +func (m *Metrics) incCounters(ctx context.Context, collector *OpenTelemetryCollector) { + m.updateComponentCounters(ctx, collector, true) + m.updateGeneralCRMetricsComponents(ctx, collector, true) +} + +func (m *Metrics) decCounters(ctx context.Context, collector *OpenTelemetryCollector) { + m.updateComponentCounters(ctx, collector, false) + m.updateGeneralCRMetricsComponents(ctx, collector, false) +} + +func (m *Metrics) updateGeneralCRMetricsComponents(ctx context.Context, collector *OpenTelemetryCollector, up bool) { + + inc := 1 + if !up { + inc = -1 + } + m.modeCounter.Add(ctx, int64(inc), metric.WithAttributes( + attribute.Key("collector_name").String(collector.Name), + attribute.Key("namespace").String(collector.Namespace), + attribute.Key("type").String(string(collector.Spec.Mode)), + )) +} +func (m *Metrics) updateComponentCounters(ctx context.Context, collector *OpenTelemetryCollector, up bool) { + components := getComponentsFromConfigV1Beta1(collector.Spec.Config) + moveCounter(ctx, collector, components.receivers, m.receiversCounter, up) + moveCounter(ctx, collector, components.exporters, m.exporterCounter, up) + moveCounter(ctx, collector, components.processors, m.processorCounter, up) + moveCounter(ctx, collector, components.extensions, m.extensionsCounter, up) +} + func extractElements(elements map[string]interface{}) []string { if elements == nil { return []string{} @@ -94,68 +167,6 @@ func getComponentsFromConfigV1Beta1(yamlContent Config) *components { return info } -func IncCounters(ctx context.Context, collector *OpenTelemetryCollector) error { - if err := updateComponentCounters(ctx, collector, true); err != nil { - return err - } - return updateGeneralCRMetricsComponents(ctx, collector, true) -} - -func DecCounters(ctx context.Context, collector *OpenTelemetryCollector) error { - if err := updateComponentCounters(ctx, collector, false); err != nil { - return err - } - return updateGeneralCRMetricsComponents(ctx, collector, false) -} - -func updateGeneralCRMetricsComponents(ctx context.Context, collector *OpenTelemetryCollector, up bool) error { - meter := otel.Meter(meterName) - modeCounter, err := meter.Int64UpDownCounter(mode) - if err != nil { - return err - } - inc := 1 - if !up { - inc = -1 - } - modeCounter.Add(ctx, int64(inc), metric.WithAttributes( - attribute.Key("collector_name").String(collector.Name), - attribute.Key("namespace").String(collector.Namespace), - attribute.Key("type").String(string(collector.Spec.Mode)), - )) - return nil -} -func updateComponentCounters(ctx context.Context, collector *OpenTelemetryCollector, up bool) error { - meter := otel.Meter(meterName) - receiversCounter, err := meter.Int64UpDownCounter(receivers) - if err != nil { - return err - } - - exporterCounter, err := meter.Int64UpDownCounter(exporters) - if err != nil { - return err - } - - processorCounter, err := meter.Int64UpDownCounter(processors) - if err != nil { - return err - } - - extensionsCounter, err := meter.Int64UpDownCounter(extensions) - if err != nil { - return err - } - - components := getComponentsFromConfigV1Beta1(collector.Spec.Config) - moveCounter(ctx, collector, components.receivers, receiversCounter, up) - moveCounter(ctx, collector, components.exporters, exporterCounter, up) - moveCounter(ctx, collector, components.processors, processorCounter, up) - moveCounter(ctx, collector, components.extensions, extensionsCounter, up) - - return nil -} - func moveCounter( ctx context.Context, collector *OpenTelemetryCollector, types []string, upDown metric.Int64UpDownCounter, up bool) { for _, exporter := range types { diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 963273dd37..5c5f0b84cb 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -1,8 +1,2 @@ resources: - manager.yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -images: -- name: controller - newName: quay.io/rvargasp/opentelemetry-operator - newTag: 1714976402.0.0 diff --git a/controllers/suite_test.go b/controllers/suite_test.go index a9d82248e9..bf60d66c71 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -175,7 +175,7 @@ func TestMain(m *testing.M) { } reviewer := rbac.NewReviewer(clientset) - if err = v1beta1.SetupCollectorWebhook(mgr, config.New(), reviewer); err != nil { + if err = v1beta1.SetupCollectorWebhook(mgr, config.New(), reviewer, nil); err != nil { fmt.Printf("failed to SetupWebhookWithManager: %v", err) os.Exit(1) } diff --git a/internal/webhook/podmutation/webhookhandler_suite_test.go b/internal/webhook/podmutation/webhookhandler_suite_test.go index 464649f489..1336cab0e8 100644 --- a/internal/webhook/podmutation/webhookhandler_suite_test.go +++ b/internal/webhook/podmutation/webhookhandler_suite_test.go @@ -105,7 +105,7 @@ func TestMain(m *testing.M) { } reviewer := rbac.NewReviewer(clientset) - if err = v1beta1.SetupCollectorWebhook(mgr, config.New(), reviewer); err != nil { + if err = v1beta1.SetupCollectorWebhook(mgr, config.New(), reviewer, nil); err != nil { fmt.Printf("failed to SetupWebhookWithManager: %v", err) os.Exit(1) } diff --git a/main.go b/main.go index 7882e387c2..76ce9a57be 100644 --- a/main.go +++ b/main.go @@ -155,7 +155,7 @@ func main() { pflag.BoolVar(&enableNginxInstrumentation, constants.FlagNginx, false, "Controls whether the operator supports nginx auto-instrumentation") pflag.BoolVar(&enableNodeJSInstrumentation, constants.FlagNodeJS, true, "Controls whether the operator supports nodejs auto-instrumentation") pflag.BoolVar(&enableJavaInstrumentation, constants.FlagJava, true, "Controls whether the operator supports java auto-instrumentation") - pflag.BoolVar(&enableCRMetrics, constants.FlagCRMetrics, false, "Controls whether the CR metrics is enabled") + pflag.BoolVar(&enableCRMetrics, constants.FlagCRMetrics, true, "Controls whether the CR metrics is enabled") stringFlagOrEnv(&collectorImage, "collector-image", "RELATED_IMAGE_COLLECTOR", fmt.Sprintf("ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector:%s", v.OpenTelemetryCollector), "The default OpenTelemetry collector image. This image is used when no image is specified in the CustomResource.") stringFlagOrEnv(&targetAllocatorImage, "target-allocator-image", "RELATED_IMAGE_TARGET_ALLOCATOR", fmt.Sprintf("ghcr.io/open-telemetry/opentelemetry-operator/target-allocator:%s", v.TargetAllocator), "The default OpenTelemetry target allocator image. This image is used when no image is specified in the CustomResource.") @@ -337,12 +337,6 @@ func main() { } } - if enableCRMetrics { - if metricsErr := otelv1beta1.BootstrapMetrics(); metricsErr != nil { - setupLog.Error(metricsErr, "Error bootstrapping CRD metrics") - } - } - if cfg.LabelsFilter() != nil { for _, basePattern := range cfg.LabelsFilter() { _, compileErr := regexp.Compile(basePattern) @@ -381,7 +375,19 @@ func main() { } if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = otelv1beta1.SetupCollectorWebhook(mgr, cfg, reviewer); err != nil { + var crdMetrics *otelv1beta1.Metrics + + if enableCRMetrics { + if metricsErr := otelv1beta1.BootstrapMetrics(); metricsErr != nil { + setupLog.Error(metricsErr, "Error bootstrapping CRD metrics") + } + crdMetrics, err = otelv1beta1.NewMetrics() + if err != nil { + setupLog.Error(err, "Error bootstrapping CRD metrics") + } + } + + if err = otelv1beta1.SetupCollectorWebhook(mgr, cfg, reviewer, crdMetrics); err != nil { setupLog.Error(err, "unable to create webhook", "webhook", "OpenTelemetryCollector") os.Exit(1) } diff --git a/pkg/collector/upgrade/suite_test.go b/pkg/collector/upgrade/suite_test.go index e6e505b760..fdafdca245 100644 --- a/pkg/collector/upgrade/suite_test.go +++ b/pkg/collector/upgrade/suite_test.go @@ -105,7 +105,7 @@ func TestMain(m *testing.M) { } reviewer := rbac.NewReviewer(clientset) - if err = v1beta1.SetupCollectorWebhook(mgr, config.New(), reviewer); err != nil { + if err = v1beta1.SetupCollectorWebhook(mgr, config.New(), reviewer, nil); err != nil { fmt.Printf("failed to SetupWebhookWithManager: %v", err) os.Exit(1) }