From 0b2f6d0d8923831d859192f7958b0cd23a1f3af7 Mon Sep 17 00:00:00 2001 From: Zakhar Bessarab Date: Thu, 12 Jan 2023 10:50:34 +0400 Subject: [PATCH] lib/promscrape/discovery/dockerswarm: fix discovery filters being applied to all objects (#3632) * lib/promscrape/discovery/dockerswarm: fix discovery filters being applied to all objects Signed-off-by: Zakhar Bessarab * Update docs/CHANGELOG.md Signed-off-by: Zakhar Bessarab Co-authored-by: Aliaksandr Valialkin --- docs/CHANGELOG.md | 1 + lib/promscrape/discovery/dockerswarm/api.go | 8 ++++++-- lib/promscrape/discovery/dockerswarm/dockerswarm.go | 12 +++++++++--- lib/promscrape/discovery/dockerswarm/network.go | 2 +- lib/promscrape/discovery/dockerswarm/nodes.go | 7 ++++++- lib/promscrape/discovery/dockerswarm/services.go | 7 ++++++- lib/promscrape/discovery/dockerswarm/tasks.go | 7 ++++++- 7 files changed, 35 insertions(+), 9 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index cf5b5be55..8df5f94b6 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -15,6 +15,7 @@ The following tip changes can be tested by building VictoriaMetrics components f ## v1.79.x long-time support release (LTS) +* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): [dockerswarm_sd_configs](https://docs.victoriametrics.com/sd_configs.html#dockerswarm_sd_configs): apply `filters` only to objects of the specified `role`. Previously filters were applied to all the objects, which could cause errors when different types of objects were used with filters that were not compatible with them. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3579). * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): suppress all the scrape errors when `-promscrape.suppressScrapeErrors` is enabled. Previously some scrape errors were logged even if `-promscrape.suppressScrapeErrors` flag was set. * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): consistently put the scrape url with scrape target labels to all error logs for failed scrapes. Previously some failed scrapes were logged without this information. * BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): properly parse `M` and `Mi` suffixes as `1e6` multipliers in `1M` and `1Mi` numeric constants. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3664). The issue has been introduced in [v1.79.7](https://docs.victoriametrics.com/CHANGELOG.html#v1797). diff --git a/lib/promscrape/discovery/dockerswarm/api.go b/lib/promscrape/discovery/dockerswarm/api.go index 35d2ab974..ef33775ba 100644 --- a/lib/promscrape/discovery/dockerswarm/api.go +++ b/lib/promscrape/discovery/dockerswarm/api.go @@ -16,6 +16,9 @@ type apiConfig struct { client *discoveryutils.Client port int + // role is the type of objects to discover. + role string + // filtersQueryArg contains escaped `filters` query arg to add to each request to Docker Swarm API. filtersQueryArg string } @@ -49,11 +52,12 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) { return nil, fmt.Errorf("cannot create HTTP client for %q: %w", sdc.Host, err) } cfg.client = client + cfg.role = sdc.Role return cfg, nil } -func (cfg *apiConfig) getAPIResponse(path string) ([]byte, error) { - if len(cfg.filtersQueryArg) > 0 { +func (cfg *apiConfig) getAPIResponse(path, filtersQueryArg string) ([]byte, error) { + if len(filtersQueryArg) > 0 { separator := "?" if strings.Contains(path, "?") { separator = "&" diff --git a/lib/promscrape/discovery/dockerswarm/dockerswarm.go b/lib/promscrape/discovery/dockerswarm/dockerswarm.go index 133d9b2e0..77345a307 100644 --- a/lib/promscrape/discovery/dockerswarm/dockerswarm.go +++ b/lib/promscrape/discovery/dockerswarm/dockerswarm.go @@ -14,6 +14,12 @@ var SDCheckInterval = flag.Duration("promscrape.dockerswarmSDCheckInterval", 30* "This works only if dockerswarm_sd_configs is configured in '-promscrape.config' file. "+ "See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#dockerswarm_sd_config for details") +const ( + roleTasks = "tasks" + roleServices = "services" + roleNodes = "nodes" +) + // SDConfig represents docker swarm service discovery configuration // // See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#dockerswarm_sd_config @@ -42,11 +48,11 @@ func (sdc *SDConfig) GetLabels(baseDir string) ([]map[string]string, error) { return nil, fmt.Errorf("cannot get API config: %w", err) } switch sdc.Role { - case "tasks": + case roleTasks: return getTasksLabels(cfg) - case "services": + case roleServices: return getServicesLabels(cfg) - case "nodes": + case roleNodes: return getNodesLabels(cfg) default: return nil, fmt.Errorf("unexpected `role`: %q; must be one of `tasks`, `services` or `nodes`; skipping it", sdc.Role) diff --git a/lib/promscrape/discovery/dockerswarm/network.go b/lib/promscrape/discovery/dockerswarm/network.go index 27bb748cb..578d1f6b5 100644 --- a/lib/promscrape/discovery/dockerswarm/network.go +++ b/lib/promscrape/discovery/dockerswarm/network.go @@ -27,7 +27,7 @@ func getNetworksLabelsByNetworkID(cfg *apiConfig) (map[string]map[string]string, } func getNetworks(cfg *apiConfig) ([]network, error) { - resp, err := cfg.getAPIResponse("/networks") + resp, err := cfg.getAPIResponse("/networks", "") if err != nil { return nil, fmt.Errorf("cannot query dockerswarm api for networks: %w", err) } diff --git a/lib/promscrape/discovery/dockerswarm/nodes.go b/lib/promscrape/discovery/dockerswarm/nodes.go index c6db715f2..e3c85be2f 100644 --- a/lib/promscrape/discovery/dockerswarm/nodes.go +++ b/lib/promscrape/discovery/dockerswarm/nodes.go @@ -46,7 +46,12 @@ func getNodesLabels(cfg *apiConfig) ([]map[string]string, error) { } func getNodes(cfg *apiConfig) ([]node, error) { - resp, err := cfg.getAPIResponse("/nodes") + filtersQueryArg := "" + if cfg.role == roleNodes { + filtersQueryArg = cfg.filtersQueryArg + } + + resp, err := cfg.getAPIResponse("/nodes", filtersQueryArg) if err != nil { return nil, fmt.Errorf("cannot query dockerswarm api for nodes: %w", err) } diff --git a/lib/promscrape/discovery/dockerswarm/services.go b/lib/promscrape/discovery/dockerswarm/services.go index 5c26ad167..56d2a504e 100644 --- a/lib/promscrape/discovery/dockerswarm/services.go +++ b/lib/promscrape/discovery/dockerswarm/services.go @@ -59,7 +59,12 @@ func getServicesLabels(cfg *apiConfig) ([]map[string]string, error) { } func getServices(cfg *apiConfig) ([]service, error) { - data, err := cfg.getAPIResponse("/services") + filtersQueryArg := "" + if cfg.role == roleServices { + filtersQueryArg = cfg.filtersQueryArg + } + + data, err := cfg.getAPIResponse("/services", filtersQueryArg) if err != nil { return nil, fmt.Errorf("cannot query dockerswarm api for services: %w", err) } diff --git a/lib/promscrape/discovery/dockerswarm/tasks.go b/lib/promscrape/discovery/dockerswarm/tasks.go index d58953763..01ad64cd0 100644 --- a/lib/promscrape/discovery/dockerswarm/tasks.go +++ b/lib/promscrape/discovery/dockerswarm/tasks.go @@ -61,7 +61,12 @@ func getTasksLabels(cfg *apiConfig) ([]map[string]string, error) { } func getTasks(cfg *apiConfig) ([]task, error) { - resp, err := cfg.getAPIResponse("/tasks") + filtersQueryArg := "" + if cfg.role == roleTasks { + filtersQueryArg = cfg.filtersQueryArg + } + + resp, err := cfg.getAPIResponse("/tasks", filtersQueryArg) if err != nil { return nil, fmt.Errorf("cannot query dockerswarm api for tasks: %w", err) }