From df0ed1fca417f18a6076050a1d0a115af8f46dcb Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Larsen Date: Wed, 4 Nov 2020 20:40:53 +0100 Subject: [PATCH] Use labels for mapping metric types to metrics (#219) * Use labels for mapping metric types to metrics Signed-off-by: Mikkel Oscar Lyderik Larsen * Log warning when old format is used Signed-off-by: Mikkel Oscar Lyderik Larsen * Test NewCollector logic for external metrics Signed-off-by: Mikkel Oscar Lyderik Larsen --- README.md | 74 +++++++------ example/deploy/hpa.yaml | 5 +- pkg/annotations/parser.go | 6 +- pkg/collector/collector.go | 33 ++++-- pkg/collector/collector_test.go | 129 +++++++++++++++++++++++ pkg/collector/http_collector.go | 3 +- pkg/collector/influxdb_collector.go | 3 +- pkg/collector/influxdb_collector_test.go | 6 +- pkg/collector/pod_collector.go | 4 +- pkg/collector/pod_collector_test.go | 2 +- pkg/collector/prometheus_collector.go | 3 +- pkg/collector/zmon_collector.go | 12 +-- pkg/collector/zmon_collector_test.go | 20 ++-- pkg/server/start.go | 8 +- 14 files changed, 227 insertions(+), 81 deletions(-) create mode 100644 pkg/collector/collector_test.go diff --git a/README.md b/README.md index 7694ad5..177f5f0 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ kind: HorizontalPodAutoscaler metadata: name: myapp-hpa annotations: - # metric-config.../ + # metric-config.../ metric-config.pods.requests-per-second.json-path/json-key: "$.http_server.rps" metric-config.pods.requests-per-second.json-path/path: /metrics metric-config.pods.requests-per-second.json-path/port: "9090" @@ -104,7 +104,7 @@ kind: HorizontalPodAutoscaler metadata: name: myapp-hpa annotations: - # metric-config.../ + # metric-config.../ metric-config.pods.requests-per-second.json-path/json-key: "$.http_server.rps" metric-config.pods.requests-per-second.json-path/path: /metrics metric-config.pods.requests-per-second.json-path/port: "9090" @@ -216,11 +216,10 @@ Default is 1 minute. This is an example of an HPA configured to get metrics based on a Prometheus query. The query is defined in the annotation -`metric-config.external.prometheus-query.prometheus/processed-events-per-second` +`metric-config.external.processed-events-per-second.prometheus/query` where `processed-events-per-second` is the query name which will be associated -with the result of the query. A matching `query-name` label must be defined in -the `matchLabels` of the metric definition. This allows having multiple -prometheus queries associated with a single HPA. +with the result of the query. +This allows having multiple prometheus queries associated with a single HPA. ```yaml apiVersion: autoscaling/v2beta2 @@ -231,10 +230,9 @@ metadata: # This annotation is optional. # If specified, then this prometheus server is used, # instead of the prometheus server specified as the CLI argument `--prometheus-server`. - metric-config.external.prometheus-query.prometheus/prometheus-server: http://prometheus.my-namespace.svc - # metric-config.../ - # == query-name - metric-config.external.prometheus-query.prometheus/processed-events-per-second: | + metric-config.external.processed-events-per-second.prometheus/prometheus-server: http://prometheus.my-namespace.svc + # metric-config.../ + metric-config.external.processed-events-per-second.prometheus/query: | scalar(sum(rate(event-service_events_count{application="event-service",processed="true"}[1m]))) spec: scaleTargetRef: @@ -247,10 +245,10 @@ spec: - type: External external: metric: - name: prometheus-query + name: processed-events-per-second selector: matchLabels: - query-name: processed-events-per-second + type: prometheus target: type: AverageValue averageValue: "10" @@ -281,7 +279,7 @@ kind: HorizontalPodAutoscaler metadata: name: myapp-hpa annotations: - # metric-config.../ + # metric-config.../ metric-config.object.processed-events-per-second.prometheus/query: | scalar(sum(rate(event-service_events_count{application="event-service",processed="true"}[1m]))) metric-config.object.processed-events-per-second.prometheus/per-replica: "true" @@ -382,10 +380,9 @@ we only support Flux instead of InfluxQL. This is an example of an HPA configured to get metrics based on a Flux query. The query is defined in the annotation -`metric-config.external.flux-query.influxdb/queue_depth` -where `queue_depth` is the query name which will be associated with the result of the query. -A matching `query-name` label must be defined in the `matchLabels` of the metric definition. -This allows having multiple flux queries associated with a single HPA. +`metric-config.external..influxdb/query` where `` is +the query name which will be associated with the result of the query. This +allows having multiple flux queries associated with a single HPA. ```yaml apiVersion: autoscaling/v2beta2 @@ -399,13 +396,13 @@ metadata: # - --influxdb-address # - --influxdb-token # - --influxdb-org - metric-config.external.flux-query.influxdb/address: "http://influxdbv2.my-namespace.svc" - metric-config.external.flux-query.influxdb/token: "secret-token" + metric-config.external.queue-depth.influxdb/address: "http://influxdbv2.my-namespace.svc" + metric-config.external.queue-depth.influxdb/token: "secret-token" # This could be either the organization name or the ID. - metric-config.external.flux-query.influxdb/org: "deadbeef" - # metric-config.../ + metric-config.external.queue-depth.influxdb/org: "deadbeef" + # metric-config.../ # == query-name - metric-config.external.flux-query.influxdb/queue_depth: | + metric-config.external.queue-depth.influxdb/query: | from(bucket: "apps") |> range(start: -30s) |> filter(fn: (r) => r._measurement == "queue_depth") @@ -425,10 +422,10 @@ spec: - type: External external: metric: - name: flux-query + name: queue-depth selector: matchLabels: - query-name: queue_depth + type: influxdb target: type: Value value: "1" @@ -490,9 +487,10 @@ spec: - type: External external: metric: - name: sqs-queue-length + name: my-sqs selector: matchLabels: + type: sqs-queue-length queue-name: foobar region: eu-central-1 target: @@ -531,9 +529,9 @@ kind: HorizontalPodAutoscaler metadata: name: myapp-hpa annotations: - # metric-config.../ - metric-config.external.zmon-check.zmon/key: "custom.*" - metric-config.external.zmon-check.zmon/tag-application: "my-custom-app-*" + # metric-config.../ + metric-config.external.my-zmon-check.zmon/key: "custom.*" + metric-config.external.my-zmon-check.zmon/tag-application: "my-custom-app-*" spec: scaleTargetRef: apiVersion: apps/v1 @@ -545,9 +543,10 @@ spec: - type: External external: metric: - name: zmon-check + name: my-zmon-check selector: matchLabels: + type: zmon check-id: "1234" # the ZMON check to query for metrics key: "custom.value" tag-application: my-custom-app @@ -597,8 +596,8 @@ specify a duration of `5m` then the query will return metric points for the last 5 minutes and apply the specified aggregation with the same duration .e.g `max(5m)`. -The annotations `metric-config.external.zmon-check.zmon/key` and -`metric-config.external.zmon-check.zmon/tag-` can be optionally used if +The annotations `metric-config.external.my-zmon-check.zmon/key` and +`metric-config.external.my-zmon-check.zmon/tag-` can be optionally used if you need to define a `key` or other `tag` with a "star" query syntax like `values.*`. This *hack* is in place because it's not allowed to use `*` in the metric label definitions. If both annotations and corresponding label is @@ -626,10 +625,10 @@ kind: HorizontalPodAutoscaler metadata: name: myapp-hpa annotations: - # metric-config.../ - metric-config.external.http.json/json-key: "$.some-metric.value" - metric-config.external.http.json/endpoint: "http://metric-source.app-namespace:8080/metrics" - metric-config.external.http.json/aggregator: "max" + # metric-config.../ + metric-config.external.unique-metric-name.json-path/json-key: "$.some-metric.value" + metric-config.external.unique-metric-name.json-path/endpoint: "http://metric-source.app-namespace:8080/metrics" + metric-config.external.unique-metric-name.json-path/aggregator: "max" spec: scaleTargetRef: apiVersion: apps/v1 @@ -641,10 +640,10 @@ spec: - type: External external: metric: - name: http + name: unique-metric-name selector: matchLabels: - identifier: unique-metric-name + type: json-path target: averageValue: 1 type: AverageValue @@ -659,4 +658,3 @@ target. The following configuration values are supported: in the namespace `app-namespace` is called. - `aggregator` is only required if the metric is an array of values and specifies how the values are aggregated. Currently this option can support the values: `sum`, `max`, `min`, `avg`. - diff --git a/example/deploy/hpa.yaml b/example/deploy/hpa.yaml index 522a386..afa4087 100644 --- a/example/deploy/hpa.yaml +++ b/example/deploy/hpa.yaml @@ -6,7 +6,7 @@ metadata: labels: application: custom-metrics-consumer annotations: - # metric-config.../ + # metric-config.../ metric-config.pods.queue-length.json-path/json-key: "$.queue.length" metric-config.pods.queue-length.json-path/path: /metrics metric-config.pods.queue-length.json-path/port: "9090" @@ -50,9 +50,10 @@ spec: - type: External external: metric: - name: sqs-queue-length + name: app-queue-length selector: matchLabels: + type: sqs-queue-length queue-name: foobar region: eu-central-1 target: diff --git a/pkg/annotations/parser.go b/pkg/annotations/parser.go index 5aeeb6e..39b3b82 100644 --- a/pkg/annotations/parser.go +++ b/pkg/annotations/parser.go @@ -15,7 +15,7 @@ const ( ) type AnnotationConfigs struct { - CollectorName string + CollectorType string Configs map[string]string PerReplica bool Interval time.Duration @@ -64,14 +64,14 @@ func (m AnnotationConfigMap) Parse(annotations map[string]string) error { config, ok := m[key] if !ok { config = &AnnotationConfigs{ - CollectorName: metricCollector, + CollectorType: metricCollector, Configs: map[string]string{}, } m[key] = config } // TODO: fail if collector name doesn't match - if config.CollectorName != metricCollector { + if config.CollectorType != metricCollector { continue } diff --git a/pkg/collector/collector.go b/pkg/collector/collector.go index f6d886c..85b942b 100644 --- a/pkg/collector/collector.go +++ b/pkg/collector/collector.go @@ -4,12 +4,17 @@ import ( "fmt" "time" + log "github.com/sirupsen/logrus" "github.com/zalando-incubator/kube-metrics-adapter/pkg/annotations" autoscalingv2 "k8s.io/api/autoscaling/v2beta2" "k8s.io/metrics/pkg/apis/custom_metrics" "k8s.io/metrics/pkg/apis/external_metrics" ) +const ( + typeLabelKey = "type" +) + type ObjectReference struct { autoscalingv2.CrossVersionObjectReference Namespace string @@ -19,6 +24,7 @@ type CollectorFactory struct { podsPlugins pluginMap objectPlugins objectPluginMap externalPlugins map[string]CollectorPlugin + logger *log.Entry } type objectPluginMap struct { @@ -39,6 +45,7 @@ func NewCollectorFactory() *CollectorFactory { Named: map[string]*pluginMap{}, }, externalPlugins: map[string]CollectorPlugin{}, + logger: log.WithFields(log.Fields{"collector": "true"}), } } @@ -112,7 +119,7 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscal switch config.Type { case autoscalingv2.PodsMetricSourceType: // first try to find a plugin by format - if plugin, ok := c.podsPlugins.Named[config.CollectorName]; ok { + if plugin, ok := c.podsPlugins.Named[config.CollectorType]; ok { return plugin.NewCollector(hpa, config, interval) } @@ -123,7 +130,7 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscal case autoscalingv2.ObjectMetricSourceType: // first try to find a plugin by kind if kinds, ok := c.objectPlugins.Named[config.ObjectReference.Kind]; ok { - if plugin, ok := kinds.Named[config.CollectorName]; ok { + if plugin, ok := kinds.Named[config.CollectorType]; ok { return plugin.NewCollector(hpa, config, interval) } @@ -134,7 +141,7 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscal } // else try to find a default plugin for this kind - if plugin, ok := c.objectPlugins.Any.Named[config.CollectorName]; ok { + if plugin, ok := c.objectPlugins.Any.Named[config.CollectorType]; ok { return plugin.NewCollector(hpa, config, interval) } @@ -142,7 +149,21 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscal return c.objectPlugins.Any.Any.NewCollector(hpa, config, interval) } case autoscalingv2.ExternalMetricSourceType: - if plugin, ok := c.externalPlugins[config.Metric.Name]; ok { + // First type to get metric type from the `type` label, + // otherwise fall back to the legacy metric name based mapping. + var pluginKey string + if config.Metric.Selector != nil && config.Metric.Selector.MatchLabels != nil { + if typ, ok := config.Metric.Selector.MatchLabels[typeLabelKey]; ok { + pluginKey = typ + } + } + + if pluginKey == "" { + pluginKey = config.Metric.Name + c.logger.Warnf("HPA %s/%s is using deprecated metric type identifier '%s'", hpa.Namespace, hpa.Name, config.Metric.Name) + } + + if plugin, ok := c.externalPlugins[pluginKey]; ok { return plugin.NewCollector(hpa, config, interval) } } @@ -168,7 +189,7 @@ type Collector interface { type MetricConfig struct { MetricTypeName - CollectorName string + CollectorType string Config map[string]string ObjectReference custom_metrics.ObjectReference PerReplica bool @@ -228,7 +249,7 @@ func ParseHPAMetrics(hpa *autoscalingv2.HorizontalPodAutoscaler) ([]*MetricConfi annotationConfigs, present := parser.GetAnnotationConfig(typeName.Metric.Name, typeName.Type) if present { - config.CollectorName = annotationConfigs.CollectorName + config.CollectorType = annotationConfigs.CollectorType config.Interval = annotationConfigs.Interval config.PerReplica = annotationConfigs.PerReplica // configs specified in annotations takes precedence diff --git a/pkg/collector/collector_test.go b/pkg/collector/collector_test.go new file mode 100644 index 0000000..821d471 --- /dev/null +++ b/pkg/collector/collector_test.go @@ -0,0 +1,129 @@ +package collector + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + autoscalingv2 "k8s.io/api/autoscaling/v2beta2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type mockCollectorPlugin struct { + Name string +} + +func (c *mockCollectorPlugin) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) { + return &mockCollector{Name: c.Name}, nil +} + +type mockCollector struct { + Name string +} + +func (c *mockCollector) GetMetrics() ([]CollectedMetric, error) { + return nil, nil +} + +func (c *mockCollector) Interval() time.Duration { + return 0 +} + +func TestNewCollector(t *testing.T) { + for _, tc := range []struct { + msg string + hpa *autoscalingv2.HorizontalPodAutoscaler + expectedCollector string + }{ + { + msg: "should get create collector type from legacy metric name", + hpa: &autoscalingv2.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + }, + Spec: autoscalingv2.HorizontalPodAutoscalerSpec{ + Metrics: []autoscalingv2.MetricSpec{ + { + Type: autoscalingv2.ExternalMetricSourceType, + External: &autoscalingv2.ExternalMetricSource{ + Metric: autoscalingv2.MetricIdentifier{ + Name: "external-1", + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"x": "y"}, + }, + }, + }, + }, + }, + }, + }, + expectedCollector: "external-1", + }, + { + msg: "should get create collector type from type label (ignore legacy metric name)", + hpa: &autoscalingv2.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + }, + Spec: autoscalingv2.HorizontalPodAutoscalerSpec{ + Metrics: []autoscalingv2.MetricSpec{ + { + Type: autoscalingv2.ExternalMetricSourceType, + External: &autoscalingv2.ExternalMetricSource{ + Metric: autoscalingv2.MetricIdentifier{ + Name: "external-1", + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"type": "external-2"}, + }, + }, + }, + }, + }, + }, + }, + expectedCollector: "external-2", + }, + { + msg: "should not find collector when no collector matches", + hpa: &autoscalingv2.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + }, + Spec: autoscalingv2.HorizontalPodAutoscalerSpec{ + Metrics: []autoscalingv2.MetricSpec{ + { + Type: autoscalingv2.ExternalMetricSourceType, + External: &autoscalingv2.ExternalMetricSource{ + Metric: autoscalingv2.MetricIdentifier{ + Name: "external-3", + }, + }, + }, + }, + }, + }, + expectedCollector: "", + }, + } { + t.Run(tc.msg, func(t *testing.T) { + collectorFactory := NewCollectorFactory() + for _, collector := range []string{"1", "2"} { + collectorFactory.RegisterExternalCollector([]string{"external-" + collector}, &mockCollectorPlugin{Name: "external-" + collector}) + } + configs, err := ParseHPAMetrics(tc.hpa) + require.NoError(t, err) + require.Len(t, configs, 1) + + collector, err := collectorFactory.NewCollector(tc.hpa, configs[0], 0) + if tc.expectedCollector == "" { + require.Error(t, err) + } else { + require.NoError(t, err) + + c, ok := collector.(*mockCollector) + require.True(t, ok) + require.Equal(t, tc.expectedCollector, c.Name) + } + }) + } +} diff --git a/pkg/collector/http_collector.go b/pkg/collector/http_collector.go index 1e4ce57..1987c25 100644 --- a/pkg/collector/http_collector.go +++ b/pkg/collector/http_collector.go @@ -14,7 +14,8 @@ import ( ) const ( - HTTPMetricName = "http" + HTTPJSONPathType = "json-path" + HTTPMetricNameLegacy = "http" HTTPEndpointAnnotationKey = "endpoint" HTTPJsonPathAnnotationKey = "json-key" identifierLabel = "identifier" diff --git a/pkg/collector/influxdb_collector.go b/pkg/collector/influxdb_collector.go index c7d079a..8acdedc 100644 --- a/pkg/collector/influxdb_collector.go +++ b/pkg/collector/influxdb_collector.go @@ -15,7 +15,8 @@ import ( ) const ( - InfluxDBMetricName = "flux-query" + InfluxDBMetricType = "influxdb" + InfluxDBMetricNameLegacy = "flux-query" influxDBAddressKey = "address" influxDBTokenKey = "token" influxDBOrgKey = "org" diff --git a/pkg/collector/influxdb_collector_test.go b/pkg/collector/influxdb_collector_test.go index 454677c..cf67d22 100644 --- a/pkg/collector/influxdb_collector_test.go +++ b/pkg/collector/influxdb_collector_test.go @@ -24,7 +24,7 @@ func TestInfluxDBCollector_New(t *testing.T) { }, }, }, - CollectorName: "influxdb", + CollectorType: "influxdb", Config: map[string]string{ "range1m": `from(bucket: "?") |> range(start: -1m)`, "range2m": `from(bucket: "?") |> range(start: -2m)`, @@ -62,7 +62,7 @@ func TestInfluxDBCollector_New(t *testing.T) { }, }, }, - CollectorName: "influxdb", + CollectorType: "influxdb", Config: map[string]string{ "range1m": `from(bucket: "?") |> range(start: -1m)`, "range2m": `from(bucket: "?") |> range(start: -2m)`, @@ -140,7 +140,7 @@ func TestInfluxDBCollector_New(t *testing.T) { t.Run("error - "+tc.name, func(t *testing.T) { m := &MetricConfig{ MetricTypeName: tc.mTypeName, - CollectorName: "influxdb", + CollectorType: "influxdb", Config: tc.config, } _, err := NewInfluxDBCollector("http://localhost:9999", "secret", "deadbeef", m, time.Second) diff --git a/pkg/collector/pod_collector.go b/pkg/collector/pod_collector.go index 9034145..975e973 100644 --- a/pkg/collector/pod_collector.go +++ b/pkg/collector/pod_collector.go @@ -61,7 +61,7 @@ func NewPodCollector(client kubernetes.Interface, hpa *autoscalingv2.HorizontalP } var getter httpmetrics.PodMetricsGetter - switch config.CollectorName { + switch config.CollectorType { case "json-path": var err error getter, err = httpmetrics.NewPodMetricsJSONPathGetter(config.Config) @@ -69,7 +69,7 @@ func NewPodCollector(client kubernetes.Interface, hpa *autoscalingv2.HorizontalP return nil, err } default: - return nil, fmt.Errorf("format '%s' not supported", config.CollectorName) + return nil, fmt.Errorf("format '%s' not supported", config.CollectorType) } c.Getter = getter diff --git a/pkg/collector/pod_collector_test.go b/pkg/collector/pod_collector_test.go index a718790..c90d394 100644 --- a/pkg/collector/pod_collector_test.go +++ b/pkg/collector/pod_collector_test.go @@ -97,7 +97,7 @@ func makeTestHTTPServer(t *testing.T, values [][]int64) (string, string, *testMe func makeTestConfig(port string) *MetricConfig { return &MetricConfig{ - CollectorName: "json-path", + CollectorType: "json-path", Config: map[string]string{"json-key": "$.values", "port": port, "path": "/metrics", "aggregator": "sum"}, } } diff --git a/pkg/collector/prometheus_collector.go b/pkg/collector/prometheus_collector.go index 82aaec5..702168e 100644 --- a/pkg/collector/prometheus_collector.go +++ b/pkg/collector/prometheus_collector.go @@ -19,7 +19,8 @@ import ( ) const ( - PrometheusMetricName = "prometheus-query" + PrometheusMetricType = "prometheus" + PrometheusMetricNameLegacy = "prometheus-query" prometheusQueryNameLabelKey = "query-name" prometheusServerAnnotationKey = "prometheus-server" ) diff --git a/pkg/collector/zmon_collector.go b/pkg/collector/zmon_collector.go index e80619c..1315895 100644 --- a/pkg/collector/zmon_collector.go +++ b/pkg/collector/zmon_collector.go @@ -14,9 +14,10 @@ import ( ) const ( - // ZMONCheckMetric defines the metric name for metrics based on ZMON + // ZMONMetricType defines the metric type for metrics based on ZMON // checks. - ZMONCheckMetric = "zmon-check" + ZMONMetricType = "zmon" + ZMONCheckMetricLegacy = "zmon-check" zmonCheckIDLabelKey = "check-id" zmonKeyLabelKey = "key" zmonDurationLabelKey = "duration" @@ -42,12 +43,7 @@ func NewZMONCollectorPlugin(zmon zmon.ZMON) (*ZMONCollectorPlugin, error) { // NewCollector initializes a new ZMON collector from the specified HPA. func (c *ZMONCollectorPlugin) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) { - switch config.Metric.Name { - case ZMONCheckMetric: - return NewZMONCollector(c.zmon, config, interval) - } - - return nil, fmt.Errorf("metric '%s' not supported", config.Metric.Name) + return NewZMONCollector(c.zmon, config, interval) } // ZMONCollector defines a collector that is able to collect metrics from ZMON. diff --git a/pkg/collector/zmon_collector_test.go b/pkg/collector/zmon_collector_test.go index 9c8d8d2..2b266e1 100644 --- a/pkg/collector/zmon_collector_test.go +++ b/pkg/collector/zmon_collector_test.go @@ -26,7 +26,7 @@ func TestZMONCollectorNewCollector(t *testing.T) { config := &MetricConfig{ MetricTypeName: MetricTypeName{ - Metric: newMetricIdentifier(ZMONCheckMetric), + Metric: newMetricIdentifier("foo-check", ZMONMetricType), }, Config: map[string]string{ zmonCheckIDLabelKey: "1234", @@ -50,28 +50,26 @@ func TestZMONCollectorNewCollector(t *testing.T) { require.Equal(t, []string{"max"}, zmonCollector.aggregators) require.Equal(t, map[string]string{"alias": "cluster_alias"}, zmonCollector.tags) - // should fail if the metric name isn't ZMON - config.Metric = newMetricIdentifier("non-zmon-check") - _, err = collectPlugin.NewCollector(nil, config, 1*time.Second) - require.Error(t, err) - // should fail if the check id is not specified. delete(config.Config, zmonCheckIDLabelKey) - config.Metric.Name = ZMONCheckMetric + config.Metric.Name = "foo-check" _, err = collectPlugin.NewCollector(nil, config, 1*time.Second) require.Error(t, err) } -func newMetricIdentifier(metricName string) autoscalingv2.MetricIdentifier { - selector := metav1.LabelSelector{} +func newMetricIdentifier(metricName, metricType string) autoscalingv2.MetricIdentifier { + selector := metav1.LabelSelector{ + MatchLabels: map[string]string{ + "type": metricType, + }, + } return autoscalingv2.MetricIdentifier{Name: metricName, Selector: &selector} } func TestZMONCollectorGetMetrics(tt *testing.T) { - config := &MetricConfig{ MetricTypeName: MetricTypeName{ - Metric: newMetricIdentifier(ZMONCheckMetric), + Metric: newMetricIdentifier("foo-check", ZMONMetricType), Type: "foo", }, Config: map[string]string{ diff --git a/pkg/server/start.go b/pkg/server/start.go index b0e6cdd..b2d956d 100644 --- a/pkg/server/start.go +++ b/pkg/server/start.go @@ -174,7 +174,7 @@ func (o AdapterServerOptions) RunCustomMetricsAdapterServer(stopCh <-chan struct return fmt.Errorf("failed to register prometheus object collector plugin: %v", err) } - collectorFactory.RegisterExternalCollector([]string{collector.PrometheusMetricName}, promPlugin) + collectorFactory.RegisterExternalCollector([]string{collector.PrometheusMetricType, collector.PrometheusMetricNameLegacy}, promPlugin) // skipper collector can only be enabled if prometheus is. if o.SkipperIngressMetrics { @@ -195,11 +195,11 @@ func (o AdapterServerOptions) RunCustomMetricsAdapterServer(stopCh <-chan struct if err != nil { return fmt.Errorf("failed to initialize InfluxDB collector plugin: %v", err) } - collectorFactory.RegisterExternalCollector([]string{collector.InfluxDBMetricName}, influxdbPlugin) + collectorFactory.RegisterExternalCollector([]string{collector.InfluxDBMetricType, collector.InfluxDBMetricNameLegacy}, influxdbPlugin) } plugin, _ := collector.NewHTTPCollectorPlugin() - collectorFactory.RegisterExternalCollector([]string{collector.HTTPMetricName}, plugin) + collectorFactory.RegisterExternalCollector([]string{collector.HTTPJSONPathType, collector.HTTPMetricNameLegacy}, plugin) // register generic pod collector err = collectorFactory.RegisterPodsCollector("", collector.NewPodCollectorPlugin(client)) if err != nil { @@ -224,7 +224,7 @@ func (o AdapterServerOptions) RunCustomMetricsAdapterServer(stopCh <-chan struct return fmt.Errorf("failed to initialize ZMON collector plugin: %v", err) } - collectorFactory.RegisterExternalCollector([]string{collector.ZMONCheckMetric}, zmonPlugin) + collectorFactory.RegisterExternalCollector([]string{collector.ZMONMetricType, collector.ZMONCheckMetricLegacy}, zmonPlugin) } awsSessions := make(map[string]*session.Session, len(o.AWSRegions))