diff --git a/deploy/helm/nvca-operator/nvca-operator/values.yaml b/deploy/helm/nvca-operator/nvca-operator/values.yaml index 6ffe6c9d3..01ac2c49f 100644 --- a/deploy/helm/nvca-operator/nvca-operator/values.yaml +++ b/deploy/helm/nvca-operator/nvca-operator/values.yaml @@ -100,6 +100,21 @@ agentConfig: # mergeConfig: | # agent: # logLevel: debug + # + # BYOO metric subset example: + # + # mergeConfig: | + # agent: + # byooMetricSubset: + # enabled: true + # filterConfig: | + # error_mode: ignore + # metric_conditions: + # - 'metric.name != "BpsInstrument"' + # byooWorkloadMetrics: + # dropLabels: + # - metric_subset_enabled + # - custom_label ## @section resources Resource requests and limits for the nvca-operator container ## @param resources.limits.cpu CPU limit for the nvca-operator container ## @param resources.limits.memory Memory limit for the nvca-operator container diff --git a/docs/ngc-managed/cluster-management/configuration.md b/docs/ngc-managed/cluster-management/configuration.md index 01bbcfc10..8726b4ed5 100644 --- a/docs/ngc-managed/cluster-management/configuration.md +++ b/docs/ngc-managed/cluster-management/configuration.md @@ -733,6 +733,24 @@ pod and merged with the generated config at runtime. logLevel: debug ``` +BYOO metric subset example: + +```yaml + agentConfig: + mergeConfig: | + agent: + byooMetricSubset: + enabled: true + filterConfig: | + error_mode: ignore + metric_conditions: + - 'metric.name != "BpsInstrument"' + byooWorkloadMetrics: + dropLabels: + - metric_subset_enabled + - custom_label +``` + **Apply via Helm:** ```bash diff --git a/docs/user/cluster-management/configuration.md b/docs/user/cluster-management/configuration.md index 4e89780c0..84e439a79 100644 --- a/docs/user/cluster-management/configuration.md +++ b/docs/user/cluster-management/configuration.md @@ -854,6 +854,24 @@ isolated test clusters that run the LLM request router tunnel without TLS. For the full LLM addon setup, see [LLM Function Enablement](../llm-function-enablement.md). +BYOO metric subset example: + +```yaml +agentConfig: + mergeConfig: | + agent: + byooMetricSubset: + enabled: true + filterConfig: | + error_mode: ignore + metric_conditions: + - 'metric.name != "BpsInstrument"' + byooWorkloadMetrics: + dropLabels: + - metric_subset_enabled + - custom_label +``` + Apply via Helm: ```bash diff --git a/src/compute-plane-services/byoo-otel-collector/README.md b/src/compute-plane-services/byoo-otel-collector/README.md index bc76ee65d..aaa0760df 100644 --- a/src/compute-plane-services/byoo-otel-collector/README.md +++ b/src/compute-plane-services/byoo-otel-collector/README.md @@ -104,7 +104,7 @@ Exposed Ports: - 14358: OTLP HTTP receiver - 13133: `/health?verbose` endpoint to get detailed health status of collector (healthcheck v2 extension) - 19090: `/metrics` endpoint for the byoo-otel-collector metrics -- 19091: `/metrics` endpoint for optional SRE user metrics +- 19091: `/metrics` endpoint for optional metric subset user metrics ### nvcf-otel-collector Image @@ -129,9 +129,9 @@ Chunking is disabled by default. Configure it with: - `BYOO_LOG_CHUNK_MAX_BODY_BYTES`: maximum log body size in bytes before chunking. `0` disables the processor. Enabled values must be at least `4` bytes so chunks can preserve UTF-8 rune boundaries. Use `983040` bytes for normal BYOO deployments to leave room for log attributes and exporter envelope overhead under a `1000000` byte backend entry limit. - `BYOO_LOG_CHUNK_DRY_RUN`: records oversized-log metrics and warnings without mutating log payloads. Dry-run metric datapoints use `mode=dry_run`. - `BYOO_LOG_EXPORTER_BATCH_MAX_SIZE_BYTES`: serialized log export request batch size used for exporterhelper byte splitting. `0` or unset uses the default `1000000` bytes. -- `BYOO_SRE_METRICS_ENABLED`: enables an additional OTLP-only metrics pipeline that exposes filtered user metrics through a Prometheus exporter on port `19091`. Disabled by default. -- `BYOO_SRE_METRICS_FILTER_CONFIG`: optional YAML filter processor config for the SRE metrics pipeline. If unset, the default drops every metric except `BpsInstrument`, `FpsInstrument`, `RtdInstrument`, and `StageOpenDuration`, and drops datapoints/resources explicitly labeled `sre_metrics_enabled=false` or `sre_enabled_metrics=false`. -- `BYOO_CUSTOMER_METRICS_DROP_LABELS`: comma-separated resource attribute names removed from the customer metrics pipeline when SRE metrics are enabled. If unset, defaults to `sre_metrics_enabled,sre_enabled_metrics`. +- `BYOO_METRIC_SUBSET_ENABLED`: enables an additional OTLP-only metrics pipeline that exposes filtered user metrics through a Prometheus exporter on port `19091`. Disabled by default. +- `BYOO_METRIC_SUBSET_FILTER_CONFIG`: optional YAML filter processor config for the metric subset pipeline. If unset, the default drops every metric except `BpsInstrument`, `FpsInstrument`, `RtdInstrument`, and `StageOpenDuration`, and drops datapoints/resources explicitly labeled `metric_subset_enabled=false`. +- `BYOO_WORKLOAD_METRICS_DROP_LABELS`: comma-separated resource attribute names removed from the generated workload `metrics` pipeline. If unset, defaults to `metric_subset_enabled` only when the metric subset pipeline is enabled. When chunking is enabled, each emitted chunk preserves the original log metadata and adds these attributes so chunks can be grouped in the backend: diff --git a/src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_sre_metrics.yaml b/src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_metric_subset.yaml similarity index 93% rename from src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_sre_metrics.yaml rename to src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_metric_subset.yaml index ea45e2dca..42e9c7b90 100644 --- a/src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_sre_metrics.yaml +++ b/src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_metric_subset.yaml @@ -113,11 +113,11 @@ exporters: resource_to_telemetry_conversion: enabled: true send_timestamps: true - prometheusremotewrite/PROMETHEUS-customer-metrics-metrics: - endpoint: https://customer-metrics.example.invalid/api/v1/write + prometheusremotewrite/PROMETHEUS-workload-metrics-metrics: + endpoint: https://workload-metrics.example.invalid/api/v1/write tls: - cert_file: /etc/byoo-otel-collector/secrets/customer-metrics-clientCert - key_file: /etc/byoo-otel-collector/secrets/customer-metrics-clientKey + cert_file: /etc/byoo-otel-collector/secrets/workload-metrics-clientCert + key_file: /etc/byoo-otel-collector/secrets/workload-metrics-clientKey processors: attributes/add-metadata: actions: @@ -149,10 +149,16 @@ processors: send_batch_max_size: 8192 send_batch_size: 4096 timeout: 400ms - batch/sre_metrics: + batch/metric_subset: send_batch_max_size: 8192 send_batch_size: 4096 timeout: 400ms + filter/metric_subset: + error_mode: ignore + metric_conditions: + - metric.name != "BpsInstrument" and metric.name != "FpsInstrument" and metric.name != "RtdInstrument" and metric.name != "StageOpenDuration" + - resource.attributes["metric_subset_enabled"] == "false" + - datapoint.attributes["metric_subset_enabled"] == "false" filter/metrics: metrics: exclude: @@ -162,14 +168,6 @@ processors: - scrape_samples_post_metric_relabeling - scrape_samples_scraped - scrape_series_added - filter/sre_metrics: - error_mode: ignore - metric_conditions: - - metric.name != "BpsInstrument" and metric.name != "FpsInstrument" and metric.name != "RtdInstrument" and metric.name != "StageOpenDuration" - - resource.attributes["sre_metrics_enabled"] == "false" - - resource.attributes["sre_enabled_metrics"] == "false" - - datapoint.attributes["sre_metrics_enabled"] == "false" - - datapoint.attributes["sre_enabled_metrics"] == "false" memory_limiter: check_interval: 1s limit_percentage: 80 @@ -208,12 +206,10 @@ processors: attributes: - action: delete key: service.instance.id - resource/customer_metrics: + resource/workload_metrics_drop_labels: attributes: - action: delete - key: sre_metrics_enabled - - action: delete - key: sre_enabled_metrics + key: metric_subset_enabled extensions: cgroup_runtime: gomaxprocs: @@ -274,25 +270,25 @@ service: - otlp - prometheus exporters: - - prometheusremotewrite/PROMETHEUS-customer-metrics-metrics + - prometheusremotewrite/PROMETHEUS-workload-metrics-metrics processors: - memory_limiter - filter/metrics - resource - - resource/customer_metrics + - resource/workload_metrics_drop_labels - metrics_transform - batch - metrics/sre: + metrics/metric_subset: receivers: - otlp exporters: - prometheus/user-metrics processors: - memory_limiter - - filter/sre_metrics + - filter/metric_subset - resource - metrics_transform - - batch/sre_metrics + - batch/metric_subset extensions: - healthcheckv2 - cgroup_runtime diff --git a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/embed_config.go b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/embed_config.go index 1d8e3567c..90eb415b2 100644 --- a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/embed_config.go +++ b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/embed_config.go @@ -47,7 +47,8 @@ type TemplateConfig struct { InstanceID string ZoneName string LogChunking LogChunkingConfig - SREMetrics SREMetricsConfig + MetricSubset MetricSubsetConfig + WorkloadMetrics WorkloadMetricsConfig // LogExporterBatchMaxSizeBytes configures exporterhelper byte batching for logs. // Zero uses the default selected for BYOO. LogExporterBatchMaxSizeBytes int @@ -58,10 +59,13 @@ type LogChunkingConfig struct { DryRun bool } -type SREMetricsConfig struct { - Enabled bool - FilterConfig map[string]interface{} - CustomerMetricsDropLabels []string +type WorkloadMetricsConfig struct { + DropLabels []string +} + +type MetricSubsetConfig struct { + Enabled bool + FilterConfig map[string]interface{} } func ExecuteTemplate(w io.Writer, tcfg TemplateConfig) error { diff --git a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/otelconfig.go b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/otelconfig.go index 1f4ff457a..f89fffb48 100644 --- a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/otelconfig.go +++ b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/otelconfig.go @@ -42,9 +42,9 @@ type envConfig struct { ByooLogChunkMaxBodyBytes int `split_words:"true"` ByooLogChunkDryRun bool `split_words:"true"` ByooLogExporterBatchMaxSizeBytes int `split_words:"true"` - ByooSreMetricsEnabled bool `split_words:"true"` - ByooSreMetricsFilterConfig string `split_words:"true"` - ByooCustomerMetricsDropLabels string `split_words:"true"` + ByooMetricSubsetEnabled bool `split_words:"true"` + ByooMetricSubsetFilterConfig string `split_words:"true"` + ByooWorkloadMetricsDropLabels string `split_words:"true"` } func processEnvConfig(env *envConfig) error { @@ -79,15 +79,15 @@ func getTemplateConfig() (TemplateConfig, error) { return TemplateConfig{}, fmt.Errorf("BYOO_LOG_EXPORTER_BATCH_MAX_SIZE_BYTES: %w", err) } tcgf.LogExporterBatchMaxSizeBytes = logExporterBatchMaxSizeBytes - sreMetricsFilterConfig, err := resolvedSREMetricsFilterConfig(env.ByooSreMetricsFilterConfig) + metricSubsetFilterConfig, err := resolvedMetricSubsetFilterConfig(env.ByooMetricSubsetFilterConfig) if err != nil { - return TemplateConfig{}, fmt.Errorf("BYOO_SRE_METRICS_FILTER_CONFIG: %w", err) + return TemplateConfig{}, fmt.Errorf("BYOO_METRIC_SUBSET_FILTER_CONFIG: %w", err) } - tcgf.SREMetrics = SREMetricsConfig{ - Enabled: env.ByooSreMetricsEnabled, - FilterConfig: sreMetricsFilterConfig, - CustomerMetricsDropLabels: resolvedCustomerMetricsDropLabels(env.ByooCustomerMetricsDropLabels), + tcgf.MetricSubset = MetricSubsetConfig{ + Enabled: env.ByooMetricSubsetEnabled, + FilterConfig: metricSubsetFilterConfig, } + tcgf.WorkloadMetrics.DropLabels = resolvedWorkloadMetricsDropLabels(env.ByooWorkloadMetricsDropLabels, env.ByooMetricSubsetEnabled) functionID := env.NvcfFunctionID functionVersionID := env.NvcfFunctionVersionID diff --git a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/otelconfig_test.go b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/otelconfig_test.go index 4977328df..847a04764 100644 --- a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/otelconfig_test.go +++ b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/otelconfig_test.go @@ -117,7 +117,7 @@ func TestGetTemplateConfig(t *testing.T) { }, }, { - name: "custom SRE metrics config", + name: "custom metric subset config", env: map[string]string{ "NVCF_BACKEND_TYPE": "gfn", "NVCF_INSTANCE_ID": "test-instance", @@ -125,32 +125,32 @@ func TestGetTemplateConfig(t *testing.T) { "NVCF_WORKLOAD_TYPE": "function", "NVCT_TASK_ID": "task-123", "NVCF_ZONE_NAME": "zone-1", - "BYOO_SRE_METRICS_ENABLED": "true", - "BYOO_SRE_METRICS_FILTER_CONFIG": "error_mode: ignore\nmetric_conditions:\n - 'metric.name == \"drop\"'\n", - "BYOO_CUSTOMER_METRICS_DROP_LABELS": "sre_metrics_enabled, custom_label, sre_metrics_enabled", + "BYOO_METRIC_SUBSET_ENABLED": "true", + "BYOO_METRIC_SUBSET_FILTER_CONFIG": "error_mode: ignore\nmetric_conditions:\n - 'metric.name == \"drop\"'\n", + "BYOO_WORKLOAD_METRICS_DROP_LABELS": "metric_subset_enabled, custom_label, metric_subset_enabled", }, expectErr: false, expect: func(t *testing.T, cfg TemplateConfig) { - assert.True(t, cfg.SREMetrics.Enabled) + assert.True(t, cfg.MetricSubset.Enabled) assert.Equal(t, map[string]interface{}{ "error_mode": "ignore", "metric_conditions": []interface{}{ `metric.name == "drop"`, }, - }, cfg.SREMetrics.FilterConfig) - assert.Equal(t, []string{"sre_metrics_enabled", "custom_label"}, cfg.SREMetrics.CustomerMetricsDropLabels) + }, cfg.MetricSubset.FilterConfig) + assert.Equal(t, []string{"metric_subset_enabled", "custom_label"}, cfg.WorkloadMetrics.DropLabels) }, }, { - name: "invalid SRE metrics filter config", + name: "invalid metric subset filter config", env: map[string]string{ - "NVCF_BACKEND_TYPE": "gfn", - "NVCF_INSTANCE_ID": "test-instance", - "NVCF_NAMESPACE": "test-ns", - "NVCF_WORKLOAD_TYPE": "function", - "NVCT_TASK_ID": "task-123", - "NVCF_ZONE_NAME": "zone-1", - "BYOO_SRE_METRICS_FILTER_CONFIG": "processors: []", + "NVCF_BACKEND_TYPE": "gfn", + "NVCF_INSTANCE_ID": "test-instance", + "NVCF_NAMESPACE": "test-ns", + "NVCF_WORKLOAD_TYPE": "function", + "NVCT_TASK_ID": "task-123", + "NVCF_ZONE_NAME": "zone-1", + "BYOO_METRIC_SUBSET_FILTER_CONFIG": "processors: []", }, expectErr: true, }, @@ -240,9 +240,9 @@ func TestGetTemplateConfig(t *testing.T) { "BYOO_LOG_CHUNK_MAX_BODY_BYTES", "BYOO_LOG_CHUNK_DRY_RUN", "BYOO_LOG_EXPORTER_BATCH_MAX_SIZE_BYTES", - "BYOO_SRE_METRICS_ENABLED", - "BYOO_SRE_METRICS_FILTER_CONFIG", - "BYOO_CUSTOMER_METRICS_DROP_LABELS", + "BYOO_METRIC_SUBSET_ENABLED", + "BYOO_METRIC_SUBSET_FILTER_CONFIG", + "BYOO_WORKLOAD_METRICS_DROP_LABELS", } backup := map[string]*string{} for _, k := range envKeys { diff --git a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render.go b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render.go index 5f9dde95d..de563ed38 100644 --- a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render.go +++ b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render.go @@ -67,16 +67,15 @@ type OpenTelemetryConfig struct { const defaultLogExporterBatchMaxSizeBytes = 1000000 const ( - sreMetricsExporterID = "prometheus/user-metrics" - sreMetricsFilterProcessorID = "filter/sre_metrics" - sreMetricsBatchProcessorID = "batch/sre_metrics" - customerMetricsDropLabelsProcessorID = "resource/customer_metrics" - defaultSREMetricsPort = 19091 + metricSubsetExporterID = "prometheus/user-metrics" + metricSubsetFilterProcessorID = "filter/metric_subset" + metricSubsetBatchProcessorID = "batch/metric_subset" + workloadMetricsDropLabelsProcessorID = "resource/workload_metrics_drop_labels" + defaultMetricSubsetPort = 19091 ) -var defaultCustomerMetricsDropLabels = []string{ - "sre_metrics_enabled", - "sre_enabled_metrics", +var defaultWorkloadMetricsDropLabels = []string{ + "metric_subset_enabled", } // Initialize the maps if they are nil @@ -161,22 +160,20 @@ func resolvedLogExporterBatchMaxSizeBytes(configured int) (int, error) { return configured, nil } -func defaultSREMetricsFilterConfig() map[string]interface{} { +func defaultMetricSubsetFilterConfig() map[string]interface{} { return map[string]interface{}{ "error_mode": "ignore", "metric_conditions": []string{ `metric.name != "BpsInstrument" and metric.name != "FpsInstrument" and metric.name != "RtdInstrument" and metric.name != "StageOpenDuration"`, - `resource.attributes["sre_metrics_enabled"] == "false"`, - `resource.attributes["sre_enabled_metrics"] == "false"`, - `datapoint.attributes["sre_metrics_enabled"] == "false"`, - `datapoint.attributes["sre_enabled_metrics"] == "false"`, + `resource.attributes["metric_subset_enabled"] == "false"`, + `datapoint.attributes["metric_subset_enabled"] == "false"`, }, } } -func resolvedSREMetricsFilterConfig(configured string) (map[string]interface{}, error) { +func resolvedMetricSubsetFilterConfig(configured string) (map[string]interface{}, error) { if strings.TrimSpace(configured) == "" { - return defaultSREMetricsFilterConfig(), nil + return defaultMetricSubsetFilterConfig(), nil } filterConfig := map[string]interface{}{} @@ -187,24 +184,24 @@ func resolvedSREMetricsFilterConfig(configured string) (map[string]interface{}, return nil, fmt.Errorf("filter config must not be empty") } - return unwrapSREMetricsFilterConfig(filterConfig) + return unwrapMetricSubsetFilterConfig(filterConfig) } -func unwrapSREMetricsFilterConfig(filterConfig map[string]interface{}) (map[string]interface{}, error) { +func unwrapMetricSubsetFilterConfig(filterConfig map[string]interface{}) (map[string]interface{}, error) { if rawProcessors, ok := filterConfig["processors"]; ok { processors, err := mapFromConfigValue(rawProcessors, "processors") if err != nil { return nil, err } - rawFilter, ok := processors[sreMetricsFilterProcessorID] + rawFilter, ok := processors[metricSubsetFilterProcessorID] if !ok { - return nil, fmt.Errorf("processors must include %q", sreMetricsFilterProcessorID) + return nil, fmt.Errorf("processors must include %q", metricSubsetFilterProcessorID) } - return mapFromConfigValue(rawFilter, sreMetricsFilterProcessorID) + return mapFromConfigValue(rawFilter, metricSubsetFilterProcessorID) } - if rawFilter, ok := filterConfig[sreMetricsFilterProcessorID]; ok { - return mapFromConfigValue(rawFilter, sreMetricsFilterProcessorID) + if rawFilter, ok := filterConfig[metricSubsetFilterProcessorID]; ok { + return mapFromConfigValue(rawFilter, metricSubsetFilterProcessorID) } if rawFilter, ok := filterConfig["filter"]; ok && len(filterConfig) == 1 { @@ -225,9 +222,12 @@ func mapFromConfigValue(value interface{}, field string) (map[string]interface{} return configMap, nil } -func resolvedCustomerMetricsDropLabels(configured string) []string { +func resolvedWorkloadMetricsDropLabels(configured string, metricSubsetEnabled bool) []string { if strings.TrimSpace(configured) == "" { - return append([]string(nil), defaultCustomerMetricsDropLabels...) + if !metricSubsetEnabled { + return nil + } + return append([]string(nil), defaultWorkloadMetricsDropLabels...) } seen := map[string]struct{}{} @@ -500,7 +500,7 @@ func exporterMetrics(config TelemetryConfig, otelConfig *OpenTelemetryConfig) (e return exporterId, nil } -func addCustomerMetricsDropLabelsProcessor(otelConfig *OpenTelemetryConfig, labels []string) string { +func addWorkloadMetricsDropLabelsProcessor(otelConfig *OpenTelemetryConfig, labels []string) string { if len(labels) == 0 { return "" } @@ -512,15 +512,15 @@ func addCustomerMetricsDropLabelsProcessor(otelConfig *OpenTelemetryConfig, labe "action": "delete", }) } - otelConfig.Processors[customerMetricsDropLabelsProcessorID] = map[string]interface{}{ + otelConfig.Processors[workloadMetricsDropLabelsProcessorID] = map[string]interface{}{ "attributes": actions, } - return customerMetricsDropLabelsProcessorID + return workloadMetricsDropLabelsProcessorID } -func addSREMetricsExporter(otelConfig *OpenTelemetryConfig) { - otelConfig.Exporters[sreMetricsExporterID] = map[string]interface{}{ - "endpoint": fmt.Sprintf("${env:OTEL_POD_IP:-0.0.0.0}:%d", defaultSREMetricsPort), +func addMetricSubsetExporter(otelConfig *OpenTelemetryConfig) { + otelConfig.Exporters[metricSubsetExporterID] = map[string]interface{}{ + "endpoint": fmt.Sprintf("${env:OTEL_POD_IP:-0.0.0.0}:%d", defaultMetricSubsetPort), "resource_to_telemetry_conversion": map[string]interface{}{ "enabled": true, }, @@ -559,14 +559,14 @@ func cloneConfigValue(value interface{}) interface{} { } } -func addSREMetricsPipeline(otelConfig *OpenTelemetryConfig, config SREMetricsConfig) { - addSREMetricsExporter(otelConfig) +func addMetricSubsetPipeline(otelConfig *OpenTelemetryConfig, config MetricSubsetConfig) { + addMetricSubsetExporter(otelConfig) filterConfig := config.FilterConfig if len(filterConfig) == 0 { - filterConfig = defaultSREMetricsFilterConfig() + filterConfig = defaultMetricSubsetFilterConfig() } - otelConfig.Processors[sreMetricsFilterProcessorID] = cloneConfigMap(filterConfig) + otelConfig.Processors[metricSubsetFilterProcessorID] = cloneConfigMap(filterConfig) batchConfig := map[string]interface{}{ "send_batch_size": 4096, @@ -576,19 +576,19 @@ func addSREMetricsPipeline(otelConfig *OpenTelemetryConfig, config SREMetricsCon if existingBatchConfig, ok := otelConfig.Processors["batch"]; ok { batchConfig = cloneConfigMap(existingBatchConfig) } - otelConfig.Processors[sreMetricsBatchProcessorID] = batchConfig + otelConfig.Processors[metricSubsetBatchProcessorID] = batchConfig - sreMetricsPipeline := otelConfig.Service.Pipelines["metrics/sre"] - sreMetricsPipeline.Receivers = []string{"otlp"} - sreMetricsPipeline.Exporters = []string{sreMetricsExporterID} - sreMetricsPipeline.Processors = []string{ + metricSubsetPipeline := otelConfig.Service.Pipelines["metrics/metric_subset"] + metricSubsetPipeline.Receivers = []string{"otlp"} + metricSubsetPipeline.Exporters = []string{metricSubsetExporterID} + metricSubsetPipeline.Processors = []string{ "memory_limiter", - sreMetricsFilterProcessorID, + metricSubsetFilterProcessorID, "resource", "metrics_transform", - sreMetricsBatchProcessorID, + metricSubsetBatchProcessorID, } - otelConfig.Service.Pipelines["metrics/sre"] = sreMetricsPipeline + otelConfig.Service.Pipelines["metrics/metric_subset"] = metricSubsetPipeline } func exporterTraces(config TelemetryConfig, otelConfig *OpenTelemetryConfig) (exporterId string, err error) { @@ -815,16 +815,14 @@ func generateExportersAndService(config TelemetryConfig, otelConfig *OpenTelemet metricPipeline.Receivers = []string{"otlp", "prometheus"} metricPipeline.Exporters = []string{exporterId} metricPipeline.Processors = []string{"memory_limiter", "filter/metrics", "resource"} - if tmplConfig.SREMetrics.Enabled { - if processorID := addCustomerMetricsDropLabelsProcessor(otelConfig, tmplConfig.SREMetrics.CustomerMetricsDropLabels); processorID != "" { - metricPipeline.Processors = append(metricPipeline.Processors, processorID) - } + if processorID := addWorkloadMetricsDropLabelsProcessor(otelConfig, tmplConfig.WorkloadMetrics.DropLabels); processorID != "" { + metricPipeline.Processors = append(metricPipeline.Processors, processorID) } metricPipeline.Processors = append(metricPipeline.Processors, "metrics_transform", "batch") otelConfig.Service.Pipelines["metrics"] = metricPipeline - if tmplConfig.SREMetrics.Enabled { - addSREMetricsPipeline(otelConfig, tmplConfig.SREMetrics) + if tmplConfig.MetricSubset.Enabled { + addMetricSubsetPipeline(otelConfig, tmplConfig.MetricSubset) } } diff --git a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render_test.go b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render_test.go index aa8eab97f..67864c31e 100644 --- a/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render_test.go +++ b/src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render_test.go @@ -97,7 +97,7 @@ func TestRenderOtelConfig(t *testing.T) { } } -func TestRenderOtelConfigWithSREMetricsPipeline(t *testing.T) { +func TestRenderOtelConfigWithMetricSubsetPipeline(t *testing.T) { gotCfg, err := RenderOtelConfigFromBytes( []byte(`{"telemetries": {"metricsTelemetry": {"protocol": "HTTP", "provider": "PROMETHEUS", "endpoint": "https://metrics.example.invalid/api/v1/write", "name": "example-metrics"}}}`), TemplateConfig{ @@ -108,10 +108,12 @@ func TestRenderOtelConfigWithSREMetricsPipeline(t *testing.T) { FunctionVersionID: "fake-function-version-id", InstanceID: "fake-instance-id", ZoneName: "fake-zone-name", - SREMetrics: SREMetricsConfig{ - Enabled: true, - FilterConfig: defaultSREMetricsFilterConfig(), - CustomerMetricsDropLabels: defaultCustomerMetricsDropLabels, + MetricSubset: MetricSubsetConfig{ + Enabled: true, + FilterConfig: defaultMetricSubsetFilterConfig(), + }, + WorkloadMetrics: WorkloadMetricsConfig{ + DropLabels: defaultWorkloadMetricsDropLabels, }, }, ) @@ -121,25 +123,25 @@ func TestRenderOtelConfigWithSREMetricsPipeline(t *testing.T) { otelConfig := &OpenTelemetryConfig{} err = yaml.Unmarshal(gotCfg, otelConfig) assert.NoError(t, err) - assert.Contains(t, otelConfig.Exporters, sreMetricsExporterID) - assert.Contains(t, otelConfig.Processors, sreMetricsFilterProcessorID) - assert.Contains(t, otelConfig.Processors, sreMetricsBatchProcessorID) - assert.Equal(t, []string{"otlp"}, otelConfig.Service.Pipelines["metrics/sre"].Receivers) - assert.Equal(t, []string{sreMetricsExporterID}, otelConfig.Service.Pipelines["metrics/sre"].Exporters) + assert.Contains(t, otelConfig.Exporters, metricSubsetExporterID) + assert.Contains(t, otelConfig.Processors, metricSubsetFilterProcessorID) + assert.Contains(t, otelConfig.Processors, metricSubsetBatchProcessorID) + assert.Equal(t, []string{"otlp"}, otelConfig.Service.Pipelines["metrics/metric_subset"].Receivers) + assert.Equal(t, []string{metricSubsetExporterID}, otelConfig.Service.Pipelines["metrics/metric_subset"].Exporters) assert.Equal(t, []string{ "memory_limiter", - sreMetricsFilterProcessorID, + metricSubsetFilterProcessorID, "resource", "metrics_transform", - sreMetricsBatchProcessorID, - }, otelConfig.Service.Pipelines["metrics/sre"].Processors) + metricSubsetBatchProcessorID, + }, otelConfig.Service.Pipelines["metrics/metric_subset"].Processors) } -func TestRenderOtelConfigWithSREMetricsPipelineMatchesExample(t *testing.T) { +func TestRenderOtelConfigWithMetricSubsetPipelineMatchesExample(t *testing.T) { t.Setenv("ESS_SECRETS_PATH", "") gotCfg, err := RenderOtelConfigFromBytes( - []byte(`{"telemetries": {"metricsTelemetry": {"protocol": "HTTP", "provider": "PROMETHEUS", "endpoint": "https://customer-metrics.example.invalid/api/v1/write", "name": "customer-metrics"}}}`), + []byte(`{"telemetries": {"metricsTelemetry": {"protocol": "HTTP", "provider": "PROMETHEUS", "endpoint": "https://workload-metrics.example.invalid/api/v1/write", "name": "workload-metrics"}}}`), TemplateConfig{ BackendType: K8s, WorkloadType: Container, @@ -148,27 +150,29 @@ func TestRenderOtelConfigWithSREMetricsPipelineMatchesExample(t *testing.T) { FunctionVersionID: "fake-function-version-id", InstanceID: "fake-instance-id", ZoneName: "fake-zone-name", - SREMetrics: SREMetricsConfig{ - Enabled: true, - FilterConfig: defaultSREMetricsFilterConfig(), - CustomerMetricsDropLabels: defaultCustomerMetricsDropLabels, + MetricSubset: MetricSubsetConfig{ + Enabled: true, + FilterConfig: defaultMetricSubsetFilterConfig(), + }, + WorkloadMetrics: WorkloadMetricsConfig{ + DropLabels: defaultWorkloadMetricsDropLabels, }, }, ) if err != nil { - t.Fatalf("failed to render SRE metrics config: %v", err) + t.Fatalf("failed to render metric subset config: %v", err) } - const examplePath = "../../examples/otelconfigs/k8s/config_function_container_sre_metrics.yaml" - if os.Getenv("UPDATE_SRE_METRICS_EXAMPLE") == "true" { + const examplePath = "../../examples/otelconfigs/k8s/config_function_container_metric_subset.yaml" + if os.Getenv("UPDATE_METRIC_SUBSET_EXAMPLE") == "true" { if err := os.WriteFile(examplePath, gotCfg, 0o644); err != nil { - t.Fatalf("failed to update SRE metrics example config: %v", err) + t.Fatalf("failed to update metric subset example config: %v", err) } } expectedCfg, err := os.ReadFile(examplePath) if err != nil { - t.Fatalf("failed to read SRE metrics example config: %v", err) + t.Fatalf("failed to read metric subset example config: %v", err) } assertYAMLConfigEqual(t, expectedCfg, gotCfg) @@ -487,7 +491,7 @@ func TestGenerateExportersAndServiceUsesCustomLogExporterBatchMaxSize(t *testing }, exporter["sending_queue"]) } -func TestGenerateExportersAndServiceAddsSREMetricsPipeline(t *testing.T) { +func TestGenerateExportersAndServiceAddsMetricSubsetPipeline(t *testing.T) { cfg := TelemetryConfig{ Telemetries: Telemetries{ Metrics: &Telemetry{ @@ -514,10 +518,12 @@ func TestGenerateExportersAndServiceAddsSREMetricsPipeline(t *testing.T) { err := generateExportersAndService(cfg, otelConfig, TemplateConfig{ Namespace: "test-namespace", - SREMetrics: SREMetricsConfig{ - Enabled: true, - FilterConfig: filterConfig, - CustomerMetricsDropLabels: []string{"sre_metrics_enabled"}, + MetricSubset: MetricSubsetConfig{ + Enabled: true, + FilterConfig: filterConfig, + }, + WorkloadMetrics: WorkloadMetricsConfig{ + DropLabels: []string{"metric_subset_enabled"}, }, }) @@ -530,44 +536,79 @@ func TestGenerateExportersAndServiceAddsSREMetricsPipeline(t *testing.T) { "send_timestamps": true, "metric_expiration": "5m", "enable_open_metrics": true, - }, otelConfig.Exporters[sreMetricsExporterID]) - assert.Equal(t, filterConfig, otelConfig.Processors[sreMetricsFilterProcessorID]) - assert.Equal(t, otelConfig.Processors["batch"], otelConfig.Processors[sreMetricsBatchProcessorID]) + }, otelConfig.Exporters[metricSubsetExporterID]) + assert.Equal(t, filterConfig, otelConfig.Processors[metricSubsetFilterProcessorID]) + assert.Equal(t, otelConfig.Processors["batch"], otelConfig.Processors[metricSubsetBatchProcessorID]) - customerMetricsPipeline := otelConfig.Service.Pipelines["metrics"] - assert.Equal(t, []string{"otlp", "prometheus"}, customerMetricsPipeline.Receivers) - assert.Equal(t, []string{"prometheusremotewrite/PROMETHEUS-example-metrics-metrics"}, customerMetricsPipeline.Exporters) + workloadMetricsPipeline := otelConfig.Service.Pipelines["metrics"] + assert.Equal(t, []string{"otlp", "prometheus"}, workloadMetricsPipeline.Receivers) + assert.Equal(t, []string{"prometheusremotewrite/PROMETHEUS-example-metrics-metrics"}, workloadMetricsPipeline.Exporters) assert.Equal(t, []string{ "memory_limiter", "filter/metrics", "resource", - customerMetricsDropLabelsProcessorID, + workloadMetricsDropLabelsProcessorID, "metrics_transform", "batch", - }, customerMetricsPipeline.Processors) - assert.NotContains(t, customerMetricsPipeline.Processors, sreMetricsFilterProcessorID) + }, workloadMetricsPipeline.Processors) + assert.NotContains(t, workloadMetricsPipeline.Processors, metricSubsetFilterProcessorID) assert.Equal(t, map[string]interface{}{ "attributes": []map[string]interface{}{ { - "key": "sre_metrics_enabled", + "key": "metric_subset_enabled", "action": "delete", }, }, - }, otelConfig.Processors[customerMetricsDropLabelsProcessorID]) + }, otelConfig.Processors[workloadMetricsDropLabelsProcessorID]) - sreMetricsPipeline := otelConfig.Service.Pipelines["metrics/sre"] - assert.Equal(t, []string{"otlp"}, sreMetricsPipeline.Receivers) - assert.Equal(t, []string{sreMetricsExporterID}, sreMetricsPipeline.Exporters) + metricSubsetPipeline := otelConfig.Service.Pipelines["metrics/metric_subset"] + assert.Equal(t, []string{"otlp"}, metricSubsetPipeline.Receivers) + assert.Equal(t, []string{metricSubsetExporterID}, metricSubsetPipeline.Exporters) assert.Equal(t, []string{ "memory_limiter", - sreMetricsFilterProcessorID, + metricSubsetFilterProcessorID, "resource", "metrics_transform", - sreMetricsBatchProcessorID, - }, sreMetricsPipeline.Processors) + metricSubsetBatchProcessorID, + }, metricSubsetPipeline.Processors) +} + +func TestGenerateExportersAndServiceAddsWorkloadMetricsDropLabelsWithoutMetricSubset(t *testing.T) { + cfg := TelemetryConfig{ + Telemetries: Telemetries{ + Metrics: &Telemetry{ + Name: "example-metrics", + Protocol: ProtocolHTTP, + Provider: ProviderPrometheus, + Endpoint: "https://metrics.example.invalid/api/v1/write", + }, + }, + } + otelConfig := &OpenTelemetryConfig{} + initializeConfigMaps(otelConfig) + + err := generateExportersAndService(cfg, otelConfig, TemplateConfig{ + Namespace: "test-namespace", + WorkloadMetrics: WorkloadMetricsConfig{ + DropLabels: []string{"workload_label"}, + }, + }) + + assert.NoError(t, err) + assert.NotContains(t, otelConfig.Exporters, metricSubsetExporterID) + assert.NotContains(t, otelConfig.Service.Pipelines, "metrics/metric_subset") + assert.Equal(t, map[string]interface{}{ + "attributes": []map[string]interface{}{ + { + "key": "workload_label", + "action": "delete", + }, + }, + }, otelConfig.Processors[workloadMetricsDropLabelsProcessorID]) + assert.Contains(t, otelConfig.Service.Pipelines["metrics"].Processors, workloadMetricsDropLabelsProcessorID) } -func TestGenerateExportersAndServiceDoesNotAddSREMetricsPipelineWithoutCustomerMetrics(t *testing.T) { +func TestGenerateExportersAndServiceDoesNotAddMetricSubsetPipelineWithoutMetricsTelemetry(t *testing.T) { cfg := TelemetryConfig{ Telemetries: Telemetries{ Logs: &Telemetry{ @@ -583,15 +624,15 @@ func TestGenerateExportersAndServiceDoesNotAddSREMetricsPipelineWithoutCustomerM err := generateExportersAndService(cfg, otelConfig, TemplateConfig{ Namespace: "test-namespace", - SREMetrics: SREMetricsConfig{ + MetricSubset: MetricSubsetConfig{ Enabled: true, }, }) assert.NoError(t, err) - assert.NotContains(t, otelConfig.Exporters, sreMetricsExporterID) - assert.NotContains(t, otelConfig.Processors, sreMetricsFilterProcessorID) - assert.NotContains(t, otelConfig.Service.Pipelines, "metrics/sre") + assert.NotContains(t, otelConfig.Exporters, metricSubsetExporterID) + assert.NotContains(t, otelConfig.Processors, metricSubsetFilterProcessorID) + assert.NotContains(t, otelConfig.Service.Pipelines, "metrics/metric_subset") } // Test_exporterMetrics_Datadog_KeepsFirstCumulativeSample is a regression test diff --git a/src/compute-plane-services/nvca/internal/miniservice/reconcile.go b/src/compute-plane-services/nvca/internal/miniservice/reconcile.go index 81494ced3..283fa5da1 100644 --- a/src/compute-plane-services/nvca/internal/miniservice/reconcile.go +++ b/src/compute-plane-services/nvca/internal/miniservice/reconcile.go @@ -739,7 +739,7 @@ func (r *Reconciler) doInstall(ctx context.Context, } // Apply BYOO telemetry annotations to workload objects for Helm-rendered pods metaInput.EnvVars = append(metaInput.EnvVars, byooEnvs...) - metaInput.OTelCollectorEnvVars = append(metaInput.OTelCollectorEnvVars, r.cfg.Agent.BYOOLogChunking.EnvVars()...) + metaInput.OTelCollectorEnvVars = append(metaInput.OTelCollectorEnvVars, r.cfg.Agent.BYOOOTelCollectorEnvVars()...) } // Task-specific mutators. diff --git a/src/compute-plane-services/nvca/internal/miniservice/reconcile_test.go b/src/compute-plane-services/nvca/internal/miniservice/reconcile_test.go index 7919f39b3..c33a4e230 100644 --- a/src/compute-plane-services/nvca/internal/miniservice/reconcile_test.go +++ b/src/compute-plane-services/nvca/internal/miniservice/reconcile_test.go @@ -260,6 +260,13 @@ func TestReconcile_Function(t *testing.T) { DryRun: true, ExporterBatchMaxSizeBytes: &exporterBatchMaxSizeBytes, } + r.cfg.Agent.BYOOMetricSubset = nvcaconfig.BYOOMetricSubsetConfig{ + Enabled: true, + FilterConfig: "error_mode: ignore\nmetric_conditions:\n - 'metric.name == \"drop\"'\n", + } + r.cfg.Agent.BYOOWorkloadMetrics = nvcaconfig.BYOOWorkloadMetricsConfig{ + DropLabels: []string{"metric_subset_enabled", "custom_label"}, + } err := k8sutil.SetConfigDefaultResources(&r.cfg) require.NoError(t, err) r.cfg.Workload.Tolerations = []corev1.Toleration{configuredToleration} @@ -806,6 +813,7 @@ rules: metaEnv[env.Name] = env.Value } assert.NotContains(t, metaEnv, nvcaconfig.BYOOLogChunkMaxBodyBytesEnv) + assert.NotContains(t, metaEnv, nvcaconfig.BYOOMetricSubsetEnabledEnv) otelCollectorEnv := map[string]string{} for _, env := range msMeta.OTelCollectorEnvVars { otelCollectorEnv[env.Name] = env.Value @@ -813,6 +821,9 @@ rules: assert.Equal(t, "983040", otelCollectorEnv[nvcaconfig.BYOOLogChunkMaxBodyBytesEnv]) assert.Equal(t, "true", otelCollectorEnv[nvcaconfig.BYOOLogChunkDryRunEnv]) assert.Equal(t, "1000000", otelCollectorEnv[nvcaconfig.BYOOLogExporterBatchMaxSizeBytesEnv]) + assert.Equal(t, "true", otelCollectorEnv[nvcaconfig.BYOOMetricSubsetEnabledEnv]) + assert.Contains(t, otelCollectorEnv[nvcaconfig.BYOOMetricSubsetFilterConfigEnv], "metric.name") + assert.Equal(t, "metric_subset_enabled,custom_label", otelCollectorEnv[nvcaconfig.BYOOWorkloadMetricsDropLabelsEnv]) assert.Equal(t, nodefeatures.UniformInstanceTypeLabelKey, msMeta.NodeAffinityKey) assert.Equal(t, []corev1.Toleration{configuredToleration}, msMeta.Tolerations) diff --git a/src/compute-plane-services/nvca/internal/util/k8sutil/BUILD.bazel b/src/compute-plane-services/nvca/internal/util/k8sutil/BUILD.bazel index 70dcc365a..b1906412c 100644 --- a/src/compute-plane-services/nvca/internal/util/k8sutil/BUILD.bazel +++ b/src/compute-plane-services/nvca/internal/util/k8sutil/BUILD.bazel @@ -8,7 +8,7 @@ go_library( srcs = [ "affinity.go", "annotations.go", - "byoo_log_chunking.go", + "byoo_env_vars.go", "clientshim.go", "customization.go", "encoding.go", @@ -61,7 +61,7 @@ go_test( name = "k8sutil_test", srcs = [ "annotations_test.go", - "byoo_log_chunking_test.go", + "byoo_env_vars_test.go", "clientshim_test.go", "encoding_test.go", "errors_test.go", diff --git a/src/compute-plane-services/nvca/internal/util/k8sutil/byoo_log_chunking.go b/src/compute-plane-services/nvca/internal/util/k8sutil/byoo_env_vars.go similarity index 84% rename from src/compute-plane-services/nvca/internal/util/k8sutil/byoo_log_chunking.go rename to src/compute-plane-services/nvca/internal/util/k8sutil/byoo_env_vars.go index f4cb347ce..4b671a18a 100644 --- a/src/compute-plane-services/nvca/internal/util/k8sutil/byoo_log_chunking.go +++ b/src/compute-plane-services/nvca/internal/util/k8sutil/byoo_env_vars.go @@ -22,8 +22,8 @@ import ( corev1 "k8s.io/api/core/v1" ) -// AddBYOOLogChunkingEnvVarsToPodSpec injects env vars into only the BYOO OTel collector container. -func AddBYOOLogChunkingEnvVarsToPodSpec(podSpec *corev1.PodSpec, envs []corev1.EnvVar) { +// AddBYOOEnvVarsToPodSpec injects env vars into only the BYOO OTel collector container. +func AddBYOOEnvVarsToPodSpec(podSpec *corev1.PodSpec, envs []corev1.EnvVar) { if len(envs) == 0 { return } diff --git a/src/compute-plane-services/nvca/internal/util/k8sutil/byoo_log_chunking_test.go b/src/compute-plane-services/nvca/internal/util/k8sutil/byoo_env_vars_test.go similarity index 86% rename from src/compute-plane-services/nvca/internal/util/k8sutil/byoo_log_chunking_test.go rename to src/compute-plane-services/nvca/internal/util/k8sutil/byoo_env_vars_test.go index ea11ad8ee..b229c1c89 100644 --- a/src/compute-plane-services/nvca/internal/util/k8sutil/byoo_log_chunking_test.go +++ b/src/compute-plane-services/nvca/internal/util/k8sutil/byoo_env_vars_test.go @@ -26,14 +26,16 @@ import ( corev1 "k8s.io/api/core/v1" ) -func TestAddBYOOLogChunkingEnvVarsToPodSpecMutatesOnlyBYOOCollectorContainer(t *testing.T) { +func TestAddBYOOEnvVarsToPodSpecMutatesOnlyBYOOCollectorContainer(t *testing.T) { envs := []corev1.EnvVar{ {Name: nvcaconfig.BYOOLogChunkMaxBodyBytesEnv, Value: "983040"}, {Name: nvcaconfig.BYOOLogExporterBatchMaxSizeBytesEnv, Value: "1000000"}, + {Name: nvcaconfig.BYOOMetricSubsetEnabledEnv, Value: "true"}, } expectedEnv := []corev1.EnvVar{ {Name: nvcaconfig.BYOOLogChunkMaxBodyBytesEnv, Value: "983040"}, {Name: nvcaconfig.BYOOLogExporterBatchMaxSizeBytesEnv, Value: "1000000"}, + {Name: nvcaconfig.BYOOMetricSubsetEnabledEnv, Value: "true"}, } pod := &corev1.Pod{ Spec: corev1.PodSpec{ @@ -49,7 +51,7 @@ func TestAddBYOOLogChunkingEnvVarsToPodSpecMutatesOnlyBYOOCollectorContainer(t * }, } - AddBYOOLogChunkingEnvVarsToPodSpec(&pod.Spec, envs) + AddBYOOEnvVarsToPodSpec(&pod.Spec, envs) assert.Equal(t, expectedEnv, pod.Spec.Containers[0].Env) assert.Empty(t, pod.Spec.Containers[1].Env) diff --git a/src/compute-plane-services/nvca/pkg/nvca/k8scomputebackend.go b/src/compute-plane-services/nvca/pkg/nvca/k8scomputebackend.go index 3988e2296..b07d2e24f 100644 --- a/src/compute-plane-services/nvca/pkg/nvca/k8scomputebackend.go +++ b/src/compute-plane-services/nvca/pkg/nvca/k8scomputebackend.go @@ -317,13 +317,13 @@ func (c K8sComputeBackend) translateFunctionLaunchSpecification( return nil, nvcaerrors.TerminalError(err) } if reqType == ftContainer { - envs := c.bk8s.cfg.Agent.BYOOLogChunking.EnvVars() + envs := c.bk8s.cfg.Agent.BYOOOTelCollectorEnvVars() for _, obj := range objs { pod, ok := obj.(*corev1.Pod) if !ok { continue } - k8sutil.AddBYOOLogChunkingEnvVarsToPodSpec(&pod.Spec, envs) + k8sutil.AddBYOOEnvVarsToPodSpec(&pod.Spec, envs) } } diff --git a/src/compute-plane-services/nvca/pkg/nvca/k8scomputebackend_task_container.go b/src/compute-plane-services/nvca/pkg/nvca/k8scomputebackend_task_container.go index 4c58b3214..a8049d322 100644 --- a/src/compute-plane-services/nvca/pkg/nvca/k8scomputebackend_task_container.go +++ b/src/compute-plane-services/nvca/pkg/nvca/k8scomputebackend_task_container.go @@ -131,13 +131,13 @@ func (c K8sComputeBackend) applyContainerTaskCreationMessage(ctx context.Context metrics.EventErrorTotal.WithLabelValues(metricLabels...).Inc() return err } - envs := c.bk8s.cfg.Agent.BYOOLogChunking.EnvVars() + envs := c.bk8s.cfg.Agent.BYOOOTelCollectorEnvVars() for _, obj := range objs { pod, ok := obj.(*corev1.Pod) if !ok { continue } - k8sutil.AddBYOOLogChunkingEnvVarsToPodSpec(&pod.Spec, envs) + k8sutil.AddBYOOEnvVarsToPodSpec(&pod.Spec, envs) } ownerRefsForReq := getOwnerRefForRequest(req) diff --git a/src/compute-plane-services/nvca/pkg/operator/reconcile/nvcaagent_reconcile_test.go b/src/compute-plane-services/nvca/pkg/operator/reconcile/nvcaagent_reconcile_test.go index 4e598bb71..751c6b2bb 100644 --- a/src/compute-plane-services/nvca/pkg/operator/reconcile/nvcaagent_reconcile_test.go +++ b/src/compute-plane-services/nvca/pkg/operator/reconcile/nvcaagent_reconcile_test.go @@ -2841,6 +2841,13 @@ func TestEncodeAgentConfig_MergesBYOOConfig(t *testing.T) { DryRun: true, ExporterBatchMaxSizeBytes: ptr.To[int64](1000000), }, + BYOOMetricSubset: nvcaconfig.BYOOMetricSubsetConfig{ + Enabled: true, + FilterConfig: "error_mode: ignore\nmetric_conditions:\n - 'metric.name == \"drop\"'\n", + }, + BYOOWorkloadMetrics: nvcaconfig.BYOOWorkloadMetricsConfig{ + DropLabels: []string{"metric_subset_enabled", "custom_label"}, + }, }, } @@ -2857,6 +2864,9 @@ func TestEncodeAgentConfig_MergesBYOOConfig(t *testing.T) { assert.True(t, got.Agent.BYOOLogChunking.DryRun) require.NotNil(t, got.Agent.BYOOLogChunking.ExporterBatchMaxSizeBytes) assert.Equal(t, int64(1000000), *got.Agent.BYOOLogChunking.ExporterBatchMaxSizeBytes) + assert.True(t, got.Agent.BYOOMetricSubset.Enabled) + assert.Contains(t, got.Agent.BYOOMetricSubset.FilterConfig, "metric.name") + assert.Equal(t, []string{"metric_subset_enabled", "custom_label"}, got.Agent.BYOOWorkloadMetrics.DropLabels) } func TestAgentHostOverrideConfig_ClearsReValHostForSelfHostedColocatedService(t *testing.T) { diff --git a/src/compute-plane-services/nvca/pkg/webhook/miniservice_mutating_webhook.go b/src/compute-plane-services/nvca/pkg/webhook/miniservice_mutating_webhook.go index 6ad27753b..35795b793 100644 --- a/src/compute-plane-services/nvca/pkg/webhook/miniservice_mutating_webhook.go +++ b/src/compute-plane-services/nvca/pkg/webhook/miniservice_mutating_webhook.go @@ -366,7 +366,7 @@ func (w *miniserviceMutatingWebhook) mutatePodSpec(ps *corev1.PodSpec, meta nvca } _ = translatecommon.AddMixedEnvsToContainers(overrideableEnvVars, ps.InitContainers, meta.EnvVars...) _ = translatecommon.AddMixedEnvsToContainers(overrideableEnvVars, ps.Containers, meta.EnvVars...) - k8sutil.AddBYOOLogChunkingEnvVarsToPodSpec(ps, meta.OTelCollectorEnvVars) + k8sutil.AddBYOOEnvVarsToPodSpec(ps, meta.OTelCollectorEnvVars) // If the pod is allowed k8s api access (ex. when an operator created it), and it has set a non-default service account, // use it instead of the service account override. diff --git a/src/compute-plane-services/nvca/pkg/webhook/miniservice_mutating_webhook_test.go b/src/compute-plane-services/nvca/pkg/webhook/miniservice_mutating_webhook_test.go index 53725eb58..5c4ff38dd 100644 --- a/src/compute-plane-services/nvca/pkg/webhook/miniservice_mutating_webhook_test.go +++ b/src/compute-plane-services/nvca/pkg/webhook/miniservice_mutating_webhook_test.go @@ -1186,7 +1186,7 @@ func TestMiniserviceMutatePodSpec_BYOObservability(t *testing.T) { } } -func TestMiniserviceMutatePodSpec_BYOOLogChunkingEnvVarsOnlyCollector(t *testing.T) { +func TestMiniserviceMutatePodSpec_BYOOOTelCollectorEnvVarsOnlyCollector(t *testing.T) { meta := nvcatypes.MiniserviceMetadata{ EnvVars: []corev1.EnvVar{ {Name: "SHARED_ENV", Value: "shared"}, @@ -1194,6 +1194,7 @@ func TestMiniserviceMutatePodSpec_BYOOLogChunkingEnvVarsOnlyCollector(t *testing OTelCollectorEnvVars: []corev1.EnvVar{ {Name: nvcaconfig.BYOOLogChunkMaxBodyBytesEnv, Value: "983040"}, {Name: nvcaconfig.BYOOLogExporterBatchMaxSizeBytesEnv, Value: "1000000"}, + {Name: nvcaconfig.BYOOMetricSubsetEnabledEnv, Value: "true"}, }, } ps := corev1.PodSpec{ @@ -1220,8 +1221,11 @@ func TestMiniserviceMutatePodSpec_BYOOLogChunkingEnvVarsOnlyCollector(t *testing assert.Equal(t, "shared", collectorByName["SHARED_ENV"]) assert.NotContains(t, initByName, nvcaconfig.BYOOLogChunkMaxBodyBytesEnv) assert.NotContains(t, appByName, nvcaconfig.BYOOLogChunkMaxBodyBytesEnv) + assert.NotContains(t, initByName, nvcaconfig.BYOOMetricSubsetEnabledEnv) + assert.NotContains(t, appByName, nvcaconfig.BYOOMetricSubsetEnabledEnv) assert.Equal(t, "983040", collectorByName[nvcaconfig.BYOOLogChunkMaxBodyBytesEnv]) assert.Equal(t, "1000000", collectorByName[nvcaconfig.BYOOLogExporterBatchMaxSizeBytesEnv]) + assert.Equal(t, "true", collectorByName[nvcaconfig.BYOOMetricSubsetEnabledEnv]) } func envNames(envs []corev1.EnvVar) []string { diff --git a/src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/types/nvca/config/types.go b/src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/types/nvca/config/types.go index 2be981d23..0c50950a1 100644 --- a/src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/types/nvca/config/types.go +++ b/src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/types/nvca/config/types.go @@ -19,6 +19,7 @@ import ( "fmt" "reflect" "strconv" + "strings" "time" "github.com/go-viper/mapstructure/v2" @@ -58,6 +59,12 @@ const ( BYOOLogChunkDryRunEnv = "BYOO_LOG_CHUNK_DRY_RUN" // BYOOLogExporterBatchMaxSizeBytesEnv is the BYOO collector env var for exporterhelper byte batch splitting. BYOOLogExporterBatchMaxSizeBytesEnv = "BYOO_LOG_EXPORTER_BATCH_MAX_SIZE_BYTES" + // BYOOMetricSubsetEnabledEnv is the BYOO collector env var that enables the metric subset pipeline. + BYOOMetricSubsetEnabledEnv = "BYOO_METRIC_SUBSET_ENABLED" + // BYOOMetricSubsetFilterConfigEnv is the BYOO collector env var for metric subset filter config YAML. + BYOOMetricSubsetFilterConfigEnv = "BYOO_METRIC_SUBSET_FILTER_CONFIG" + // BYOOWorkloadMetricsDropLabelsEnv is the BYOO collector env var for workload metrics resource labels to drop. + BYOOWorkloadMetricsDropLabelsEnv = "BYOO_WORKLOAD_METRICS_DROP_LABELS" // DefaultBYOOLogExporterBatchMaxSizeBytes keeps serialized exporter batches near the backend limit. DefaultBYOOLogExporterBatchMaxSizeBytes int64 = 1000000 @@ -110,6 +117,51 @@ func BYOOLogChunkingEnvVars(config BYOOLogChunkingConfig) []corev1.EnvVar { return config.EnvVars() } +type BYOOMetricSubsetConfig struct { + Enabled bool `yaml:"enabled,omitempty"` + FilterConfig string `yaml:"filterConfig,omitempty"` +} + +func (c BYOOMetricSubsetConfig) IsZero() bool { + return !c.Enabled && c.FilterConfig == "" +} + +// EnvVars returns BYOO collector env vars for the supplied metric subset config. +func (c BYOOMetricSubsetConfig) EnvVars() []corev1.EnvVar { + envs := []corev1.EnvVar{} + if c.Enabled { + envs = append(envs, corev1.EnvVar{ + Name: BYOOMetricSubsetEnabledEnv, + Value: strconv.FormatBool(c.Enabled), + }) + } + if c.FilterConfig != "" { + envs = append(envs, corev1.EnvVar{ + Name: BYOOMetricSubsetFilterConfigEnv, + Value: c.FilterConfig, + }) + } + return envs +} + +type BYOOWorkloadMetricsConfig struct { + DropLabels []string `yaml:"dropLabels,omitempty"` +} + +func (c BYOOWorkloadMetricsConfig) IsZero() bool { + return len(c.DropLabels) == 0 +} + +func (c BYOOWorkloadMetricsConfig) EnvVars() []corev1.EnvVar { + if len(c.DropLabels) == 0 { + return nil + } + return []corev1.EnvVar{{ + Name: BYOOWorkloadMetricsDropLabelsEnv, + Value: strings.Join(c.DropLabels, ","), + }} +} + func (r *ResourceRequirements) ToK8sResourceRequirements() corev1.ResourceRequirements { return corev1.ResourceRequirements{ Limits: corev1.ResourceList(r.Limits), @@ -340,6 +392,12 @@ type AgentConfig struct { // BYOOLogChunking contains BYOO OTel collector log chunking and exporter batch settings. BYOOLogChunking BYOOLogChunkingConfig `yaml:",omitempty"` + + // BYOOMetricSubset contains BYOO OTel collector metric subset pipeline settings. + BYOOMetricSubset BYOOMetricSubsetConfig `yaml:"byooMetricSubset,omitempty"` + + // BYOOWorkloadMetrics contains settings for the generated workload metrics pipeline. + BYOOWorkloadMetrics BYOOWorkloadMetricsConfig `yaml:"byooWorkloadMetrics,omitempty"` } func (t AgentConfig) Complete(env Environment) AgentConfig { @@ -352,6 +410,13 @@ func (t AgentConfig) Complete(env Environment) AgentConfig { return t } +// BYOOOTelCollectorEnvVars returns env vars that must be set only on the BYOO OTel collector container. +func (t AgentConfig) BYOOOTelCollectorEnvVars() []corev1.EnvVar { + envs := t.BYOOLogChunking.EnvVars() + envs = append(envs, t.BYOOMetricSubset.EnvVars()...) + return append(envs, t.BYOOWorkloadMetrics.EnvVars()...) +} + const ( defaultCredRenewInterval = 45 * time.Minute defaultHeartbeatInterval = 5 * time.Minute diff --git a/src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/types/nvca/config/zz_generated.deepcopy.go b/src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/types/nvca/config/zz_generated.deepcopy.go index 5e7b6d3d9..f13411198 100644 --- a/src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/types/nvca/config/zz_generated.deepcopy.go +++ b/src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/types/nvca/config/zz_generated.deepcopy.go @@ -71,6 +71,8 @@ func (in *AgentConfig) DeepCopyInto(out *AgentConfig) { in.BYOOResources.DeepCopyInto(&out.BYOOResources) in.BYOOFluentBitResources.DeepCopyInto(&out.BYOOFluentBitResources) in.BYOOLogChunking.DeepCopyInto(&out.BYOOLogChunking) + out.BYOOMetricSubset = in.BYOOMetricSubset + in.BYOOWorkloadMetrics.DeepCopyInto(&out.BYOOWorkloadMetrics) return } @@ -153,6 +155,43 @@ func (in *BYOOLogChunkingConfig) DeepCopy() *BYOOLogChunkingConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BYOOMetricSubsetConfig) DeepCopyInto(out *BYOOMetricSubsetConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BYOOMetricSubsetConfig. +func (in *BYOOMetricSubsetConfig) DeepCopy() *BYOOMetricSubsetConfig { + if in == nil { + return nil + } + out := new(BYOOMetricSubsetConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BYOOWorkloadMetricsConfig) DeepCopyInto(out *BYOOWorkloadMetricsConfig) { + *out = *in + if in.DropLabels != nil { + in, out := &in.DropLabels, &out.DropLabels + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BYOOWorkloadMetricsConfig. +func (in *BYOOWorkloadMetricsConfig) DeepCopy() *BYOOWorkloadMetricsConfig { + if in == nil { + return nil + } + out := new(BYOOWorkloadMetricsConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Config) DeepCopyInto(out *Config) { *out = *in diff --git a/src/libraries/go/lib/pkg/types/nvca/config/config_test.go b/src/libraries/go/lib/pkg/types/nvca/config/config_test.go index 716d45935..fcb1751bb 100644 --- a/src/libraries/go/lib/pkg/types/nvca/config/config_test.go +++ b/src/libraries/go/lib/pkg/types/nvca/config/config_test.go @@ -397,6 +397,27 @@ agent: assert.Equal(t, ":8080", cfg.Agent.SvcAddress) }) + t.Run("byoo_metric_subset", func(t *testing.T) { + data := []byte(` +agent: + byooMetricSubset: + enabled: true + filterConfig: | + error_mode: ignore + metric_conditions: + - 'metric.name == "drop"' + byooWorkloadMetrics: + dropLabels: + - metric_subset_enabled + - custom_label +`) + cfg, err := DecodeConfig(data) + require.NoError(t, err) + assert.True(t, cfg.Agent.BYOOMetricSubset.Enabled) + assert.Contains(t, cfg.Agent.BYOOMetricSubset.FilterConfig, "metric.name") + assert.Equal(t, []string{"metric_subset_enabled", "custom_label"}, cfg.Agent.BYOOWorkloadMetrics.DropLabels) + }) + t.Run("duration_parsing", func(t *testing.T) { data := []byte(` agent: diff --git a/src/libraries/go/lib/pkg/types/nvca/config/deepcopy_test.go b/src/libraries/go/lib/pkg/types/nvca/config/deepcopy_test.go index f6d26ade3..221266f13 100644 --- a/src/libraries/go/lib/pkg/types/nvca/config/deepcopy_test.go +++ b/src/libraries/go/lib/pkg/types/nvca/config/deepcopy_test.go @@ -69,6 +69,30 @@ func TestDeepCopy_AgentConfig_Nil(t *testing.T) { assert.Nil(t, out) } +func TestDeepCopy_BYOOMetricSubsetConfig(t *testing.T) { + orig := &BYOOMetricSubsetConfig{ + Enabled: true, + FilterConfig: "error_mode: ignore", + } + out := orig.DeepCopy() + require.NotNil(t, out) + assert.NotSame(t, orig, out) + assert.Equal(t, orig.Enabled, out.Enabled) + assert.Equal(t, orig.FilterConfig, out.FilterConfig) +} + +func TestDeepCopy_BYOOWorkloadMetricsConfig(t *testing.T) { + orig := &BYOOWorkloadMetricsConfig{ + DropLabels: []string{"metric_subset_enabled", "custom_label"}, + } + out := orig.DeepCopy() + require.NotNil(t, out) + assert.Equal(t, orig.DropLabels, out.DropLabels) + + orig.DropLabels[0] = "changed" + assert.Equal(t, "metric_subset_enabled", out.DropLabels[0]) +} + func TestDeepCopy_AllowedExtraKubernetesTypeConfig(t *testing.T) { orig := &AllowedExtraKubernetesTypeConfig{Group: "apps", Version: "v1", Kind: "Deployment", Resource: "deployments"} out := orig.DeepCopy() diff --git a/src/libraries/go/lib/pkg/types/nvca/config/types.go b/src/libraries/go/lib/pkg/types/nvca/config/types.go index b9c30627c..19a148224 100644 --- a/src/libraries/go/lib/pkg/types/nvca/config/types.go +++ b/src/libraries/go/lib/pkg/types/nvca/config/types.go @@ -19,6 +19,7 @@ import ( "fmt" "reflect" "strconv" + "strings" "time" "github.com/go-viper/mapstructure/v2" @@ -58,6 +59,12 @@ const ( BYOOLogChunkDryRunEnv = "BYOO_LOG_CHUNK_DRY_RUN" // BYOOLogExporterBatchMaxSizeBytesEnv is the BYOO collector env var for exporterhelper byte batch splitting. BYOOLogExporterBatchMaxSizeBytesEnv = "BYOO_LOG_EXPORTER_BATCH_MAX_SIZE_BYTES" + // BYOOMetricSubsetEnabledEnv is the BYOO collector env var that enables the metric subset pipeline. + BYOOMetricSubsetEnabledEnv = "BYOO_METRIC_SUBSET_ENABLED" + // BYOOMetricSubsetFilterConfigEnv is the BYOO collector env var for metric subset filter config YAML. + BYOOMetricSubsetFilterConfigEnv = "BYOO_METRIC_SUBSET_FILTER_CONFIG" + // BYOOWorkloadMetricsDropLabelsEnv is the BYOO collector env var for workload metrics resource labels to drop. + BYOOWorkloadMetricsDropLabelsEnv = "BYOO_WORKLOAD_METRICS_DROP_LABELS" // DefaultBYOOLogExporterBatchMaxSizeBytes keeps serialized exporter batches near the backend limit. DefaultBYOOLogExporterBatchMaxSizeBytes int64 = 1000000 @@ -110,6 +117,51 @@ func BYOOLogChunkingEnvVars(config BYOOLogChunkingConfig) []corev1.EnvVar { return config.EnvVars() } +type BYOOMetricSubsetConfig struct { + Enabled bool `yaml:"enabled,omitempty"` + FilterConfig string `yaml:"filterConfig,omitempty"` +} + +func (c BYOOMetricSubsetConfig) IsZero() bool { + return !c.Enabled && c.FilterConfig == "" +} + +// EnvVars returns BYOO collector env vars for the supplied metric subset config. +func (c BYOOMetricSubsetConfig) EnvVars() []corev1.EnvVar { + envs := []corev1.EnvVar{} + if c.Enabled { + envs = append(envs, corev1.EnvVar{ + Name: BYOOMetricSubsetEnabledEnv, + Value: strconv.FormatBool(c.Enabled), + }) + } + if c.FilterConfig != "" { + envs = append(envs, corev1.EnvVar{ + Name: BYOOMetricSubsetFilterConfigEnv, + Value: c.FilterConfig, + }) + } + return envs +} + +type BYOOWorkloadMetricsConfig struct { + DropLabels []string `yaml:"dropLabels,omitempty"` +} + +func (c BYOOWorkloadMetricsConfig) IsZero() bool { + return len(c.DropLabels) == 0 +} + +func (c BYOOWorkloadMetricsConfig) EnvVars() []corev1.EnvVar { + if len(c.DropLabels) == 0 { + return nil + } + return []corev1.EnvVar{{ + Name: BYOOWorkloadMetricsDropLabelsEnv, + Value: strings.Join(c.DropLabels, ","), + }} +} + func (r *ResourceRequirements) ToK8sResourceRequirements() corev1.ResourceRequirements { return corev1.ResourceRequirements{ Limits: corev1.ResourceList(r.Limits), @@ -340,6 +392,12 @@ type AgentConfig struct { // BYOOLogChunking contains BYOO OTel collector log chunking and exporter batch settings. BYOOLogChunking BYOOLogChunkingConfig `yaml:",omitempty"` + + // BYOOMetricSubset contains BYOO OTel collector metric subset pipeline settings. + BYOOMetricSubset BYOOMetricSubsetConfig `yaml:"byooMetricSubset,omitempty"` + + // BYOOWorkloadMetrics contains settings for the generated workload metrics pipeline. + BYOOWorkloadMetrics BYOOWorkloadMetricsConfig `yaml:"byooWorkloadMetrics,omitempty"` } func (t AgentConfig) Complete(env Environment) AgentConfig { @@ -352,6 +410,13 @@ func (t AgentConfig) Complete(env Environment) AgentConfig { return t } +// BYOOOTelCollectorEnvVars returns env vars that must be set only on the BYOO OTel collector container. +func (t AgentConfig) BYOOOTelCollectorEnvVars() []corev1.EnvVar { + envs := t.BYOOLogChunking.EnvVars() + envs = append(envs, t.BYOOMetricSubset.EnvVars()...) + return append(envs, t.BYOOWorkloadMetrics.EnvVars()...) +} + const ( defaultCredRenewInterval = 45 * time.Minute defaultHeartbeatInterval = 5 * time.Minute diff --git a/src/libraries/go/lib/pkg/types/nvca/config/types_test.go b/src/libraries/go/lib/pkg/types/nvca/config/types_test.go index 2f4b87740..b06c1bc77 100644 --- a/src/libraries/go/lib/pkg/types/nvca/config/types_test.go +++ b/src/libraries/go/lib/pkg/types/nvca/config/types_test.go @@ -86,6 +86,52 @@ func TestAgentConfig_Complete(t *testing.T) { }) } +func TestBYOOMetricSubsetConfig_EnvVars(t *testing.T) { + cfg := BYOOMetricSubsetConfig{ + Enabled: true, + FilterConfig: "error_mode: ignore\nmetric_conditions:\n - 'metric.name == \"drop\"'\n", + } + + assert.Equal(t, []corev1.EnvVar{ + {Name: BYOOMetricSubsetEnabledEnv, Value: "true"}, + {Name: BYOOMetricSubsetFilterConfigEnv, Value: "error_mode: ignore\nmetric_conditions:\n - 'metric.name == \"drop\"'\n"}, + }, cfg.EnvVars()) +} + +func TestBYOOWorkloadMetricsConfig_EnvVars(t *testing.T) { + cfg := BYOOWorkloadMetricsConfig{ + DropLabels: []string{"metric_subset_enabled", "custom_label"}, + } + assert.Equal(t, []corev1.EnvVar{{ + Name: BYOOWorkloadMetricsDropLabelsEnv, + Value: "metric_subset_enabled,custom_label", + }}, cfg.EnvVars()) + assert.Nil(t, BYOOWorkloadMetricsConfig{}.EnvVars()) +} + +func TestAgentConfig_BYOOOTelCollectorEnvVars(t *testing.T) { + exporterBatchMaxSizeBytes := int64(1000000) + cfg := AgentConfig{ + BYOOLogChunking: BYOOLogChunkingConfig{ + MaxBodyBytes: 983040, + ExporterBatchMaxSizeBytes: &exporterBatchMaxSizeBytes, + }, + BYOOMetricSubset: BYOOMetricSubsetConfig{ + Enabled: true, + }, + BYOOWorkloadMetrics: BYOOWorkloadMetricsConfig{ + DropLabels: []string{"metric_subset_enabled"}, + }, + } + + assert.Equal(t, []corev1.EnvVar{ + {Name: BYOOLogChunkMaxBodyBytesEnv, Value: "983040"}, + {Name: BYOOLogExporterBatchMaxSizeBytesEnv, Value: "1000000"}, + {Name: BYOOMetricSubsetEnabledEnv, Value: "true"}, + {Name: BYOOWorkloadMetricsDropLabelsEnv, Value: "metric_subset_enabled"}, + }, cfg.BYOOOTelCollectorEnvVars()) +} + func TestAgentTimeConfig_Complete(t *testing.T) { t.Run("sets_all_defaults", func(t *testing.T) { cfg := AgentTimeConfig{} diff --git a/src/libraries/go/lib/pkg/types/nvca/config/zz_generated.deepcopy.go b/src/libraries/go/lib/pkg/types/nvca/config/zz_generated.deepcopy.go index 5e7b6d3d9..f13411198 100644 --- a/src/libraries/go/lib/pkg/types/nvca/config/zz_generated.deepcopy.go +++ b/src/libraries/go/lib/pkg/types/nvca/config/zz_generated.deepcopy.go @@ -71,6 +71,8 @@ func (in *AgentConfig) DeepCopyInto(out *AgentConfig) { in.BYOOResources.DeepCopyInto(&out.BYOOResources) in.BYOOFluentBitResources.DeepCopyInto(&out.BYOOFluentBitResources) in.BYOOLogChunking.DeepCopyInto(&out.BYOOLogChunking) + out.BYOOMetricSubset = in.BYOOMetricSubset + in.BYOOWorkloadMetrics.DeepCopyInto(&out.BYOOWorkloadMetrics) return } @@ -153,6 +155,43 @@ func (in *BYOOLogChunkingConfig) DeepCopy() *BYOOLogChunkingConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BYOOMetricSubsetConfig) DeepCopyInto(out *BYOOMetricSubsetConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BYOOMetricSubsetConfig. +func (in *BYOOMetricSubsetConfig) DeepCopy() *BYOOMetricSubsetConfig { + if in == nil { + return nil + } + out := new(BYOOMetricSubsetConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BYOOWorkloadMetricsConfig) DeepCopyInto(out *BYOOWorkloadMetricsConfig) { + *out = *in + if in.DropLabels != nil { + in, out := &in.DropLabels, &out.DropLabels + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BYOOWorkloadMetricsConfig. +func (in *BYOOWorkloadMetricsConfig) DeepCopy() *BYOOWorkloadMetricsConfig { + if in == nil { + return nil + } + out := new(BYOOWorkloadMetricsConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Config) DeepCopyInto(out *Config) { *out = *in