From 1f3e93f48e1cffedcd2d0f495c23cfaeea09263c Mon Sep 17 00:00:00 2001 From: Yuri Tsuprun <51751791+pincher95@users.noreply.github.com> Date: Mon, 18 Aug 2025 21:43:53 -0400 Subject: [PATCH 01/21] Add multi-target support (#1063) * Add multi-target support Signed-off-by: pincher95 * Update example-prometheus.yml Signed-off-by: pincher95 * Make `es.uri` optional by setting default to empty string check if it's empty and if so, don't parse it Signed-off-by: pincher95 Signed-off-by: pincher95 * Update README.md Signed-off-by: pincher95 * Add sanity target scheme validation Signed-off-by: pincher95 * Change yaml package to go.yaml.in/yaml/v3 Signed-off-by: pincher95 * Update yaml package to go.yaml.in/yaml/v3 Signed-off-by: pincher95 * Update CHANGELOG.md Signed-off-by: pincher95 * Remove whitespaces from README.md Signed-off-by: pincher95 * Add testing for apikey authentication module Update examples/auth_modules.yml Fix main.go to apply userpass credentials only if the module type is explicitly set to userpass. Signed-off-by: pincher95 * Add Load-time validation for the auth module config file during startup Keep light-weight validation for the probe params during runtime Add AWS SigV4 authentication module support Signed-off-by: pincher95 * Expose error in the logger Signed-off-by: pincher95 * Add TLS config per target support Add TLS config validation Update config test to include TLS config Signed-off-by: pincher95 * Indices and Shards collectors now fetch cluster_name once from GET / when no clusterinfo retriever is attached, avoiding the previous "unknown_cluster" label. Signed-off-by: pincher95 * Removed the special-case logic that redirected /metrics?target= requests to /probe. Updated auth_modules.yml to include AWS SigV4 signing and mTLS support. Signed-off-by: pincher95 * Add license headers to all new files Signed-off-by: pincher95 * Fixes for relative paths in multi-target mode Signed-off-by: pincher95 * Bump github.com/prometheus/client_golang from 1.22.0 to 1.23.0 (#1065) Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.22.0 to 1.23.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.22.0...v1.23.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-version: 1.23.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: pincher95 * Add target schema validation, http/https only Add tls auth type support in multi-target mode Update README.md, examples/auth_modules.yml, tests Signed-off-by: pincher95 * Cleanup Signed-off-by: pincher95 * Fix tls auth type validation Signed-off-by: pincher95 * Remove aws.region validation Signed-off-by: pincher95 * Add temp file cleanup in config_test.go Signed-off-by: pincher95 * Add copyright header to config_test.go Signed-off-by: pincher95 * Add version metric to the per-probe registry Update roundtripper.go to use region from config or environment resolver if not provided in config file (AWS_REGION) Update probe.go to accept module even if region omitted; environment resolver can provide it Update config.go to use region as optional field Update main.go to use region from config or environment resolver if not provided in config file (AWS_REGION) and update roundtripper.go to use region from config or environment resolver if not provided in config file (AWS_REGION) Signed-off-by: pincher95 --------- Signed-off-by: pincher95 Signed-off-by: dependabot[bot] Signed-off-by: Yuri Tsuprun <51751791+pincher95@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: pincher95 --- CHANGELOG.md | 5 + README.md | 64 ++++++- collector/indices.go | 24 ++- collector/shards.go | 38 +++- config/config.go | 137 +++++++++++++ config/config_test.go | 183 ++++++++++++++++++ examples/auth_modules.yml | 55 ++++++ examples/example-prometheus.yml | 33 ++++ go.mod | 5 +- go.sum | 2 + main.go | 320 ++++++++++++++++++++++--------- pkg/roundtripper/roundtripper.go | 7 +- probe.go | 78 ++++++++ probe_test.go | 126 ++++++++++++ 14 files changed, 974 insertions(+), 103 deletions(-) create mode 100644 config/config.go create mode 100644 config/config_test.go create mode 100644 examples/auth_modules.yml create mode 100644 examples/example-prometheus.yml create mode 100644 probe.go create mode 100644 probe_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 67d0bfec..98bd0508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ ## master / unreleased +### Added +- Multi-target scraping via `/probe` endpoint with optional auth modules (compatible with postgres_exporter style) #1063 + BREAKING CHANGES: +* [CHANGE] Set `--es.uri` by default to empty string #1063 + The flag `--es.data_stream` has been renamed to `--collector.data-stream`. The flag `--es.ilm` has been renamed to `--collector.ilm`. diff --git a/README.md b/README.md index f813534d..08bd9851 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ elasticsearch_exporter --help | Argument | Introduced in Version | Description | Default | | ----------------------- | --------------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ----------- | | collector.clustersettings| 1.6.0 | If true, query stats for cluster settings (As of v1.6.0, this flag has replaced "es.cluster_settings"). | false | -| es.uri | 1.0.2 | Address (host and port) of the Elasticsearch node we should connect to. This could be a local node (`localhost:9200`, for instance), or the address of a remote Elasticsearch server. When basic auth is needed, specify as: `://:@:`. E.G., `http://admin:pass@localhost:9200`. Special characters in the user credentials need to be URL-encoded. | | +| es.uri | 1.0.2 | Address (host and port) of the Elasticsearch node we should connect to **when running in single-target mode**. Leave empty (the default) when you want to run the exporter only as a multi-target `/probe` endpoint. When basic auth is needed, specify as: `://:@:`. E.G., `http://admin:pass@localhost:9200`. Special characters in the user credentials need to be URL-encoded. | "" | | es.all | 1.0.2 | If true, query stats for all nodes in the cluster, rather than just the node we connect to. | false | | es.indices | 1.0.2 | If true, query stats for all indices in the cluster. | false | | es.indices_settings | 1.0.4rc1 | If true, query settings stats for all indices in the cluster. | false | @@ -77,6 +77,7 @@ elasticsearch_exporter --help | web.telemetry-path | 1.0.2 | Path under which to expose metrics. | /metrics | | aws.region | 1.5.0 | Region for AWS elasticsearch | | | aws.role-arn | 1.6.0 | Role ARN of an IAM role to assume. | | +| config.file | 2.0.0 | Path to a YAML configuration file that defines `auth_modules:` used by the `/probe` multi-target endpoint. Leave unset when not using multi-target mode. | | | version | 1.0.2 | Show version info on stdout and exit. | | Commandline parameters start with a single `-` for versions less than `1.1.0rc1`. @@ -113,6 +114,67 @@ Further Information - [Defining Roles](https://www.elastic.co/guide/en/elastic-stack-overview/7.3/defining-roles.html) - [Privileges](https://www.elastic.co/guide/en/elastic-stack-overview/7.3/security-privileges.html) +### Multi-Target Scraping (beta) + +From v2.X the exporter exposes `/probe` allowing one running instance to scrape many clusters. + +Supported `auth_module` types: + +| type | YAML fields | Injected into request | +| ---------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| `userpass` | `userpass.username`, `userpass.password`, optional `options:` map | Sets HTTP basic-auth header, appends `options` as query parameters | +| `apikey` | `apikey:` Base64 API-Key string, optional `options:` map | Adds `Authorization: ApiKey …` header, appends `options` | +| `aws` | `aws.region`, optional `aws.role_arn`, optional `options:` map | Uses AWS SigV4 signing transport for HTTP(S) requests, appends `options` | +| `tls` | `tls.ca_file`, `tls.cert_file`, `tls.key_file` | Uses client certificate authentication via TLS; cannot be mixed with other auth types | + +Example config: + +```yaml +# exporter-config.yml +auth_modules: + prod_basic: + type: userpass + userpass: + username: metrics + password: s3cr3t + + staging_key: + type: apikey + apikey: "bXk6YXBpa2V5Ig==" # base64 id:key + options: + sslmode: disable +``` + +Run exporter: + +```bash +./elasticsearch_exporter --config.file=exporter-config.yml +``` + +Prometheus scrape_config: + +```yaml +- job_name: es + metrics_path: /probe + params: + auth_module: [staging_key] + static_configs: + - targets: ["https://es-stage:9200"] + relabel_configs: + - source_labels: [__address__] + target_label: __param_target + - source_labels: [__param_target] + target_label: instance + - target_label: __address__ + replacement: exporter:9114 +``` + +Notes: +- `/metrics` serves a single, process-wide registry and is intended for single-target mode. +- `/probe` creates a fresh registry per scrape for the given `target` allowing multi-target scraping. +- Any `options:` under an auth module will be appended as URL query parameters to the target URL. +- The `tls` auth module (client certificate authentication) is intended for self‑managed Elasticsearch/OpenSearch deployments. Amazon OpenSearch Service typically authenticates at the domain edge with IAM/SigV4 and does not support client certificate authentication; use the `aws` auth module instead when scraping Amazon OpenSearch Service domains. + ### Metrics | Name | Type | Cardinality | Help | diff --git a/collector/indices.go b/collector/indices.go index dd7e7274..fdad33f5 100644 --- a/collector/indices.go +++ b/collector/indices.go @@ -19,6 +19,7 @@ import ( "log/slog" "net/http" "net/url" + "path" "sort" "strconv" @@ -620,13 +621,28 @@ func (i *Indices) fetchAndDecodeIndexStats(ctx context.Context) (indexStatsRespo return isr, nil } -// getCluserName returns the name of the cluster from the clusterinfo -// if the clusterinfo is nil, it returns "unknown_cluster" -// TODO(@sysadmind): this should be removed once we have a better way to handle clusterinfo +// getClusterName returns the cluster name. If no clusterinfo retriever is +// attached (e.g. /probe mode) it performs a lightweight call to the root +// endpoint once and caches the result. func (i *Indices) getClusterName() string { - if i.lastClusterInfo != nil { + if i.lastClusterInfo != nil && i.lastClusterInfo.ClusterName != "unknown_cluster" { return i.lastClusterInfo.ClusterName } + u := *i.url + u.Path = path.Join(u.Path, "/") + resp, err := i.client.Get(u.String()) + if err == nil { + defer resp.Body.Close() + if resp.StatusCode == http.StatusOK { + var root struct { + ClusterName string `json:"cluster_name"` + } + if err := json.NewDecoder(resp.Body).Decode(&root); err == nil && root.ClusterName != "" { + i.lastClusterInfo = &clusterinfo.Response{ClusterName: root.ClusterName} + return root.ClusterName + } + } + } return "unknown_cluster" } diff --git a/collector/shards.go b/collector/shards.go index 136ea671..351680ca 100644 --- a/collector/shards.go +++ b/collector/shards.go @@ -64,23 +64,50 @@ type nodeShardMetric struct { Labels labels } +// fetchClusterNameOnce performs a single request to the root endpoint to obtain the cluster name. +func fetchClusterNameOnce(s *Shards) string { + if s.lastClusterInfo != nil && s.lastClusterInfo.ClusterName != "unknown_cluster" { + return s.lastClusterInfo.ClusterName + } + u := *s.url + u.Path = path.Join(u.Path, "/") + resp, err := s.client.Get(u.String()) + if err == nil { + defer resp.Body.Close() + if resp.StatusCode == http.StatusOK { + var root struct { + ClusterName string `json:"cluster_name"` + } + if err := json.NewDecoder(resp.Body).Decode(&root); err == nil && root.ClusterName != "" { + s.lastClusterInfo = &clusterinfo.Response{ClusterName: root.ClusterName} + return root.ClusterName + } + } + } + return "unknown_cluster" +} + // NewShards defines Shards Prometheus metrics func NewShards(logger *slog.Logger, client *http.Client, url *url.URL) *Shards { + var shardPtr *Shards nodeLabels := labels{ keys: func(...string) []string { return []string{"node", "cluster"} }, - values: func(lastClusterinfo *clusterinfo.Response, s ...string) []string { + values: func(lastClusterinfo *clusterinfo.Response, base ...string) []string { if lastClusterinfo != nil { - return append(s, lastClusterinfo.ClusterName) + return append(base, lastClusterinfo.ClusterName) } - // this shouldn't happen, as the clusterinfo Retriever has a blocking - // Run method. It blocks until the first clusterinfo call has succeeded - return append(s, "unknown_cluster") + if shardPtr != nil { + return append(base, fetchClusterNameOnce(shardPtr)) + } + return append(base, "unknown_cluster") }, } shards := &Shards{ + // will assign later + logger: logger, client: client, url: url, @@ -123,6 +150,7 @@ func NewShards(logger *slog.Logger, client *http.Client, url *url.URL) *Shards { logger.Debug("exiting cluster info receive loop") }() + shardPtr = shards return shards } diff --git a/config/config.go b/config/config.go new file mode 100644 index 00000000..2137cc5e --- /dev/null +++ b/config/config.go @@ -0,0 +1,137 @@ +// Copyright The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "fmt" + "os" + "strings" + + "go.yaml.in/yaml/v3" +) + +// Config represents the YAML configuration file structure. +type Config struct { + AuthModules map[string]AuthModule `yaml:"auth_modules"` +} + +type AuthModule struct { + Type string `yaml:"type"` + UserPass *UserPassConfig `yaml:"userpass,omitempty"` + APIKey string `yaml:"apikey,omitempty"` + AWS *AWSConfig `yaml:"aws,omitempty"` + TLS *TLSConfig `yaml:"tls,omitempty"` + Options map[string]string `yaml:"options,omitempty"` +} + +// AWSConfig contains settings for SigV4 authentication. +type AWSConfig struct { + Region string `yaml:"region,omitempty"` + RoleARN string `yaml:"role_arn,omitempty"` +} + +// TLSConfig allows per-target TLS options. +type TLSConfig struct { + CAFile string `yaml:"ca_file,omitempty"` + CertFile string `yaml:"cert_file,omitempty"` + KeyFile string `yaml:"key_file,omitempty"` + InsecureSkipVerify bool `yaml:"insecure_skip_verify,omitempty"` +} + +type UserPassConfig struct { + Username string `yaml:"username"` + Password string `yaml:"password"` +} + +// validate ensures every auth module has the required fields according to its type. +func (c *Config) validate() error { + for name, am := range c.AuthModules { + // Validate fields based on auth type + switch strings.ToLower(am.Type) { + case "userpass": + if am.UserPass == nil || am.UserPass.Username == "" || am.UserPass.Password == "" { + return fmt.Errorf("auth_module %s type userpass requires username and password", name) + } + case "apikey": + if am.APIKey == "" { + return fmt.Errorf("auth_module %s type apikey requires apikey", name) + } + case "aws": + // No strict validation: region can come from environment/defaults; role_arn is optional. + case "tls": + // TLS auth type means client certificate authentication only (no other auth) + if am.TLS == nil { + return fmt.Errorf("auth_module %s type tls requires tls configuration section", name) + } + if am.TLS.CertFile == "" || am.TLS.KeyFile == "" { + return fmt.Errorf("auth_module %s type tls requires cert_file and key_file for client certificate authentication", name) + } + // Validate that other auth fields are not set when using TLS auth type + if am.UserPass != nil { + return fmt.Errorf("auth_module %s type tls cannot have userpass configuration", name) + } + if am.APIKey != "" { + return fmt.Errorf("auth_module %s type tls cannot have apikey", name) + } + if am.AWS != nil { + return fmt.Errorf("auth_module %s type tls cannot have aws configuration", name) + } + default: + return fmt.Errorf("auth_module %s has unsupported type %s", name, am.Type) + } + + // Validate TLS configuration (optional for all auth types, provides transport security) + if am.TLS != nil { + // For cert-based auth (type: tls), cert and key are required + // For other auth types, TLS config is optional and used for transport security + if strings.ToLower(am.Type) != "tls" { + // For non-TLS auth types, if cert/key are provided, both must be present + if (am.TLS.CertFile != "") != (am.TLS.KeyFile != "") { + return fmt.Errorf("auth_module %s: if providing client certificate, both cert_file and key_file must be specified", name) + } + } + + // Validate file accessibility + for fileType, path := range map[string]string{ + "ca_file": am.TLS.CAFile, + "cert_file": am.TLS.CertFile, + "key_file": am.TLS.KeyFile, + } { + if path == "" { + continue + } + if _, err := os.Stat(path); err != nil { + return fmt.Errorf("auth_module %s: %s '%s' not accessible: %w", name, fileType, path, err) + } + } + } + } + return nil +} + +// LoadConfig reads, parses, and validates the YAML config file. +func LoadConfig(path string) (*Config, error) { + data, err := os.ReadFile(path) + if err != nil { + return nil, err + } + var cfg Config + if err := yaml.Unmarshal(data, &cfg); err != nil { + return nil, err + } + if err := cfg.validate(); err != nil { + return nil, err + } + return &cfg, nil +} diff --git a/config/config_test.go b/config/config_test.go new file mode 100644 index 00000000..f5147db6 --- /dev/null +++ b/config/config_test.go @@ -0,0 +1,183 @@ +// Copyright The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "os" + "testing" +) + +func mustTempFile(t *testing.T) string { + f, err := os.CreateTemp(t.TempDir(), "pem-*.crt") + if err != nil { + t.Fatalf("temp file: %v", err) + } + f.Close() + // Ensure temp file is removed even if created outside of test's TempDir semantics change + path := f.Name() + t.Cleanup(func() { _ = os.Remove(path) }) + return path +} + +// ---------------------------- Positive cases ---------------------------- +func TestLoadConfigPositiveVariants(t *testing.T) { + ca := mustTempFile(t) + cert := mustTempFile(t) + key := mustTempFile(t) + + positive := []struct { + name string + yaml string + }{{ + "userpass", + `auth_modules: + basic: + type: userpass + userpass: + username: u + password: p`, + }, { + "userpass-with-tls", + `auth_modules: + basic: + type: userpass + userpass: + username: u + password: p + tls: + ca_file: ` + ca + ` + insecure_skip_verify: true`, + }, { + "apikey", + `auth_modules: + key: + type: apikey + apikey: ZXhhbXBsZQ==`, + }, { + "apikey-with-tls", + `auth_modules: + key: + type: apikey + apikey: ZXhhbXBsZQ== + tls: + ca_file: ` + ca + ` + cert_file: ` + cert + ` + key_file: ` + key + ``, + }, { + "aws-with-tls", + `auth_modules: + awsmod: + type: aws + aws: + region: us-east-1 + tls: + insecure_skip_verify: true`, + }, { + "tls-only", + `auth_modules: + pki: + type: tls + tls: + ca_file: ` + ca + ` + cert_file: ` + cert + ` + key_file: ` + key + ``, + }} + + for _, c := range positive { + tmp, _ := os.CreateTemp(t.TempDir(), "cfg-*.yml") + _, _ = tmp.WriteString(c.yaml) + _ = tmp.Close() + t.Cleanup(func() { _ = os.Remove(tmp.Name()) }) + if _, err := LoadConfig(tmp.Name()); err != nil { + t.Fatalf("%s: expected success, got %v", c.name, err) + } + } +} + +// ---------------------------- Negative cases ---------------------------- +func TestLoadConfigNegativeVariants(t *testing.T) { + cert := mustTempFile(t) + key := mustTempFile(t) + + negative := []struct { + name string + yaml string + }{{ + "userpassMissingPassword", + `auth_modules: + bad: + type: userpass + userpass: {username: u}`, + }, { + "tlsMissingCert", + `auth_modules: + bad: + type: tls + tls: {key_file: ` + key + `}`, + }, { + "tlsMissingKey", + `auth_modules: + bad: + type: tls + tls: {cert_file: ` + cert + `}`, + }, { + "tlsMissingConfig", + `auth_modules: + bad: + type: tls`, + }, { + "tlsWithUserpass", + `auth_modules: + bad: + type: tls + tls: {cert_file: ` + cert + `, key_file: ` + key + `} + userpass: {username: u, password: p}`, + }, { + "tlsWithAPIKey", + `auth_modules: + bad: + type: tls + tls: {cert_file: ` + cert + `, key_file: ` + key + `} + apikey: ZXhhbXBsZQ==`, + }, { + "tlsWithAWS", + `auth_modules: + bad: + type: tls + tls: {cert_file: ` + cert + `, key_file: ` + key + `} + aws: {region: us-east-1}`, + }, { + "tlsIncompleteCert", + `auth_modules: + bad: + type: apikey + apikey: ZXhhbXBsZQ== + tls: {cert_file: ` + cert + `}`, + }, { + "unsupportedType", + `auth_modules: + bad: + type: foobar`, + }} + + for _, c := range negative { + tmp, _ := os.CreateTemp(t.TempDir(), "cfg-*.yml") + _, _ = tmp.WriteString(c.yaml) + _ = tmp.Close() + t.Cleanup(func() { _ = os.Remove(tmp.Name()) }) + if _, err := LoadConfig(tmp.Name()); err == nil { + t.Fatalf("%s: expected validation error, got none", c.name) + } + } +} diff --git a/examples/auth_modules.yml b/examples/auth_modules.yml new file mode 100644 index 00000000..7603aa8c --- /dev/null +++ b/examples/auth_modules.yml @@ -0,0 +1,55 @@ +# Example exporter-config.yml demonstrating multiple auth modules +# Each module can be referenced with ?auth_module= in /probe requests. + +auth_modules: + ########################################################################### + # 1. Simple basic-auth over HTTPS # + ########################################################################### + prod_basic: + type: userpass + userpass: + username: metrics + password: s3cr3t + # extra URL query parameters are appended to the target DSN + options: + sslmode: disable # becomes ?sslmode=disable + + ########################################################################### + # 2. Read-only account for staging cluster # + ########################################################################### + staging_ro: + type: userpass + userpass: + username: readonly + password: changeme + + ########################################################################### + # 3. API-Key authentication # + ########################################################################### + prod_key: + type: apikey + apikey: BASE64-ENCODED-KEY== + + ########################################################################### + # 5. AWS SigV4 signing with optional TLS settings # + ########################################################################### + aws_sigv4: + type: aws + aws: + region: us-east-1 + # role_arn is optional + # Optional TLS configuration for transport security + tls: + ca_file: /etc/ssl/ca.pem + insecure_skip_verify: false + + ########################################################################### + # 6. Client certificate authentication only (no username/password) # + ########################################################################### + pki_mtls: + type: tls # This auth type uses ONLY client certificates for authentication + tls: + ca_file: /etc/ssl/pki/ca.pem # Optional: CA for server verification + cert_file: /etc/ssl/pki/client.pem # Required: Client certificate for auth + key_file: /etc/ssl/pki/client-key.pem # Required: Client private key for auth + insecure_skip_verify: false # Optional: Skip server cert validation diff --git a/examples/example-prometheus.yml b/examples/example-prometheus.yml new file mode 100644 index 00000000..f63be37a --- /dev/null +++ b/examples/example-prometheus.yml @@ -0,0 +1,33 @@ +scrape_configs: + - job_name: es-multi + metrics_path: /probe + # Default parameters for all scrapes in this job. + # Can be overridden by labels on a per-target basis. + params: + auth_module: [prod_key] + static_configs: + # This is a target group. All targets here will use the default 'prod_key' auth_module. + - targets: + - https://es-prod-1:9200 + - https://es-prod-2:9200 + # This is another target group. + - targets: + - https://es-stage:9200 + # The __param_ prefix on a label causes it to be added as a URL parameter. + # This will override the default auth_module for this target. + labels: + __param_auth_module: staging_basic + relabel_configs: + # The following relabeling rules are applied to every target. + + # 1. The special label __address__ (the target address) is saved as the 'target' URL parameter. + - source_labels: [__address__] + target_label: __param_target + + # 2. The 'target' parameter is used as the 'instance' label for the scraped metrics. + - source_labels: [__param_target] + target_label: instance + + # 3. The scrape address is rewritten to point to the exporter. + - target_label: __address__ + replacement: exporter:9114 # host:port of the single exporter diff --git a/go.mod b/go.mod index 707e523a..1f4be428 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/prometheus-community/elasticsearch_exporter -go 1.23.0 - -toolchain go1.24.1 +go 1.24.1 require ( github.com/alecthomas/kingpin/v2 v2.4.0 @@ -15,6 +13,7 @@ require ( github.com/prometheus/client_golang v1.23.0 github.com/prometheus/common v0.65.0 github.com/prometheus/exporter-toolkit v0.14.0 + go.yaml.in/yaml/v3 v3.0.4 ) require ( diff --git a/go.sum b/go.sum index 858d9942..3edf5138 100644 --- a/go.sum +++ b/go.sum @@ -82,6 +82,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= diff --git a/main.go b/main.go index a8405f45..c739c28d 100644 --- a/main.go +++ b/main.go @@ -36,6 +36,7 @@ import ( webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag" "github.com/prometheus-community/elasticsearch_exporter/collector" + "github.com/prometheus-community/elasticsearch_exporter/config" "github.com/prometheus-community/elasticsearch_exporter/pkg/clusterinfo" "github.com/prometheus-community/elasticsearch_exporter/pkg/roundtripper" ) @@ -60,7 +61,7 @@ func main() { toolkitFlags = webflag.AddFlags(kingpin.CommandLine, ":9114") esURI = kingpin.Flag("es.uri", "HTTP API address of an Elasticsearch node."). - Default("http://localhost:9200").String() + Default("").String() esTimeout = kingpin.Flag("es.timeout", "Timeout for trying to get stats from Elasticsearch."). Default("5s").Duration() @@ -109,6 +110,7 @@ func main() { awsRoleArn = kingpin.Flag("aws.role-arn", "Role ARN of an IAM role to assume."). Default("").String() + configFile = kingpin.Flag("config.file", "Path to YAML configuration file.").Default("").String() ) promslogConfig := &promslog.Config{} @@ -117,6 +119,18 @@ func main() { kingpin.CommandLine.HelpFlag.Short('h') kingpin.Parse() + // Load optional YAML config + var cfg *config.Config + if *configFile != "" { + var cfgErr error + cfg, cfgErr = config.LoadConfig(*configFile) + if cfgErr != nil { + // At this stage logger not yet created; fallback to stderr + fmt.Fprintf(os.Stderr, "failed to load config file: %v\n", cfgErr) + os.Exit(1) + } + } + var w io.Writer switch strings.ToLower(*logOutput) { case "stderr": @@ -129,116 +143,124 @@ func main() { promslogConfig.Writer = w logger := promslog.New(promslogConfig) - esURL, err := url.Parse(*esURI) - if err != nil { - logger.Error("failed to parse es.uri", "err", err) - os.Exit(1) - } + // version metric + prometheus.MustRegister(versioncollector.NewCollector(name)) - esUsername := os.Getenv("ES_USERNAME") - esPassword := os.Getenv("ES_PASSWORD") + // Create a context that is cancelled on SIGKILL or SIGINT. + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill) + defer cancel() - if esUsername != "" && esPassword != "" { - esURL.User = url.UserPassword(esUsername, esPassword) - } + if *esURI != "" { + esURL, err := url.Parse(*esURI) + if err != nil { + logger.Error("failed to parse es.uri", "err", err) + os.Exit(1) + } - // returns nil if not provided and falls back to simple TCP. - tlsConfig := createTLSConfig(*esCA, *esClientCert, *esClientPrivateKey, *esInsecureSkipVerify) + esUsername := os.Getenv("ES_USERNAME") + esPassword := os.Getenv("ES_PASSWORD") - var httpTransport http.RoundTripper + if esUsername != "" && esPassword != "" { + esURL.User = url.UserPassword(esUsername, esPassword) + } - httpTransport = &http.Transport{ - TLSClientConfig: tlsConfig, - Proxy: http.ProxyFromEnvironment, - } + // returns nil if not provided and falls back to simple TCP. + tlsConfig := createTLSConfig(*esCA, *esClientCert, *esClientPrivateKey, *esInsecureSkipVerify) - esAPIKey := os.Getenv("ES_API_KEY") + var httpTransport http.RoundTripper - if esAPIKey != "" { - httpTransport = &transportWithAPIKey{ - underlyingTransport: httpTransport, - apiKey: esAPIKey, + httpTransport = &http.Transport{ + TLSClientConfig: tlsConfig, + Proxy: http.ProxyFromEnvironment, } - } - httpClient := &http.Client{ - Timeout: *esTimeout, - Transport: httpTransport, - } + esAPIKey := os.Getenv("ES_API_KEY") - if *awsRegion != "" { - httpClient.Transport, err = roundtripper.NewAWSSigningTransport(httpTransport, *awsRegion, *awsRoleArn, logger) - if err != nil { - logger.Error("failed to create AWS transport", "err", err) - os.Exit(1) + if esAPIKey != "" { + httpTransport = &transportWithAPIKey{ + underlyingTransport: httpTransport, + apiKey: esAPIKey, + } } - } - // version metric - prometheus.MustRegister(versioncollector.NewCollector(name)) + httpClient := &http.Client{ + Timeout: *esTimeout, + Transport: httpTransport, + } - // create the exporter - exporter, err := collector.NewElasticsearchCollector( - logger, - []string{}, - collector.WithElasticsearchURL(esURL), - collector.WithHTTPClient(httpClient), - ) - if err != nil { - logger.Error("failed to create Elasticsearch collector", "err", err) - os.Exit(1) - } - prometheus.MustRegister(exporter) - - // TODO(@sysadmind): Remove this when we have a better way to get the cluster name to down stream collectors. - // cluster info retriever - clusterInfoRetriever := clusterinfo.New(logger, httpClient, esURL, *esClusterInfoInterval) - - prometheus.MustRegister(collector.NewClusterHealth(logger, httpClient, esURL)) - prometheus.MustRegister(collector.NewNodes(logger, httpClient, esURL, *esAllNodes, *esNode)) - - if *esExportIndices || *esExportShards { - sC := collector.NewShards(logger, httpClient, esURL) - prometheus.MustRegister(sC) - iC := collector.NewIndices(logger, httpClient, esURL, *esExportShards, *esExportIndexAliases) - prometheus.MustRegister(iC) - if registerErr := clusterInfoRetriever.RegisterConsumer(iC); registerErr != nil { - logger.Error("failed to register indices collector in cluster info") - os.Exit(1) + if *awsRegion != "" { + var err error + httpClient.Transport, err = roundtripper.NewAWSSigningTransport(httpTransport, *awsRegion, *awsRoleArn, logger) + if err != nil { + logger.Error("failed to create AWS transport", "err", err) + os.Exit(1) + } } - if registerErr := clusterInfoRetriever.RegisterConsumer(sC); registerErr != nil { - logger.Error("failed to register shards collector in cluster info") + + // create the exporter + exporter, err := collector.NewElasticsearchCollector( + logger, + []string{}, + collector.WithElasticsearchURL(esURL), + collector.WithHTTPClient(httpClient), + ) + if err != nil { + logger.Error("failed to create Elasticsearch collector", "err", err) os.Exit(1) } - } + prometheus.MustRegister(exporter) + + // TODO(@sysadmind): Remove this when we have a better way to get the cluster name to down stream collectors. + // cluster info retriever + clusterInfoRetriever := clusterinfo.New(logger, httpClient, esURL, *esClusterInfoInterval) + + prometheus.MustRegister(collector.NewClusterHealth(logger, httpClient, esURL)) + prometheus.MustRegister(collector.NewNodes(logger, httpClient, esURL, *esAllNodes, *esNode)) + + if *esExportIndices || *esExportShards { + sC := collector.NewShards(logger, httpClient, esURL) + prometheus.MustRegister(sC) + iC := collector.NewIndices(logger, httpClient, esURL, *esExportShards, *esExportIndexAliases) + prometheus.MustRegister(iC) + if registerErr := clusterInfoRetriever.RegisterConsumer(iC); registerErr != nil { + logger.Error("failed to register indices collector in cluster info") + os.Exit(1) + } + if registerErr := clusterInfoRetriever.RegisterConsumer(sC); registerErr != nil { + logger.Error("failed to register shards collector in cluster info") + os.Exit(1) + } + } - if *esExportIndicesSettings { - prometheus.MustRegister(collector.NewIndicesSettings(logger, httpClient, esURL)) - } + if *esExportIndicesSettings { + prometheus.MustRegister(collector.NewIndicesSettings(logger, httpClient, esURL)) + } - if *esExportIndicesMappings { - prometheus.MustRegister(collector.NewIndicesMappings(logger, httpClient, esURL)) - } + if *esExportIndicesMappings { + prometheus.MustRegister(collector.NewIndicesMappings(logger, httpClient, esURL)) + } - // Create a context that is cancelled on SIGKILL or SIGINT. - ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill) - defer cancel() + // start the cluster info retriever + switch runErr := clusterInfoRetriever.Run(ctx); runErr { + case nil: + logger.Info("started cluster info retriever", "interval", (*esClusterInfoInterval).String()) + case clusterinfo.ErrInitialCallTimeout: + logger.Info("initial cluster info call timed out") + default: + logger.Error("failed to run cluster info retriever", "err", runErr) + os.Exit(1) + } - // start the cluster info retriever - switch runErr := clusterInfoRetriever.Run(ctx); runErr { - case nil: - logger.Info("started cluster info retriever", "interval", (*esClusterInfoInterval).String()) - case clusterinfo.ErrInitialCallTimeout: - logger.Info("initial cluster info call timed out") - default: - logger.Error("failed to run cluster info retriever", "err", err) - os.Exit(1) + // register cluster info retriever as prometheus collector + prometheus.MustRegister(clusterInfoRetriever) } - // register cluster info retriever as prometheus collector - prometheus.MustRegister(clusterInfoRetriever) + http.HandleFunc(*metricsPath, func(w http.ResponseWriter, r *http.Request) { + // /metrics endpoint is reserved for single-target mode only. + // For per-scrape overrides use the dedicated /probe endpoint. + promhttp.Handler().ServeHTTP(w, r) + }) - http.Handle(*metricsPath, promhttp.Handler()) if *metricsPath != "/" && *metricsPath != "" { landingConfig := web.LandingConfig{ Name: "Elasticsearch Exporter", @@ -264,9 +286,129 @@ func main() { http.Error(w, http.StatusText(http.StatusOK), http.StatusOK) }) + // probe endpoint + http.HandleFunc("/probe", func(w http.ResponseWriter, r *http.Request) { + origQuery := r.URL.Query() + targetStr, am, valErr := validateProbeParams(cfg, origQuery) + if valErr != nil { + http.Error(w, valErr.Error(), http.StatusBadRequest) + return + } + targetURL, _ := url.Parse(targetStr) + if am != nil { + // Apply userpass credentials only if the module type is explicitly set to userpass. + if strings.EqualFold(am.Type, "userpass") && am.UserPass != nil { + targetURL.User = url.UserPassword(am.UserPass.Username, am.UserPass.Password) + } + if len(am.Options) > 0 { + q := targetURL.Query() + for k, v := range am.Options { + q.Set(k, v) + } + targetURL.RawQuery = q.Encode() + } + } + + // Build a dedicated HTTP client for this probe request (reuse TLS opts, timeout, etc.). + pemCA := *esCA + pemCert := *esClientCert + pemKey := *esClientPrivateKey + insecure := *esInsecureSkipVerify + + // Apply TLS configuration from auth module if provided (for transport security) + // This matches single-target behavior where TLS settings are always applied + if am != nil && am.TLS != nil { + // Override with module-specific TLS settings + if am.TLS.CAFile != "" { + pemCA = am.TLS.CAFile + } + if am.TLS.CertFile != "" { + pemCert = am.TLS.CertFile + } + if am.TLS.KeyFile != "" { + pemKey = am.TLS.KeyFile + } + if am.TLS.InsecureSkipVerify { + insecure = true + } + } + tlsCfg := createTLSConfig(pemCA, pemCert, pemKey, insecure) + var transport http.RoundTripper = &http.Transport{ + TLSClientConfig: tlsCfg, + Proxy: http.ProxyFromEnvironment, + } + + // inject authentication based on auth_module type + if am != nil { + switch strings.ToLower(am.Type) { + case "apikey": + if am.APIKey != "" { + transport = &transportWithAPIKey{ + underlyingTransport: transport, + apiKey: am.APIKey, + } + } + case "aws": + var region string + if am.AWS.Region != "" { + region = am.AWS.Region + } + var err error + transport, err = roundtripper.NewAWSSigningTransport(transport, region, am.AWS.RoleARN, logger) + if err != nil { + http.Error(w, "failed to create AWS signing transport", http.StatusInternalServerError) + return + } + case "tls": + // No additional auth wrapper needed - client certificates in TLS config handle authentication + case "userpass": + // Already handled above by setting targetURL.User + } + } + probeClient := &http.Client{ + Timeout: *esTimeout, + Transport: transport, + } + + reg := prometheus.NewRegistry() + + // version metric + reg.MustRegister(versioncollector.NewCollector(name)) + + // Core exporter collector + exp, err := collector.NewElasticsearchCollector( + logger, + []string{}, + collector.WithElasticsearchURL(targetURL), + collector.WithHTTPClient(probeClient), + ) + if err != nil { + http.Error(w, "failed to create exporter", http.StatusInternalServerError) + return + } + reg.MustRegister(exp) + // Basic additional collectors – reuse global CLI flags + reg.MustRegister(collector.NewClusterHealth(logger, probeClient, targetURL)) + reg.MustRegister(collector.NewNodes(logger, probeClient, targetURL, *esAllNodes, *esNode)) + if *esExportIndices || *esExportShards { + shardsC := collector.NewShards(logger, probeClient, targetURL) + indicesC := collector.NewIndices(logger, probeClient, targetURL, *esExportShards, *esExportIndexAliases) + reg.MustRegister(shardsC) + reg.MustRegister(indicesC) + } + if *esExportIndicesSettings { + reg.MustRegister(collector.NewIndicesSettings(logger, probeClient, targetURL)) + } + if *esExportIndicesMappings { + reg.MustRegister(collector.NewIndicesMappings(logger, probeClient, targetURL)) + } + + promhttp.HandlerFor(reg, promhttp.HandlerOpts{}).ServeHTTP(w, r) + }) + server := &http.Server{} go func() { - if err = web.ListenAndServe(server, toolkitFlags, logger); err != nil { + if err := web.ListenAndServe(server, toolkitFlags, logger); err != nil { logger.Error("http server quit", "err", err) os.Exit(1) } diff --git a/pkg/roundtripper/roundtripper.go b/pkg/roundtripper/roundtripper.go index 4c4dd026..8f1cfd3f 100644 --- a/pkg/roundtripper/roundtripper.go +++ b/pkg/roundtripper/roundtripper.go @@ -42,7 +42,12 @@ type AWSSigningTransport struct { } func NewAWSSigningTransport(transport http.RoundTripper, region string, roleArn string, log *slog.Logger) (*AWSSigningTransport, error) { - cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion(region)) + // Only set region explicitly when provided; otherwise allow env/IMDS resolution + var opts []func(*config.LoadOptions) error + if region != "" { + opts = append(opts, config.WithRegion(region)) + } + cfg, err := config.LoadDefaultConfig(context.Background(), opts...) if err != nil { log.Error("failed to load aws default config", "err", err) return nil, err diff --git a/probe.go b/probe.go new file mode 100644 index 00000000..2b999604 --- /dev/null +++ b/probe.go @@ -0,0 +1,78 @@ +// Copyright The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "errors" + "net/url" + "strings" + + "github.com/prometheus-community/elasticsearch_exporter/config" +) + +var ( + errMissingTarget = errors.New("missing target parameter") + errInvalidTarget = errors.New("invalid target parameter") + errModuleNotFound = errors.New("auth_module not found") + errUnsupportedModule = errors.New("unsupported auth_module type") +) + +// validateProbeParams performs upfront validation of the query parameters. +// It returns the target string (as given), the resolved AuthModule (optional), or an error. +func validateProbeParams(cfg *config.Config, q url.Values) (string, *config.AuthModule, error) { + target := q.Get("target") + if target == "" { + return "", nil, errMissingTarget + } + + // If the target does not contain an URL scheme, default to http. + // This allows users to pass "host:port" without the "http://" prefix. + if !strings.Contains(target, "://") { + target = "http://" + target + } + + u, err := url.Parse(target) + if err != nil { + return "", nil, errInvalidTarget + } + if u.Scheme != "http" && u.Scheme != "https" { + return "", nil, errInvalidTarget + } + + modu := q.Get("auth_module") + if modu == "" { + return target, nil, nil // no auth module requested + } + if cfg == nil { + return "", nil, errModuleNotFound + } + am, ok := cfg.AuthModules[modu] + if !ok { + return "", nil, errModuleNotFound + } + switch strings.ToLower(am.Type) { + case "userpass": + return target, &am, nil + case "apikey": + return target, &am, nil + case "aws": + // Accept module even if region omitted; environment resolver can provide it. + return target, &am, nil + case "tls": + // TLS auth type is valid; detailed TLS validation is performed during config load. + return target, &am, nil + default: + return "", nil, errUnsupportedModule + } +} diff --git a/probe_test.go b/probe_test.go new file mode 100644 index 00000000..a2cc3bbf --- /dev/null +++ b/probe_test.go @@ -0,0 +1,126 @@ +// Copyright The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "net/url" + "testing" + + "github.com/prometheus-community/elasticsearch_exporter/config" +) + +func TestValidateProbeParams(t *testing.T) { + cfg := &config.Config{AuthModules: map[string]config.AuthModule{}} + // missing target + _, _, err := validateProbeParams(cfg, url.Values{}) + if err != errMissingTarget { + t.Fatalf("expected missing target error, got %v", err) + } + + // invalid target + vals := url.Values{} + vals.Set("target", "http://[::1") + _, _, err = validateProbeParams(cfg, vals) + if err == nil { + t.Fatalf("expected invalid target error") + } + + // invalid scheme + vals = url.Values{} + vals.Set("target", "ftp://example.com") + _, _, err = validateProbeParams(cfg, vals) + if err == nil { + t.Fatalf("expected invalid target error for unsupported scheme") + } + + // unknown module + vals = url.Values{} + vals.Set("target", "http://localhost:9200") + vals.Set("auth_module", "foo") + _, _, err = validateProbeParams(cfg, vals) + if err != errModuleNotFound { + t.Fatalf("expected module not found error, got %v", err) + } + + // good path (userpass) + cfg.AuthModules["foo"] = config.AuthModule{Type: "userpass", UserPass: &config.UserPassConfig{Username: "u", Password: "p"}} + vals = url.Values{} + vals.Set("target", "http://localhost:9200") + vals.Set("auth_module", "foo") + tgt, am, err := validateProbeParams(cfg, vals) + if err != nil || am == nil || tgt == "" { + t.Fatalf("expected success, got err=%v", err) + } + + // good path (apikey) with both userpass and apikey set - apikey should be accepted + cfg.AuthModules["api"] = config.AuthModule{ + Type: "apikey", + APIKey: "mysecret", + UserPass: &config.UserPassConfig{Username: "u", Password: "p"}, + } + vals = url.Values{} + vals.Set("target", "http://localhost:9200") + vals.Set("auth_module", "api") + _, am, err = validateProbeParams(cfg, vals) + if err != nil { + t.Fatalf("expected success for apikey module, got err=%v", err) + } + if am == nil || am.Type != "apikey" { + t.Fatalf("expected apikey module, got %+v", am) + } + if am.APIKey != "mysecret" { + t.Fatalf("unexpected apikey value: %s", am.APIKey) + } + + // good path (aws) + cfg.AuthModules["awsmod"] = config.AuthModule{ + Type: "aws", + AWS: &config.AWSConfig{ + Region: "us-east-1", + RoleARN: "arn:aws:iam::123456789012:role/metrics", + }, + } + vals = url.Values{} + vals.Set("target", "http://localhost:9200") + vals.Set("auth_module", "awsmod") + _, am, err = validateProbeParams(cfg, vals) + if err != nil { + t.Fatalf("expected success for aws module, got err=%v", err) + } + if am == nil || am.Type != "aws" { + t.Fatalf("expected aws module, got %+v", am) + } + if am.AWS == nil || am.AWS.Region != "us-east-1" { + t.Fatalf("unexpected aws config: %+v", am.AWS) + } + + // invalid path (aws with empty region - rejected at config load; simulate here by passing nil cfg lookup) + // No additional test needed as config.LoadConfig enforces region. + + // good path (tls) + cfg.AuthModules["mtls"] = config.AuthModule{ + Type: "tls", + TLS: &config.TLSConfig{CAFile: "/dev/null", CertFile: "/dev/null", KeyFile: "/dev/null"}, + } + vals = url.Values{} + vals.Set("target", "http://localhost:9200") + vals.Set("auth_module", "mtls") + _, am, err = validateProbeParams(cfg, vals) + if err != nil { + t.Fatalf("expected success for tls module, got err=%v", err) + } + if am == nil || am.Type != "tls" { + t.Fatalf("expected tls module, got %+v", am) + } +} From fd6d1c9899bd17517cb950a0b2a087aaeb380cf7 Mon Sep 17 00:00:00 2001 From: pincher95 Date: Tue, 25 Nov 2025 17:51:41 -0500 Subject: [PATCH 02/21] Add node label to elasticsearch_nodes_roles metric - Add 'node' (node ID) label to elasticsearch_nodes_roles metric - Node ID comes from the map key in nodes stats response (no extra API calls) - Update tests for ES versions 5.6.16, 6.8.8, and 7.13.1 Signed-off-by: pincher95 --- collector/nodes.go | 15 +++------ collector/nodes_test.go | 72 ++++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 46 deletions(-) diff --git a/collector/nodes.go b/collector/nodes.go index b830ec3f..d1c7cbb0 100644 --- a/collector/nodes.go +++ b/collector/nodes.go @@ -16,7 +16,6 @@ package collector import ( "encoding/json" "fmt" - "io" "log/slog" "net/http" "net/url" @@ -77,7 +76,7 @@ var nodesRolesMetric = prometheus.NewDesc( var ( defaultNodeLabels = []string{"cluster", "host", "name", "es_master_node", "es_data_node", "es_ingest_node", "es_client_node"} - defaultRoleLabels = []string{"cluster", "host", "name"} + defaultRoleLabels = []string{"cluster", "host", "name", "node"} defaultThreadPoolLabels = append(defaultNodeLabels, "type") defaultBreakerLabels = append(defaultNodeLabels, "breaker") defaultIndexingPressureLabels = []string{"cluster", "host", "name", "indexing_pressure"} @@ -1883,13 +1882,8 @@ func (c *Nodes) fetchAndDecodeNodeStats() (nodeStatsResponse, error) { return nsr, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) } - bts, err := io.ReadAll(res.Body) - if err != nil { - return nsr, err - } - - if err := json.Unmarshal(bts, &nsr); err != nil { - return nsr, err + if err := json.NewDecoder(res.Body).Decode(&nsr); err != nil { + return nsr, fmt.Errorf("failed to decode response body: %w", err) } return nsr, nil } @@ -1905,7 +1899,7 @@ func (c *Nodes) Collect(ch chan<- prometheus.Metric) { return } - for _, node := range nodeStatsResp.Nodes { + for nodeID, node := range nodeStatsResp.Nodes { // Handle the node labels metric roles := getRoles(node) @@ -1919,6 +1913,7 @@ func (c *Nodes) Collect(ch chan<- prometheus.Metric) { nodeStatsResp.ClusterName, node.Host, node.Name, + nodeID, role, } diff --git a/collector/nodes_test.go b/collector/nodes_test.go index 3275d18e..6b7944e6 100644 --- a/collector/nodes_test.go +++ b/collector/nodes_test.go @@ -340,18 +340,18 @@ func TestNodesStats(t *testing.T) { elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="mapped"} 14.845 # HELP elasticsearch_nodes_roles Node roles # TYPE elasticsearch_nodes_roles gauge - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_cold"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_content"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_frozen"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_hot"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_warm"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="ingest"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="master"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="ml"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="remote_cluster_client"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="transform"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_cold"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_content"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_frozen"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_hot"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_warm"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="ml"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="remote_cluster_client"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="transform"} 0 # HELP elasticsearch_os_cpu_percent Percent CPU used by OS # TYPE elasticsearch_os_cpu_percent gauge elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 23 @@ -799,18 +799,18 @@ func TestNodesStats(t *testing.T) { elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="mapped"} 16.456 # HELP elasticsearch_nodes_roles Node roles # TYPE elasticsearch_nodes_roles gauge - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_cold"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_content"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_frozen"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_hot"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_warm"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="ingest"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="master"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="ml"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="remote_cluster_client"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="transform"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_cold"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_content"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_frozen"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_hot"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_warm"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="ml"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="remote_cluster_client"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="transform"} 0 # HELP elasticsearch_os_cpu_percent Percent CPU used by OS # TYPE elasticsearch_os_cpu_percent gauge elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 30 @@ -1322,18 +1322,18 @@ func TestNodesStats(t *testing.T) { elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="mapped"} 21.844 # HELP elasticsearch_nodes_roles Node roles # TYPE elasticsearch_nodes_roles gauge - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_cold"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_content"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_frozen"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_hot"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_warm"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="ingest"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="master"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="ml"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="remote_cluster_client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="transform"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_cold"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_content"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_frozen"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_hot"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_warm"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="ml"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="remote_cluster_client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="transform"} 1 # HELP elasticsearch_os_cpu_percent Percent CPU used by OS # TYPE elasticsearch_os_cpu_percent gauge elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 37 From 741be2ff50df1157003882ce656faeff2761d8ca Mon Sep 17 00:00:00 2001 From: pincher95 Date: Tue, 25 Nov 2025 17:52:49 -0500 Subject: [PATCH 03/21] Add node label to elasticsearch_nodes_roles metric - Add 'node' (node ID) label to elasticsearch_nodes_roles metric - Node ID comes from the map key in nodes stats response (no extra API calls) - Update tests for ES versions 5.6.16, 6.8.8, and 7.13.1 Signed-off-by: pincher95 --- collector/nodes.go | 15 ++++++--- collector/nodes_test.go | 72 ++++++++++++++++++++--------------------- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/collector/nodes.go b/collector/nodes.go index d1c7cbb0..b830ec3f 100644 --- a/collector/nodes.go +++ b/collector/nodes.go @@ -16,6 +16,7 @@ package collector import ( "encoding/json" "fmt" + "io" "log/slog" "net/http" "net/url" @@ -76,7 +77,7 @@ var nodesRolesMetric = prometheus.NewDesc( var ( defaultNodeLabels = []string{"cluster", "host", "name", "es_master_node", "es_data_node", "es_ingest_node", "es_client_node"} - defaultRoleLabels = []string{"cluster", "host", "name", "node"} + defaultRoleLabels = []string{"cluster", "host", "name"} defaultThreadPoolLabels = append(defaultNodeLabels, "type") defaultBreakerLabels = append(defaultNodeLabels, "breaker") defaultIndexingPressureLabels = []string{"cluster", "host", "name", "indexing_pressure"} @@ -1882,8 +1883,13 @@ func (c *Nodes) fetchAndDecodeNodeStats() (nodeStatsResponse, error) { return nsr, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) } - if err := json.NewDecoder(res.Body).Decode(&nsr); err != nil { - return nsr, fmt.Errorf("failed to decode response body: %w", err) + bts, err := io.ReadAll(res.Body) + if err != nil { + return nsr, err + } + + if err := json.Unmarshal(bts, &nsr); err != nil { + return nsr, err } return nsr, nil } @@ -1899,7 +1905,7 @@ func (c *Nodes) Collect(ch chan<- prometheus.Metric) { return } - for nodeID, node := range nodeStatsResp.Nodes { + for _, node := range nodeStatsResp.Nodes { // Handle the node labels metric roles := getRoles(node) @@ -1913,7 +1919,6 @@ func (c *Nodes) Collect(ch chan<- prometheus.Metric) { nodeStatsResp.ClusterName, node.Host, node.Name, - nodeID, role, } diff --git a/collector/nodes_test.go b/collector/nodes_test.go index 6b7944e6..3275d18e 100644 --- a/collector/nodes_test.go +++ b/collector/nodes_test.go @@ -340,18 +340,18 @@ func TestNodesStats(t *testing.T) { elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="mapped"} 14.845 # HELP elasticsearch_nodes_roles Node roles # TYPE elasticsearch_nodes_roles gauge - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_cold"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_content"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_frozen"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_hot"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_warm"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="ingest"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="master"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="ml"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="remote_cluster_client"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="transform"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_cold"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_content"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_frozen"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_hot"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_warm"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="ml"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="remote_cluster_client"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="transform"} 0 # HELP elasticsearch_os_cpu_percent Percent CPU used by OS # TYPE elasticsearch_os_cpu_percent gauge elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 23 @@ -799,18 +799,18 @@ func TestNodesStats(t *testing.T) { elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="mapped"} 16.456 # HELP elasticsearch_nodes_roles Node roles # TYPE elasticsearch_nodes_roles gauge - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_cold"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_content"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_frozen"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_hot"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_warm"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="ingest"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="master"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="ml"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="remote_cluster_client"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="transform"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_cold"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_content"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_frozen"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_hot"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_warm"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="ml"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="remote_cluster_client"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="transform"} 0 # HELP elasticsearch_os_cpu_percent Percent CPU used by OS # TYPE elasticsearch_os_cpu_percent gauge elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 30 @@ -1322,18 +1322,18 @@ func TestNodesStats(t *testing.T) { elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="mapped"} 21.844 # HELP elasticsearch_nodes_roles Node roles # TYPE elasticsearch_nodes_roles gauge - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_cold"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_content"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_frozen"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_hot"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_warm"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="ingest"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="master"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="ml"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="remote_cluster_client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="transform"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_cold"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_content"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_frozen"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_hot"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_warm"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="ml"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="remote_cluster_client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="transform"} 1 # HELP elasticsearch_os_cpu_percent Percent CPU used by OS # TYPE elasticsearch_os_cpu_percent gauge elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 37 From 425c57f695557852087764f031d59fe861a76db4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:42:24 -0400 Subject: [PATCH 04/21] Bump actions/setup-go from 5.4.0 to 6.0.0 (#1086) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.4.0 to 6.0.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/0aaccfd150d50ccaeb58ebd88d36e91967a5f35b...44694675825211faa026b3c33043df3e48a5fa00) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: pincher95 --- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/mixin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 672dd424..a7eba347 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -26,7 +26,7 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install Go - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 with: go-version: 1.24.x - name: Install snmp_exporter/generator dependencies diff --git a/.github/workflows/mixin.yml b/.github/workflows/mixin.yml index a23d933e..a4f3f0dc 100644 --- a/.github/workflows/mixin.yml +++ b/.github/workflows/mixin.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup Go - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 with: go-version: 1.23.x - name: Install dependencies From 2f848d09a20d5783717b3b82981ce8a5adfb4008 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:45:38 -0400 Subject: [PATCH 05/21] Bump the aws group with 4 updates (#1081) Bumps the aws group with 4 updates: [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2), [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2), [github.com/aws/aws-sdk-go-v2/credentials](https://github.com/aws/aws-sdk-go-v2) and [github.com/aws/aws-sdk-go-v2/service/sts](https://github.com/aws/aws-sdk-go-v2). Updates `github.com/aws/aws-sdk-go-v2` from 1.37.2 to 1.39.2 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.37.2...v1.39.2) Updates `github.com/aws/aws-sdk-go-v2/config` from 1.30.3 to 1.31.12 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.30.3...config/v1.31.12) Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.18.3 to 1.18.16 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.18.3...config/v1.18.16) Updates `github.com/aws/aws-sdk-go-v2/service/sts` from 1.36.0 to 1.38.6 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.36.0...service/sts/v1.38.6) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2 dependency-version: 1.39.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: aws - dependency-name: github.com/aws/aws-sdk-go-v2/config dependency-version: 1.31.12 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: aws - dependency-name: github.com/aws/aws-sdk-go-v2/credentials dependency-version: 1.18.16 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aws - dependency-name: github.com/aws/aws-sdk-go-v2/service/sts dependency-version: 1.38.6 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: aws ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: pincher95 --- go.mod | 24 ++++++++++++------------ go.sum | 52 ++++++++++++++++++++++++++-------------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/go.mod b/go.mod index 1f4be428..92fba81f 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,10 @@ go 1.24.1 require ( github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/aws/aws-sdk-go-v2 v1.37.2 - github.com/aws/aws-sdk-go-v2/config v1.30.3 - github.com/aws/aws-sdk-go-v2/credentials v1.18.3 - github.com/aws/aws-sdk-go-v2/service/sts v1.36.0 + github.com/aws/aws-sdk-go-v2 v1.39.2 + github.com/aws/aws-sdk-go-v2/config v1.31.12 + github.com/aws/aws-sdk-go-v2/credentials v1.18.16 + github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 github.com/blang/semver/v4 v4.0.0 github.com/imdario/mergo v0.3.13 github.com/prometheus/client_golang v1.23.0 @@ -18,15 +18,15 @@ require ( require ( github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.2 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.27.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.32.0 // indirect - github.com/aws/smithy-go v1.22.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 // indirect + github.com/aws/smithy-go v1.23.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect diff --git a/go.sum b/go.sum index 3edf5138..7795b67c 100644 --- a/go.sum +++ b/go.sum @@ -2,32 +2,32 @@ github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjH github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/aws/aws-sdk-go-v2 v1.37.2 h1:xkW1iMYawzcmYFYEV0UCMxc8gSsjCGEhBXQkdQywVbo= -github.com/aws/aws-sdk-go-v2 v1.37.2/go.mod h1:9Q0OoGQoboYIAJyslFyF1f5K1Ryddop8gqMhWx/n4Wg= -github.com/aws/aws-sdk-go-v2/config v1.30.3 h1:utupeVnE3bmB221W08P0Moz1lDI3OwYa2fBtUhl7TCc= -github.com/aws/aws-sdk-go-v2/config v1.30.3/go.mod h1:NDGwOEBdpyZwLPlQkpKIO7frf18BW8PaCmAM9iUxQmI= -github.com/aws/aws-sdk-go-v2/credentials v1.18.3 h1:ptfyXmv+ooxzFwyuBth0yqABcjVIkjDL0iTYZBSbum8= -github.com/aws/aws-sdk-go-v2/credentials v1.18.3/go.mod h1:Q43Nci++Wohb0qUh4m54sNln0dbxJw8PvQWkrwOkGOI= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.2 h1:nRniHAvjFJGUCl04F3WaAj7qp/rcz5Gi1OVoj5ErBkc= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.2/go.mod h1:eJDFKAMHHUvv4a0Zfa7bQb//wFNUXGrbFpYRCHe2kD0= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.2 h1:sPiRHLVUIIQcoVZTNwqQcdtjkqkPopyYmIX0M5ElRf4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.2/go.mod h1:ik86P3sgV+Bk7c1tBFCwI3VxMoSEwl4YkRB9xn1s340= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.2 h1:ZdzDAg075H6stMZtbD2o+PyB933M/f20e9WmCBC17wA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.2/go.mod h1:eE1IIzXG9sdZCB0pNNpMpsYTLl4YdOQD3njiVN1e/E4= +github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I= +github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2/config v1.31.12 h1:pYM1Qgy0dKZLHX2cXslNacbcEFMkDMl+Bcj5ROuS6p8= +github.com/aws/aws-sdk-go-v2/config v1.31.12/go.mod h1:/MM0dyD7KSDPR+39p9ZNVKaHDLb9qnfDurvVS2KAhN8= +github.com/aws/aws-sdk-go-v2/credentials v1.18.16 h1:4JHirI4zp958zC026Sm+V4pSDwW4pwLefKrc0bF2lwI= +github.com/aws/aws-sdk-go-v2/credentials v1.18.16/go.mod h1:qQMtGx9OSw7ty1yLclzLxXCRbrkjWAM7JnObZjmCB7I= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 h1:Mv4Bc0mWmv6oDuSWTKnk+wgeqPL5DRFu5bQL9BGPQ8Y= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9/go.mod h1:IKlKfRppK2a1y0gy1yH6zD+yX5uplJ6UuPlgd48dJiQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 h1:se2vOWGD3dWQUtfn4wEjRQJb1HK1XsNIt825gskZ970= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9/go.mod h1:hijCGH2VfbZQxqCDN7bwz/4dzxV+hkyhjawAtdPWKZA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 h1:6RBnKZLkJM4hQ+kN6E7yWFveOTg8NLPHAkqrs4ZPlTU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9/go.mod h1:V9rQKRmK7AWuEsOMnHzKj8WyrIir1yUJbZxDuZLFvXI= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0 h1:6+lZi2JeGKtCraAj1rpoZfKqnQ9SptseRZioejfUOLM= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0/go.mod h1:eb3gfbVIxIoGgJsi9pGne19dhCBpK6opTYpQqAmdy44= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.2 h1:oxmDEO14NBZJbK/M8y3brhMFEIGN4j8a6Aq8eY0sqlo= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.2/go.mod h1:4hH+8QCrk1uRWDPsVfsNDUup3taAjO8Dnx63au7smAU= -github.com/aws/aws-sdk-go-v2/service/sso v1.27.0 h1:j7/jTOjWeJDolPwZ/J4yZ7dUsxsWZEsxNwH5O7F8eEA= -github.com/aws/aws-sdk-go-v2/service/sso v1.27.0/go.mod h1:M0xdEPQtgpNT7kdAX4/vOAPkFj60hSQRb7TvW9B0iug= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.32.0 h1:ywQF2N4VjqX+Psw+jLjMmUL2g1RDHlvri3NxHA08MGI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.32.0/go.mod h1:Z+qv5Q6b7sWiclvbJyPSOT1BRVU9wfSUPaqQzZ1Xg3E= -github.com/aws/aws-sdk-go-v2/service/sts v1.36.0 h1:bRP/a9llXSSgDPk7Rqn5GD/DQCGo6uk95plBFKoXt2M= -github.com/aws/aws-sdk-go-v2/service/sts v1.36.0/go.mod h1:tgBsFzxwl65BWkuJ/x2EUs59bD4SfYKgikvFDJi1S58= -github.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw= -github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 h1:5r34CgVOD4WZudeEKZ9/iKpiT6cM1JyEROpXjOcdWv8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9/go.mod h1:dB12CEbNWPbzO2uC6QSWHteqOg4JfBVJOojbAoAUb5I= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 h1:A1oRkiSQOWstGh61y4Wc/yQ04sqrQZr1Si/oAXj20/s= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.6/go.mod h1:5PfYspyCU5Vw1wNPsxi15LZovOnULudOQuVxphSflQA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 h1:5fm5RTONng73/QA73LhCNR7UT9RpFH3hR6HWL6bIgVY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1/go.mod h1:xBEjWD13h+6nq+z4AkqSfSvqRKFgDIQeaMguAJndOWo= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 h1:p3jIvqYwUZgu/XYeI48bJxOhvm47hZb5HUQ0tn6Q9kA= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.6/go.mod h1:WtKK+ppze5yKPkZ0XwqIVWD4beCwv056ZbPQNoeHqM8= +github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= +github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= @@ -82,10 +82,10 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= From 4e3e45eac129a1f3b3e7ebeca71e9072db45c7ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:48:22 -0400 Subject: [PATCH 06/21] Bump actions/checkout from 4.2.2 to 5.0.0 (#1085) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 5.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/11bd71901bbe5b1630ceea73d27597364c9af683...08c6903cd8c0fde910a37f88322edcfb5dd907a8) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: pincher95 --- .github/workflows/ci.yml | 10 +++++----- .github/workflows/container_description.yml | 4 ++-- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/mixin.yml | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f3d05c2..7038ffc5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: # should also be updated. image: quay.io/prometheus/golang-builder:1.23-base steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7 - uses: ./.github/promci/actions/setup_environment - run: make GO_ONLY=1 SKIP_GOLANGCI_LINT=1 @@ -33,7 +33,7 @@ jobs: matrix: thread: [ 0, 1, 2 ] steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7 - uses: ./.github/promci/actions/build with: @@ -59,7 +59,7 @@ jobs: # Whenever the Go version is updated here, .promu.yml # should also be updated. steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7 - uses: ./.github/promci/actions/build with: @@ -76,7 +76,7 @@ jobs: || (github.event_name == 'push' && github.event.ref == 'refs/heads/master') steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7 - uses: ./.github/promci/actions/publish_main with: @@ -94,7 +94,7 @@ jobs: if: | (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7 - uses: ./.github/promci/actions/publish_release with: diff --git a/.github/workflows/container_description.yml b/.github/workflows/container_description.yml index 7de8bb8d..c7c7ac77 100644 --- a/.github/workflows/container_description.yml +++ b/.github/workflows/container_description.yml @@ -18,7 +18,7 @@ jobs: if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks. steps: - name: git checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Set docker hub repo name @@ -42,7 +42,7 @@ jobs: if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks. steps: - name: git checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Set quay.io org name diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index a7eba347..e599756c 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Install Go uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 with: diff --git a/.github/workflows/mixin.yml b/.github/workflows/mixin.yml index a4f3f0dc..93acad5f 100644 --- a/.github/workflows/mixin.yml +++ b/.github/workflows/mixin.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Go uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 with: From a6bc1dafb4490b49198339de85b4e988fc4961b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:51:52 -0400 Subject: [PATCH 07/21] Bump github.com/prometheus/client_golang from 1.23.0 to 1.23.2 (#1084) Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.23.0 to 1.23.2. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.23.0...v1.23.2) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-version: 1.23.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: pincher95 --- go.mod | 17 +++++++++-------- go.sum | 38 ++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 92fba81f..99492d31 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,8 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 github.com/blang/semver/v4 v4.0.0 github.com/imdario/mergo v0.3.13 - github.com/prometheus/client_golang v1.23.0 - github.com/prometheus/common v0.65.0 + github.com/prometheus/client_golang v1.23.2 + github.com/prometheus/common v0.66.1 github.com/prometheus/exporter-toolkit v0.14.0 go.yaml.in/yaml/v3 v3.0.4 ) @@ -39,12 +39,13 @@ require ( github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/procfs v0.16.1 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - golang.org/x/crypto v0.38.0 // indirect - golang.org/x/net v0.40.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + golang.org/x/crypto v0.41.0 // indirect + golang.org/x/net v0.43.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.14.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.25.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 7795b67c..529c21bd 100644 --- a/go.sum +++ b/go.sum @@ -64,12 +64,12 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc= -github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= -github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg= github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= @@ -78,28 +78,30 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From a4e32b44db2020165eca938e72a1b338060e9cb4 Mon Sep 17 00:00:00 2001 From: Joe Adams Date: Thu, 12 Jun 2025 13:21:14 -0400 Subject: [PATCH 08/21] Do not log input URL string The error itself already has the sanitized URL so there is no need to log the sensitive input string. Signed-off-by: Joe Adams Signed-off-by: pincher95 --- collector/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collector/util.go b/collector/util.go index fc1eaaa6..b0bfd2ac 100644 --- a/collector/util.go +++ b/collector/util.go @@ -29,7 +29,7 @@ func getURL(ctx context.Context, hc *http.Client, log *slog.Logger, u string) ([ resp, err := hc.Do(req) if err != nil { - return nil, fmt.Errorf("failed to get %s: %v", u, err) + return nil, err } defer func() { From ac8dbf35442ed6a8223bf5e69d9618ed3939fb8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Oct 2025 01:52:59 +0000 Subject: [PATCH 09/21] Bump github.com/prometheus/exporter-toolkit from 0.14.0 to 0.14.1 Bumps [github.com/prometheus/exporter-toolkit](https://github.com/prometheus/exporter-toolkit) from 0.14.0 to 0.14.1. - [Release notes](https://github.com/prometheus/exporter-toolkit/releases) - [Commits](https://github.com/prometheus/exporter-toolkit/compare/v0.14.0...v0.14.1) --- updated-dependencies: - dependency-name: github.com/prometheus/exporter-toolkit dependency-version: 0.14.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: pincher95 --- go.mod | 18 +++++++++--------- go.sum | 37 ++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 99492d31..b0d8286c 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/imdario/mergo v0.3.13 github.com/prometheus/client_golang v1.23.2 github.com/prometheus/common v0.66.1 - github.com/prometheus/exporter-toolkit v0.14.0 + github.com/prometheus/exporter-toolkit v0.15.0 go.yaml.in/yaml/v3 v3.0.4 ) @@ -29,7 +29,7 @@ require ( github.com/aws/smithy-go v1.23.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mdlayher/socket v0.4.1 // indirect @@ -39,13 +39,13 @@ require ( github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/procfs v0.16.1 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/net v0.43.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + golang.org/x/crypto v0.43.0 // indirect + golang.org/x/net v0.45.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.37.0 // indirect + golang.org/x/text v0.30.0 // indirect + golang.org/x/time v0.13.0 // indirect google.golang.org/protobuf v1.36.8 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 529c21bd..8d9b6155 100644 --- a/go.sum +++ b/go.sum @@ -34,12 +34,11 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= +github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= @@ -70,8 +69,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= -github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg= -github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA= +github.com/prometheus/exporter-toolkit v0.15.0 h1:Pcle5sSViwR1x0gdPd0wtYrPQENBieQAM7TmT0qtb2U= +github.com/prometheus/exporter-toolkit v0.15.0/go.mod h1:OyRWd2iTo6Xge9Kedvv0IhCrJSBu36JCfJ2yVniRIYk= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -84,30 +83,30 @@ github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8 github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= +golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= +golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM= +golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 873bf984b17ff3c2a8b9cee3c9d0c608a50a1409 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Oct 2025 06:17:08 +0000 Subject: [PATCH 10/21] Bump github.com/prometheus/common from 0.65.0 to 0.66.1 Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.65.0 to 0.66.1. - [Release notes](https://github.com/prometheus/common/releases) - [Changelog](https://github.com/prometheus/common/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/common/compare/v0.65.0...v0.66.1) --- updated-dependencies: - dependency-name: github.com/prometheus/common dependency-version: 0.66.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: pincher95 --- go.mod | 8 ++++---- go.sum | 26 ++++++++++++++++---------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index b0d8286c..11b48001 100644 --- a/go.mod +++ b/go.mod @@ -11,13 +11,13 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/imdario/mergo v0.3.13 github.com/prometheus/client_golang v1.23.2 - github.com/prometheus/common v0.66.1 + github.com/prometheus/common v0.67.1 github.com/prometheus/exporter-toolkit v0.15.0 go.yaml.in/yaml/v3 v3.0.4 ) require ( - github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 // indirect @@ -42,10 +42,10 @@ require ( go.yaml.in/yaml/v2 v2.4.3 // indirect golang.org/x/crypto v0.43.0 // indirect golang.org/x/net v0.45.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/oauth2 v0.31.0 // indirect golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.37.0 // indirect golang.org/x/text v0.30.0 // indirect golang.org/x/time v0.13.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/go.sum b/go.sum index 8d9b6155..e3eea2f4 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I= github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= github.com/aws/aws-sdk-go-v2/config v1.31.12 h1:pYM1Qgy0dKZLHX2cXslNacbcEFMkDMl+Bcj5ROuS6p8= @@ -67,8 +67,8 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= +github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= github.com/prometheus/exporter-toolkit v0.15.0 h1:Pcle5sSViwR1x0gdPd0wtYrPQENBieQAM7TmT0qtb2U= github.com/prometheus/exporter-toolkit v0.15.0/go.mod h1:OyRWd2iTo6Xge9Kedvv0IhCrJSBu36JCfJ2yVniRIYk= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= @@ -76,7 +76,13 @@ github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlT github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= @@ -91,8 +97,8 @@ golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM= golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= +golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= @@ -101,12 +107,12 @@ golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 4b339e8077e6a5056a05168bc6a6acdcaacc301f Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Fri, 24 Oct 2025 13:09:27 +0200 Subject: [PATCH 11/21] Update Go (#1088) * Update minimum Go version to 1.24.0. * Update build to Go 1.25. * Cleanup disabled CircleCI pipeline. Signed-off-by: SuperQ Signed-off-by: pincher95 --- .circleci/config.yml | 36 ------------------------------------ .github/workflows/ci.yml | 2 +- .github/workflows/mixin.yml | 2 +- .promu.yml | 2 +- go.mod | 2 +- 5 files changed, 4 insertions(+), 40 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 066521b3..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- -# This project has switched to GitHub actions. -# Circle CI is not disabled repository-wise so that previous pull requests -# continue working. -# This file does not generate any CircleCI workflow. - -version: 2.1 - -executors: - - golang: - docker: - - image: busybox - -jobs: - noopjob: - executor: golang - - steps: - - run: - command: "true" - - -workflows: - version: 2 - elasticsearch_exporter: - jobs: - - noopjob - triggers: - - schedule: - cron: "0 0 30 2 *" - filters: - branches: - only: - - main - - master diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7038ffc5..273fdccc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: container: # Whenever the Go version is updated here, .promu.yml # should also be updated. - image: quay.io/prometheus/golang-builder:1.23-base + image: quay.io/prometheus/golang-builder:1.25-base steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7 diff --git a/.github/workflows/mixin.yml b/.github/workflows/mixin.yml index 93acad5f..aa973b0b 100644 --- a/.github/workflows/mixin.yml +++ b/.github/workflows/mixin.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 with: - go-version: 1.23.x + go-version: 1.25.x - name: Install dependencies run: | go install github.com/google/go-jsonnet/cmd/jsonnet@v0.20.0 diff --git a/.promu.yml b/.promu.yml index b53c4f24..12606999 100644 --- a/.promu.yml +++ b/.promu.yml @@ -1,7 +1,7 @@ go: # Whenever the Go version is updated here, # .github/workflows should also be updated. - version: 1.23 + version: 1.25 repository: path: github.com/prometheus-community/elasticsearch_exporter build: diff --git a/go.mod b/go.mod index 11b48001..ec28a01b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/prometheus-community/elasticsearch_exporter -go 1.24.1 +go 1.24.0 require ( github.com/alecthomas/kingpin/v2 v2.4.0 From e376642c7c7fd8ed322241baad8b1ef58cd0c5d2 Mon Sep 17 00:00:00 2001 From: Joe Adams Date: Mon, 27 Oct 2025 21:12:26 -0400 Subject: [PATCH 12/21] Fix mixed value types for disk watermark (#1055) * Fix mixed value types for disk watermark The disk watermark values can be a ratio or percentage according to the docs[1], however when set to a percentage, the defaults become an object and therefore fails to parse. In that case, we really only care about what the user set. Adds a test to confirm a fix for #1044. Fixes #1044 [1] https://www.elastic.co/docs/reference/elasticsearch/configuration-reference/cluster-level-shard-allocation-routing-settings#disk-based-shard-allocation Signed-off-by: Joe Adams * Add missing test fixture Signed-off-by: Joe Adams --------- Signed-off-by: Joe Adams Signed-off-by: pincher95 --- collector/cluster_settings.go | 154 ++- collector/cluster_settings_test.go | 24 + fixtures/settings-8.9.1-watermark.json | 1562 ++++++++++++++++++++++++ 3 files changed, 1678 insertions(+), 62 deletions(-) create mode 100644 fixtures/settings-8.9.1-watermark.json diff --git a/collector/cluster_settings.go b/collector/cluster_settings.go index 10e7a180..af9afca9 100644 --- a/collector/cluster_settings.go +++ b/collector/cluster_settings.go @@ -140,9 +140,9 @@ type clusterSettingsDisk struct { // clusterSettingsWatermark is representation of Elasticsearch Cluster shard routing disk allocation watermark settings type clusterSettingsWatermark struct { - FloodStage string `json:"flood_stage"` - High string `json:"high"` - Low string `json:"low"` + FloodStage interface{} `json:"flood_stage"` + High interface{} `json:"high"` + Low interface{} `json:"low"` } func (c *ClusterSettingsCollector) Update(ctx context.Context, ch chan<- prometheus.Metric) error { @@ -222,80 +222,110 @@ func (c *ClusterSettingsCollector) Update(ctx context.Context, ch chan<- prometh ) // Watermark bytes or ratio metrics - if strings.HasSuffix(merged.Cluster.Routing.Allocation.Disk.Watermark.High, "b") { - flooodStageBytes, err := getValueInBytes(merged.Cluster.Routing.Allocation.Disk.Watermark.FloodStage) - if err != nil { - c.logger.Error("failed to parse flood_stage bytes", "err", err) - } else { - ch <- prometheus.MustNewConstMetric( - clusterSettingsDesc["floodStageBytes"], - prometheus.GaugeValue, - flooodStageBytes, - ) - } - - highBytes, err := getValueInBytes(merged.Cluster.Routing.Allocation.Disk.Watermark.High) - if err != nil { - c.logger.Error("failed to parse high bytes", "err", err) - } else { - ch <- prometheus.MustNewConstMetric( - clusterSettingsDesc["highBytes"], - prometheus.GaugeValue, - highBytes, - ) - } - - lowBytes, err := getValueInBytes(merged.Cluster.Routing.Allocation.Disk.Watermark.Low) - if err != nil { - c.logger.Error("failed to parse low bytes", "err", err) - } else { - ch <- prometheus.MustNewConstMetric( - clusterSettingsDesc["lowBytes"], - prometheus.GaugeValue, - lowBytes, - ) - } - - return nil - } - - // Watermark ratio metrics - floodRatio, err := getValueAsRatio(merged.Cluster.Routing.Allocation.Disk.Watermark.FloodStage) + watermarkFlood, err := parseWatermarkValue(merged.Cluster.Routing.Allocation.Disk.Watermark.FloodStage) if err != nil { - c.logger.Error("failed to parse flood_stage ratio", "err", err) + c.logger.Error("failed to parse flood stage watermark", "err", err) } else { - ch <- prometheus.MustNewConstMetric( - clusterSettingsDesc["floodStageRatio"], - prometheus.GaugeValue, - floodRatio, - ) + if strings.HasSuffix(watermarkFlood, "b") { + floodStageBytes, err := getValueInBytes(watermarkFlood) + if err != nil { + c.logger.Error("failed to parse flood_stage bytes", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["floodStageBytes"], + prometheus.GaugeValue, + floodStageBytes, + ) + } + } else { + floodStageRatio, err := getValueAsRatio(watermarkFlood) + if err != nil { + c.logger.Error("failed to parse flood_stage ratio", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["floodStageRatio"], + prometheus.GaugeValue, + floodStageRatio, + ) + } + } } - highRatio, err := getValueAsRatio(merged.Cluster.Routing.Allocation.Disk.Watermark.High) + watermarkHigh, err := parseWatermarkValue(merged.Cluster.Routing.Allocation.Disk.Watermark.High) if err != nil { - c.logger.Error("failed to parse high ratio", "err", err) + c.logger.Error("failed to parse high watermark", "err", err) } else { - ch <- prometheus.MustNewConstMetric( - clusterSettingsDesc["highRatio"], - prometheus.GaugeValue, - highRatio, - ) + if strings.HasSuffix(watermarkHigh, "b") { + highBytes, err := getValueInBytes(watermarkHigh) + if err != nil { + c.logger.Error("failed to parse high bytes", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["highBytes"], + prometheus.GaugeValue, + highBytes, + ) + } + } else { + highRatio, err := getValueAsRatio(watermarkHigh) + if err != nil { + c.logger.Error("failed to parse high ratio", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["highRatio"], + prometheus.GaugeValue, + highRatio, + ) + } + } } - lowRatio, err := getValueAsRatio(merged.Cluster.Routing.Allocation.Disk.Watermark.Low) + watermarkLow, err := parseWatermarkValue(merged.Cluster.Routing.Allocation.Disk.Watermark.Low) if err != nil { - c.logger.Error("failed to parse low ratio", "err", err) + c.logger.Error("failed to parse low watermark", "err", err) } else { - ch <- prometheus.MustNewConstMetric( - clusterSettingsDesc["lowRatio"], - prometheus.GaugeValue, - lowRatio, - ) + if strings.HasSuffix(watermarkLow, "b") { + lowBytes, err := getValueInBytes(watermarkLow) + if err != nil { + c.logger.Error("failed to parse low bytes", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["lowBytes"], + prometheus.GaugeValue, + lowBytes, + ) + } + } else { + lowRatio, err := getValueAsRatio(watermarkLow) + if err != nil { + c.logger.Error("failed to parse low ratio", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["lowRatio"], + prometheus.GaugeValue, + lowRatio, + ) + } + } } return nil } +func parseWatermarkValue(value interface{}) (string, error) { + switch v := value.(type) { + case string: + return v, nil + case map[string]interface{}: + if val, ok := v["value"].(string); ok { + return val, nil + } + return "", fmt.Errorf("unexpected structure in watermark value: %v", v) + default: + return "", fmt.Errorf("unsupported type for watermark value: %T", v) + } +} + func getValueInBytes(value string) (float64, error) { type UnitValue struct { unit string diff --git a/collector/cluster_settings_test.go b/collector/cluster_settings_test.go index 28de33ec..ee3f15a7 100644 --- a/collector/cluster_settings_test.go +++ b/collector/cluster_settings_test.go @@ -114,6 +114,30 @@ elasticsearch_clustersettings_allocation_watermark_high_bytes 2.147483648e+11 # HELP elasticsearch_clustersettings_allocation_watermark_low_bytes Low watermark for disk usage in bytes. # TYPE elasticsearch_clustersettings_allocation_watermark_low_bytes gauge elasticsearch_clustersettings_allocation_watermark_low_bytes 5.24288e+07 +`, + }, + { + name: "8.9.1-persistent-watermark-percent", + file: "../fixtures/settings-8.9.1-watermark.json", + want: ` +# HELP elasticsearch_clustersettings_stats_max_shards_per_node Current maximum number of shards per node setting. +# TYPE elasticsearch_clustersettings_stats_max_shards_per_node gauge +elasticsearch_clustersettings_stats_max_shards_per_node 1000 +# HELP elasticsearch_clustersettings_stats_shard_allocation_enabled Current mode of cluster wide shard routing allocation settings. +# TYPE elasticsearch_clustersettings_stats_shard_allocation_enabled gauge +elasticsearch_clustersettings_stats_shard_allocation_enabled 0 +# HELP elasticsearch_clustersettings_allocation_threshold_enabled Is disk allocation decider enabled. +# TYPE elasticsearch_clustersettings_allocation_threshold_enabled gauge +elasticsearch_clustersettings_allocation_threshold_enabled 1 +# HELP elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio Flood stage watermark as a ratio. +# TYPE elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio gauge +elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio 0.96 +# HELP elasticsearch_clustersettings_allocation_watermark_high_ratio High watermark for disk usage as a ratio. +# TYPE elasticsearch_clustersettings_allocation_watermark_high_ratio gauge +elasticsearch_clustersettings_allocation_watermark_high_ratio 0.92 +# HELP elasticsearch_clustersettings_allocation_watermark_low_ratio Low watermark for disk usage as a ratio. +# TYPE elasticsearch_clustersettings_allocation_watermark_low_ratio gauge +elasticsearch_clustersettings_allocation_watermark_low_ratio 0.88 `, }, } diff --git a/fixtures/settings-8.9.1-watermark.json b/fixtures/settings-8.9.1-watermark.json new file mode 100644 index 00000000..6002449a --- /dev/null +++ b/fixtures/settings-8.9.1-watermark.json @@ -0,0 +1,1562 @@ +{ + "persistent": { + "cluster": { + "routing": { + "allocation": { + "disk": { + "watermark": { + "low": "88%", + "flood_stage": "96%", + "high": "92%" + } + } + } + } + } + }, + "transient": {}, + "defaults": { + "cluster": { + "max_voting_config_exclusions": "10", + "auto_shrink_voting_configuration": "true", + "discovery_configuration_check": { + "interval": "30000ms" + }, + "election": { + "duration": "500ms", + "initial_timeout": "100ms", + "max_timeout": "10s", + "back_off_time": "100ms", + "strategy": "supports_voting_only" + }, + "no_master_block": "write", + "persistent_tasks": { + "allocation": { + "enable": "all", + "recheck_interval": "30s" + } + }, + "blocks": { + "read_only_allow_delete": "false", + "read_only": "false" + }, + "remote": { + "initial_connect_timeout": "30s", + "node": { + "attr": "" + }, + "connections_per_cluster": "3" + }, + "follower_lag": { + "timeout": "90000ms" + }, + "routing": { + "use_adaptive_replica_selection": "true", + "rebalance": { + "enable": "all" + }, + "allocation": { + "enforce_default_tier_preference": "true", + "node_concurrent_incoming_recoveries": "2", + "node_initial_primaries_recoveries": "4", + "desired_balance": { + "progress_log_interval": "1m", + "undesired_allocations": { + "log_interval": "1h", + "threshold": "0.1" + } + }, + "same_shard": { + "host": "false" + }, + "total_shards_per_node": "-1", + "type": "desired_balance", + "disk": { + "threshold_enabled": "true", + "reroute_interval": "60s", + "watermark": { + "flood_stage": { + "frozen": "95%", + "frozen.max_headroom": "20GB", + "max_headroom": "-1" + }, + "high": { + "max_headroom": "-1" + }, + "low": { + "max_headroom": "-1" + }, + "enable_for_single_data_node": "true" + } + }, + "awareness": { + "attributes": [] + }, + "balance": { + "disk_usage": "2.0E-11", + "index": "0.55", + "threshold": "1.0", + "shard": "0.45", + "write_load": "10.0" + }, + "enable": "all", + "node_concurrent_outgoing_recoveries": "2", + "allow_rebalance": "indices_all_active", + "cluster_concurrent_rebalance": "2", + "node_concurrent_recoveries": "2" + } + }, + "indices": { + "tombstones": { + "size": "500" + }, + "close": { + "enable": "true" + } + }, + "join_validation": { + "cache_timeout": "60s" + }, + "max_shards_per_node.frozen": "3000", + "nodes": { + "reconnect_interval": "10s" + }, + "service": { + "master_service_starvation_logging_threshold": "5m", + "slow_master_task_logging_threshold": "10s", + "slow_task_logging_threshold": "30s" + }, + "publish": { + "timeout": "30000ms", + "info_timeout": "10000ms" + }, + "name": "docker-cluster", + "fault_detection": { + "leader_check": { + "interval": "1000ms", + "timeout": "10000ms", + "retry_count": "3" + }, + "follower_check": { + "interval": "1000ms", + "timeout": "10000ms", + "retry_count": "3" + } + }, + "max_shards_per_node": "1000", + "initial_master_nodes": [], + "deprecation_indexing": { + "enabled": "true", + "x_opaque_id_used": { + "enabled": "true" + } + }, + "snapshot": { + "info": { + "max_concurrent_fetches": "5" + } + }, + "info": { + "update": { + "interval": "30s", + "timeout": "15s" + } + } + }, + "stack": { + "templates": { + "enabled": "true" + } + }, + "time_series": { + "poll_interval": "5m" + }, + "readiness": { + "port": "-1" + }, + "logger": { + "level": "INFO" + }, + "bootstrap": { + "memory_lock": "false", + "ctrlhandler": "true" + }, + "health_node": { + "transport_action_timeout": "5s" + }, + "ingest": { + "user_agent": { + "cache_size": "1000" + }, + "geoip": { + "cache_size": "1000", + "downloader": { + "endpoint": "https://geoip.elastic.co/v1/database", + "poll": { + "interval": "3d" + }, + "eager": { + "download": "false" + }, + "enabled": "true" + } + }, + "grok": { + "watchdog": { + "max_execution_time": "1s", + "interval": "1s" + } + } + }, + "network": { + "host": [ + "0.0.0.0" + ], + "tcp": { + "reuse_address": "true", + "keep_count": "-1", + "keep_interval": "-1", + "no_delay": "true", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "keep_idle": "-1", + "send_buffer_size": "-1b" + }, + "bind_host": [ + "0.0.0.0" + ], + "server": "true", + "breaker": { + "inflight_requests": { + "limit": "100%", + "overhead": "2.0" + } + }, + "publish_host": [ + "0.0.0.0" + ] + }, + "searchable_snapshots": { + "blob_cache": { + "periodic_cleanup": { + "interval": "1h", + "batch_size": "100", + "pit_keep_alive": "10m", + "retention_period": "1h" + } + } + }, + "path": { + "data": [], + "logs": "/usr/share/elasticsearch/logs", + "shared_data": "", + "home": "/usr/share/elasticsearch", + "repo": [] + }, + "search": { + "default_search_timeout": "-1", + "max_open_scroll_context": "500", + "max_buckets": "65536", + "max_async_search_response_size": "10mb", + "keep_alive_interval": "1m", + "max_keep_alive": "24h", + "highlight": { + "term_vector_multi_value": "true" + }, + "default_allow_partial_results": "true", + "low_level_cancellation": "true", + "allow_expensive_queries": "true", + "check_ccs_compatibility": "false", + "default_keep_alive": "5m", + "aggs": { + "rewrite_to_filter_by_filter": "true", + "tdigest_execution_hint": "DEFAULT" + } + }, + "security": { + "manager": { + "filter_bad_defaults": "true" + } + }, + "ccr": { + "wait_for_metadata_timeout": "60s", + "indices": { + "recovery": { + "recovery_activity_timeout": "60s", + "chunk_size": "1mb", + "internal_action_timeout": "60s", + "max_bytes_per_sec": "40mb", + "max_concurrent_file_chunks": "5" + } + }, + "auto_follow": { + "wait_for_metadata_timeout": "60s" + } + }, + "repositories": { + "fs": { + "chunk_size": "9223372036854775807b", + "location": "" + }, + "url": { + "supported_protocols": [ + "http", + "https", + "ftp", + "file", + "jar" + ], + "allowed_urls": [], + "url": "http:" + } + }, + "action": { + "auto_create_index": "true", + "search": { + "pre_filter_shard_size": { + "default": "128" + }, + "shard_count": { + "limit": "9223372036854775807" + } + }, + "destructive_requires_name": "true" + }, + "client": { + "type": "node" + }, + "enrich": { + "max_force_merge_attempts": "3", + "cleanup_period": "15m", + "fetch_size": "10000", + "cache_size": "1000", + "coordinator_proxy": { + "max_concurrent_requests": "8", + "max_lookups_per_request": "128", + "queue_capacity": "1024" + }, + "max_concurrent_policy_executions": "50" + }, + "xpack": { + "watcher": { + "execution": { + "scroll": { + "size": "0", + "timeout": "" + }, + "default_throttle_period": "5s" + }, + "internal": { + "ops": { + "bulk": { + "default_timeout": "" + }, + "index": { + "default_timeout": "" + }, + "search": { + "default_timeout": "" + } + } + }, + "thread_pool": { + "queue_size": "1000", + "size": "40" + }, + "index": { + "rest": { + "direct_access": "" + } + }, + "use_ilm_index_management": "true", + "trigger": { + "schedule": { + "ticker": { + "tick_interval": "500ms" + } + } + }, + "enabled": "true", + "input": { + "search": { + "default_timeout": "" + } + }, + "encrypt_sensitive_data": "false", + "transform": { + "search": { + "default_timeout": "" + } + }, + "stop": { + "timeout": "30s" + }, + "watch": { + "scroll": { + "size": "0" + } + }, + "bulk": { + "concurrent_requests": "0", + "flush_interval": "1s", + "size": "1mb", + "actions": "1" + }, + "actions": { + "bulk": { + "default_timeout": "" + }, + "index": { + "default_timeout": "" + } + } + }, + "eql": { + "enabled": "true" + }, + "ent_search": { + "enabled": "true" + }, + "monitoring": { + "migration": { + "decommission_alerts": "false" + }, + "collection": { + "cluster": { + "stats": { + "timeout": "10s" + } + }, + "node": { + "stats": { + "timeout": "10s" + } + }, + "indices": [], + "ccr": { + "stats": { + "timeout": "10s" + } + }, + "enrich": { + "stats": { + "timeout": "10s" + } + }, + "index": { + "stats": { + "timeout": "10s" + }, + "recovery": { + "active_only": "false", + "timeout": "10s" + } + }, + "interval": "10s", + "enabled": "false", + "ml": { + "job": { + "stats": { + "timeout": "10s" + } + } + } + }, + "history": { + "duration": "168h" + }, + "elasticsearch": { + "collection": { + "enabled": "true" + } + }, + "templates": { + "enabled": "true" + } + }, + "graph": { + "enabled": "true" + }, + "searchable": { + "snapshot": { + "allocate_on_rolling_restart": "false", + "cache": { + "range_size": "32mb", + "sync": { + "max_files": "10000", + "interval": "60s", + "shutdown_timeout": "10s" + }, + "recovery_range_size": "128kb" + }, + "shared_cache": { + "recovery_range_size": "128kb", + "region_size": "16mb", + "size": "0", + "min_time_delta": "60s", + "decay": { + "interval": "60s" + }, + "size.max_headroom": "-1", + "range_size": "16mb", + "max_freq": "100" + } + } + }, + "rollup": { + "task_thread_pool": { + "queue_size": "-1", + "size": "1" + } + }, + "searchable_snapshots": { + "cache_fetch_async_thread_pool": { + "core": "0", + "max": "24", + "keep_alive": "30s" + }, + "cache_prewarming_thread_pool": { + "core": "0", + "max": "16", + "keep_alive": "30s" + } + }, + "downsample": { + "thread_pool": { + "queue_size": "256", + "size": "1" + } + }, + "license": { + "upload": { + "types": [ + "standard", + "gold", + "platinum", + "enterprise", + "trial" + ] + }, + "self_generated": { + "type": "basic" + } + }, + "notification": { + "pagerduty": { + "default_account": "" + }, + "webhook": { + "additional_token_enabled": "false" + }, + "email": { + "account": { + "domain_allowlist": [ + "*" + ] + }, + "default_account": "", + "html": { + "sanitization": { + "allow": [ + "body", + "head", + "_tables", + "_links", + "_blocks", + "_formatting", + "img:embedded" + ], + "disallow": [], + "enabled": "true" + } + } + }, + "reporting": { + "retries": "40", + "warning": { + "enabled": "true" + }, + "interval": "15s" + }, + "jira": { + "default_account": "" + }, + "slack": { + "default_account": "" + } + }, + "security": { + "operator_privileges": { + "enabled": "false" + }, + "dls_fls": { + "enabled": "true" + }, + "dls": { + "bitset": { + "cache": { + "size": "10%", + "ttl": "2h" + } + } + }, + "transport": { + "filter": { + "allow": [], + "deny": [], + "enabled": "true" + }, + "ssl": { + "enabled": "false" + } + }, + "ssl": { + "diagnose": { + "trust": "true" + } + }, + "enabled": "false", + "enrollment": { + "enabled": "false" + }, + "filter": { + "always_allow_bound_address": "true" + }, + "encryption": { + "algorithm": "AES/CTR/NoPadding" + }, + "audit": { + "enabled": "false", + "logfile": { + "emit_cluster_name": "false", + "emit_node_id": "true", + "emit_node_name": "false", + "emit_node_host_address": "false", + "emit_cluster_uuid": "true", + "emit_node_host_name": "false", + "events": { + "emit_request_body": "false", + "include": [ + "ACCESS_DENIED", + "ACCESS_GRANTED", + "ANONYMOUS_ACCESS_DENIED", + "AUTHENTICATION_FAILED", + "CONNECTION_DENIED", + "TAMPERED_REQUEST", + "RUN_AS_DENIED", + "RUN_AS_GRANTED", + "SECURITY_CONFIG_CHANGE" + ], + "exclude": [] + } + } + }, + "authc": { + "password_hashing": { + "algorithm": "BCRYPT" + }, + "success_cache": { + "size": "10000", + "enabled": "true", + "expire_after_access": "1h" + }, + "api_key": { + "doc_cache": { + "ttl": "5m" + }, + "cache": { + "hash_algo": "ssha256", + "max_keys": "25000", + "ttl": "24h" + }, + "delete": { + "interval": "24h", + "retention_period": "7d", + "timeout": "-1" + }, + "enabled": "true", + "hashing": { + "algorithm": "PBKDF2" + } + }, + "anonymous": { + "authz_exception": "true", + "roles": [], + "username": "_anonymous" + }, + "run_as": { + "enabled": "true" + }, + "reserved_realm": { + "enabled": "true" + }, + "service_token": { + "cache": { + "hash_algo": "ssha256", + "max_tokens": "100000", + "ttl": "20m" + } + }, + "token": { + "delete": { + "interval": "30m", + "timeout": "-1" + }, + "enabled": "false", + "timeout": "20m" + } + }, + "autoconfiguration": { + "enabled": "true" + }, + "fips_mode": { + "enabled": "false" + }, + "encryption_key": { + "length": "128", + "algorithm": "AES" + }, + "http": { + "filter": { + "allow": [], + "deny": [], + "enabled": "true" + }, + "ssl": { + "enabled": "false" + } + }, + "automata": { + "max_determinized_states": "100000", + "cache": { + "size": "10000", + "ttl": "48h", + "enabled": "true" + } + }, + "user": null, + "authz": { + "timer": { + "indices": { + "enabled": "false", + "threshold": { + "warn": "200ms", + "debug": "20ms", + "info": "100ms" + } + } + }, + "store": { + "privileges": { + "cache": { + "ttl": "24h", + "max_size": "10000" + } + }, + "roles": { + "has_privileges": { + "cache": { + "max_size": "1000" + } + }, + "cache": { + "max_size": "10000" + }, + "negative_lookup_cache": { + "max_size": "10000" + }, + "field_permissions": { + "cache": { + "max_size_in_bytes": "104857600" + } + } + } + } + } + }, + "transform": { + "num_transform_failure_retries": "10", + "transform_scheduler_frequency": "1s" + }, + "ccr": { + "enabled": "true", + "ccr_thread_pool": { + "queue_size": "100", + "size": "32" + } + }, + "idp": { + "privileges": { + "application": "", + "cache": { + "size": "100", + "ttl": "90m" + } + }, + "metadata": { + "signing": { + "keystore": { + "alias": "" + } + } + }, + "slo_endpoint": { + "post": "https:", + "redirect": "https:" + }, + "defaults": { + "nameid_format": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", + "authn_expiry": "5m" + }, + "allowed_nameid_formats": [ + "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" + ], + "contact": { + "given_name": "", + "email": "", + "surname": "" + }, + "organization": { + "display_name": "", + "name": "", + "url": "http:" + }, + "sso_endpoint": { + "post": "https:", + "redirect": "https:" + }, + "entity_id": "", + "signing": { + "keystore": { + "alias": "" + } + }, + "sp": { + "cache": { + "size": "1000", + "ttl": "60m" + }, + "wildcard": { + "path": "wildcard_services.json" + } + }, + "enabled": "false" + }, + "profiling": { + "enabled": "true", + "query": { + "stacktrace": { + "max_slices": "16" + }, + "details": { + "max_slices": "16" + }, + "realtime": "true" + }, + "templates": { + "enabled": "false" + } + }, + "http": { + "tcp": { + "keep_alive": "true" + }, + "default_connection_timeout": "10s", + "proxy": { + "host": "", + "scheme": "", + "port": "0" + }, + "connection_pool_ttl": "-1", + "max_response_size": "10mb", + "whitelist": [ + "*" + ], + "default_read_timeout": "10s" + }, + "autoscaling": { + "memory": { + "monitor": { + "timeout": "15s" + } + } + }, + "applications": { + "behavioral_analytics": { + "ingest": { + "bulk_processor": { + "max_events_per_bulk": "500", + "flush_delay": "10s", + "max_bytes_in_flight": "5%", + "max_number_of_retries": "1" + } + } + } + }, + "ml": { + "utility_thread_pool": { + "core": "1", + "max": "2048", + "keep_alive": "10m" + }, + "max_anomaly_records": "500", + "enable_config_migration": "true", + "max_open_jobs": "512", + "delayed_data_check_freq": "15m", + "min_disk_space_off_heap": "5gb", + "allocated_processors_scale": "1", + "model_repository": "https://ml-models.elastic.co", + "use_auto_machine_memory_percent": "false", + "inference_model": { + "cache_size": "40%", + "time_to_live": "5m" + }, + "nightly_maintenance_requests_per_second": "-1.0", + "node_concurrent_job_allocations": "2", + "max_model_memory_limit": "0b", + "enabled": "true", + "max_lazy_ml_nodes": "0", + "max_ml_node_size": "0b", + "max_machine_memory_percent": "30", + "persist_results_max_retries": "20", + "autodetect_process": "true", + "datafeed_thread_pool": { + "core": "1", + "max": "512", + "keep_alive": "1m" + }, + "max_inference_processors": "50", + "native_inference_comms_thread_pool": { + "core": "3", + "max": "324", + "keep_alive": "1m" + }, + "process_connect_timeout": "10s", + "job_comms_thread_pool": { + "core": "4", + "max": "2048", + "keep_alive": "1m" + } + } + }, + "rest": { + "action": { + "multi": { + "allow_explicit_index": "true" + } + } + }, + "cache": { + "recycler": { + "page": { + "limit": { + "heap": "10%" + }, + "type": "CONCURRENT", + "weight": { + "longs": "1.0", + "ints": "1.0", + "bytes": "1.0", + "objects": "0.1" + } + } + } + }, + "tracing": { + "apm": { + "sanitize_field_names": [ + "password", + "passwd", + "pwd", + "secret", + "*key", + "*token*", + "*session*", + "*credit*", + "*card*", + "*auth*", + "*principal*", + "set-cookie" + ], + "enabled": "false", + "names": { + "include": [], + "exclude": [] + } + } + }, + "async_search": { + "index_cleanup_interval": "1h" + }, + "reindex": { + "remote": { + "whitelist": [] + } + }, + "resource": { + "reload": { + "enabled": "true", + "interval": { + "low": "60s", + "high": "5s", + "medium": "30s" + } + } + }, + "thread_pool": { + "force_merge": { + "queue_size": "-1", + "size": "1" + }, + "search_coordination": { + "queue_size": "1000", + "size": "4" + }, + "snapshot_meta": { + "core": "1", + "max": "24", + "keep_alive": "30s" + }, + "fetch_shard_started": { + "core": "1", + "max": "16", + "keep_alive": "5m" + }, + "estimated_time_interval.warn_threshold": "5s", + "scheduler": { + "warn_threshold": "5s" + }, + "cluster_coordination": { + "queue_size": "-1", + "size": "1" + }, + "search": { + "queue_size": "1000", + "size": "13" + }, + "fetch_shard_store": { + "core": "1", + "max": "16", + "keep_alive": "5m" + }, + "flush": { + "core": "1", + "max": "4", + "keep_alive": "5m" + }, + "vectortile": { + "queue_size": "-1", + "size": "1" + }, + "get": { + "queue_size": "1000", + "size": "13" + }, + "system_read": { + "queue_size": "2000", + "size": "4" + }, + "system_critical_read": { + "queue_size": "2000", + "size": "4" + }, + "estimated_time_interval": "200ms", + "write": { + "queue_size": "10000", + "size": "8" + }, + "system_critical_write": { + "queue_size": "1500", + "size": "4" + }, + "refresh": { + "core": "1", + "max": "4", + "keep_alive": "5m" + }, + "repository_azure": { + "core": "0", + "max": "5", + "keep_alive": "30s" + }, + "system_write": { + "queue_size": "1000", + "size": "4" + }, + "generic": { + "core": "4", + "max": "128", + "keep_alive": "30s" + }, + "warmer": { + "core": "1", + "max": "4", + "keep_alive": "5m" + }, + "auto_complete": { + "queue_size": "100", + "size": "2" + }, + "azure_event_loop": { + "core": "0", + "max": "1", + "keep_alive": "30s" + }, + "profiling": { + "core": "0", + "max": "1", + "keep_alive": "30m" + }, + "management": { + "core": "1", + "max": "5", + "keep_alive": "5m" + }, + "analyze": { + "queue_size": "16", + "size": "1" + }, + "snapshot": { + "core": "1", + "max": "10", + "keep_alive": "5m" + }, + "search_throttled": { + "queue_size": "100", + "size": "1" + } + }, + "health": { + "node": { + "enabled": "true" + }, + "master_history": { + "has_master_lookup_timeframe": "30s", + "identity_changes_threshold": "4", + "no_master_transitions_threshold": "4" + }, + "ilm": { + "max_time_on_action": "1d", + "max_time_on_step": "1d", + "max_retries_per_step": "100" + }, + "reporting": { + "local": { + "monitor": { + "interval": "30s" + } + } + } + }, + "index": { + "codec": "default", + "recovery": { + "type": "" + }, + "store": { + "type": "", + "fs": { + "fs_lock": "native" + }, + "preload": [], + "snapshot": { + "uncached_chunk_size": "-1b", + "cache": { + "excluded_file_types": [] + } + } + } + }, + "monitor": { + "jvm": { + "gc": { + "enabled": "true", + "overhead": { + "warn": "50", + "debug": "10", + "info": "25" + }, + "refresh_interval": "1s" + }, + "refresh_interval": "1s" + }, + "process": { + "refresh_interval": "1s" + }, + "os": { + "refresh_interval": "1s" + }, + "fs": { + "health": { + "enabled": "true", + "refresh_interval": "120s", + "slow_path_logging_threshold": "5s" + }, + "refresh_interval": "1s" + } + }, + "runtime_fields": { + "grok": { + "watchdog": { + "max_execution_time": "1s", + "interval": "1s" + } + } + }, + "cluster_state": { + "document_page_size": "1mb" + }, + "transport": { + "tcp": { + "reuse_address": "true", + "keep_count": "-1", + "keep_interval": "-1", + "no_delay": "true", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "keep_idle": "-1", + "send_buffer_size": "-1b" + }, + "bind_host": [], + "connect_timeout": "30s", + "compress": "INDEXING_DATA", + "ping_schedule": "-1", + "connections_per_node": { + "recovery": "2", + "state": "1", + "bulk": "3", + "reg": "6", + "ping": "1" + }, + "tracer": { + "include": [], + "exclude": [ + "internal:coordination/fault_detection/*" + ] + }, + "type": "", + "slow_operation_logging_threshold": "5s", + "type.default": "netty4", + "rst_on_close": "false", + "port": "9300-9399", + "compression_scheme": "LZ4", + "host": [], + "publish_port": "-1", + "publish_host": [], + "netty": { + "receive_predictor_size": "64kb", + "receive_predictor_max": "64kb", + "worker_count": "8", + "receive_predictor_min": "64kb", + "boss_count": "1" + } + }, + "deprecation": { + "skip_deprecated_settings": [] + }, + "script": { + "allowed_contexts": [], + "max_compilations_rate": "150/5m", + "cache": { + "max_size": "3000", + "expire": "0ms" + }, + "painless": { + "regex": { + "enabled": "limited", + "limit-factor": "6" + } + }, + "max_size_in_bytes": "65535", + "allowed_types": [], + "disable_max_compilations_rate": "false" + }, + "indexing_pressure": { + "memory": { + "limit": "10%" + } + }, + "node": { + "bandwidth": { + "recovery": { + "disk": { + "write": "-1", + "read": "-1" + }, + "factor": { + "write": "0.4", + "read": "0.4" + }, + "operator": { + "factor.read": "0.4", + "factor.write": "0.4", + "factor": "0.4", + "factor.max_overcommit": "100.0" + }, + "network": "-1" + } + }, + "enable_lucene_segment_infos_trace": "false", + "roles": [ + "data", + "data_cold", + "data_content", + "data_frozen", + "data_hot", + "data_warm", + "ingest", + "master", + "ml", + "remote_cluster_client", + "transform" + ], + "_internal": { + "default_refresh_interval": "1s" + }, + "name": "e3ce5021e045", + "external_id": "", + "id": { + "seed": "0" + }, + "processors": "8.0", + "store": { + "allow_mmap": "true" + }, + "attr": { + "xpack": { + "installed": "true" + }, + "ml": { + "max_jvm_size": "1073741824", + "allocated_processors": "8", + "machine_memory": "2147483648", + "allocated_processors_double": "8.0" + } + }, + "portsfile": "false" + }, + "indices": { + "replication": { + "retry_timeout": "60s", + "initial_retry_backoff_bound": "50ms" + }, + "cache": { + "cleanup_interval": "1m" + }, + "mapping": { + "dynamic_timeout": "30s", + "max_in_flight_updates": "10" + }, + "memory": { + "interval": "5s", + "max_index_buffer_size": "-1", + "shard_inactive_time": "5m", + "index_buffer_size": "10%", + "min_index_buffer_size": "48mb" + }, + "breaker": { + "request": { + "limit": "60%", + "type": "memory", + "overhead": "1.0" + }, + "total": { + "limit": "95%", + "use_real_memory": "true" + }, + "fielddata": { + "limit": "40%", + "type": "memory", + "overhead": "1.03" + }, + "type": "hierarchy" + }, + "write_ack_delay_interval": "0ms", + "query": { + "bool": { + "max_nested_depth": "30", + "max_clause_count": "4096" + }, + "query_string": { + "analyze_wildcard": "false", + "allowLeadingWildcard": "true" + } + }, + "id_field_data": { + "enabled": "false" + }, + "recovery": { + "internal_action_retry_timeout": "1m", + "recovery_activity_timeout": "1800000ms", + "retry_delay_network": "5s", + "internal_action_timeout": "15m", + "max_concurrent_snapshot_file_downloads_per_node": "25", + "retry_delay_state_sync": "500ms", + "max_concurrent_snapshot_file_downloads": "5", + "internal_action_long_timeout": "1800000ms", + "max_concurrent_operations": "1", + "use_snapshots": "true", + "max_bytes_per_sec": "40mb", + "max_concurrent_file_chunks": "2" + }, + "requests": { + "cache": { + "size": "1%", + "expire": "0ms" + } + }, + "store": { + "delete": { + "shard": { + "timeout": "30s" + } + }, + "shard_lock_retry": { + "interval": "1s", + "timeout": "1m" + } + }, + "analysis": { + "hunspell": { + "dictionary": { + "ignore_case": "false", + "lazy": "false" + } + } + }, + "queries": { + "cache": { + "count": "10000", + "size": "10%", + "all_segments": "false" + } + }, + "lifecycle": { + "poll_interval": "10m", + "rollover": { + "only_if_has_documents": "true" + }, + "step": { + "master_timeout": "30s" + }, + "history_index_enabled": "true" + }, + "write_ack_delay_randomness_bound": "70ms", + "fielddata": { + "cache": { + "size": "-1b" + } + } + }, + "master_history": { + "max_age": "30m" + }, + "plugin": { + "mandatory": [] + }, + "ingest_node": { + "transport_action_timeout": "20s" + }, + "slm": { + "health": { + "failed_snapshot_warn_threshold": "5" + }, + "minimum_interval": "15m", + "retention_schedule": "0 30 1 * * ?", + "retention_duration": "1h", + "history_index_enabled": "true" + }, + "discovery": { + "seed_hosts": [], + "unconfigured_bootstrap_timeout": "3s", + "request_peers_timeout": "3000ms", + "initial_state_timeout": "30s", + "cluster_formation_warning_timeout": "10000ms", + "seed_providers": [], + "type": "single-node", + "seed_resolver": { + "max_concurrent_resolvers": "10", + "timeout": "5s" + }, + "find_peers_interval": "1000ms", + "probe": { + "connect_timeout": "30s", + "handshake_timeout": "30s" + } + }, + "http": { + "cors": { + "max-age": "1728000", + "allow-origin": "", + "allow-headers": "X-Requested-With,Content-Type,Content-Length,Authorization,Accept,User-Agent,X-Elastic-Client-Meta", + "allow-credentials": "false", + "allow-methods": "OPTIONS,HEAD,GET,POST,PUT,DELETE", + "enabled": "false" + }, + "max_chunk_size": "8kb", + "compression_level": "3", + "max_initial_line_length": "4kb", + "shutdown_grace_period": "0ms", + "type": "", + "pipelining": { + "max_events": "10000" + }, + "type.default": "netty4", + "host": [], + "publish_port": "-1", + "read_timeout": "0ms", + "max_content_length": "100mb", + "netty": { + "receive_predictor_size": "64kb", + "max_composite_buffer_components": "69905", + "worker_count": "0" + }, + "tcp": { + "reuse_address": "true", + "keep_count": "-1", + "keep_interval": "-1", + "no_delay": "true", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "keep_idle": "-1", + "send_buffer_size": "-1b" + }, + "bind_host": [], + "client_stats": { + "enabled": "true", + "closed_channels": { + "max_age": "5m", + "max_count": "10000" + } + }, + "reset_cookies": "false", + "max_warning_header_count": "-1", + "tracer": { + "include": [], + "exclude": [] + }, + "max_warning_header_size": "-1b", + "detailed_errors": { + "enabled": "true" + }, + "port": "9200-9300", + "max_header_size": "16kb", + "compression": "true", + "publish_host": [] + }, + "write_load_forecaster": { + "max_index_age": "7d" + }, + "gateway": { + "recover_after_data_nodes": "-1", + "expected_data_nodes": "-1", + "write_dangling_indices_info": "true", + "slow_write_logging_threshold": "10s", + "recover_after_time": "0ms" + }, + "snapshot": { + "refresh_repo_uuid_on_restore": "true", + "max_concurrent_operations": "1000" + } + } +} From 7e157c3cdd923f2b4a66f1c419622ec6cd271fb5 Mon Sep 17 00:00:00 2001 From: prombot Date: Fri, 24 Oct 2025 17:49:15 +0000 Subject: [PATCH 13/21] Update common Prometheus files Signed-off-by: prombot Signed-off-by: pincher95 --- .github/workflows/container_description.yml | 4 ++-- .github/workflows/golangci-lint.yml | 13 +++++++++---- Makefile.common | 6 +++++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/container_description.yml b/.github/workflows/container_description.yml index c7c7ac77..7de8bb8d 100644 --- a/.github/workflows/container_description.yml +++ b/.github/workflows/container_description.yml @@ -18,7 +18,7 @@ jobs: if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks. steps: - name: git checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set docker hub repo name @@ -42,7 +42,7 @@ jobs: if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks. steps: - name: git checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set quay.io org name diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index e599756c..75f886d5 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -24,16 +24,21 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false - name: Install Go uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 with: - go-version: 1.24.x + go-version: 1.25.x - name: Install snmp_exporter/generator dependencies run: sudo apt-get update && sudo apt-get -y install libsnmp-dev if: github.repository == 'prometheus/snmp_exporter' + - name: Get golangci-lint version + id: golangci-lint-version + run: echo "version=$(make print-golangci-lint-version)" >> $GITHUB_OUTPUT - name: Lint - uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd # v7.0.0 + uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0 with: args: --verbose - version: v2.1.5 + version: ${{ steps.golangci-lint-version.outputs.version }} diff --git a/Makefile.common b/Makefile.common index 6f61bec4..6762d0f8 100644 --- a/Makefile.common +++ b/Makefile.common @@ -61,7 +61,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_ SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v2.1.5 +GOLANGCI_LINT_VERSION ?= v2.4.0 GOLANGCI_FMT_OPTS ?= # golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. # windows isn't included here because of the path separator being different. @@ -266,6 +266,10 @@ $(GOLANGCI_LINT): | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) endif +.PHONY: common-print-golangci-lint-version +common-print-golangci-lint-version: + @echo $(GOLANGCI_LINT_VERSION) + .PHONY: precheck precheck:: From 7acfdfc22c3d56b988ae765384ac9bb42a95b977 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Tue, 28 Oct 2025 12:08:08 +0100 Subject: [PATCH 14/21] Don't log collector errors (#1050) Avoid logging collector failures at Error level to avoid log spam. Signed-off-by: SuperQ Signed-off-by: pincher95 --- collector/collector.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collector/collector.go b/collector/collector.go index 86e4d70c..dbc41574 100644 --- a/collector/collector.go +++ b/collector/collector.go @@ -185,7 +185,7 @@ func execute(ctx context.Context, name string, c Collector, ch chan<- prometheus if IsNoDataError(err) { logger.Debug("collector returned no data", "name", name, "duration_seconds", duration.Seconds(), "err", err) } else { - logger.Error("collector failed", "name", name, "duration_seconds", duration.Seconds(), "err", err) + logger.Warn("collector failed", "name", name, "duration_seconds", duration.Seconds(), "err", err) } success = 0 } else { From 8b80a7420669ecdb1a02569816df1803593864ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 20:59:47 -0500 Subject: [PATCH 15/21] Bump github.com/prometheus/common from 0.67.1 to 0.67.2 (#1091) Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.67.1 to 0.67.2. - [Release notes](https://github.com/prometheus/common/releases) - [Changelog](https://github.com/prometheus/common/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/common/compare/v0.67.1...v0.67.2) --- updated-dependencies: - dependency-name: github.com/prometheus/common dependency-version: 0.67.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: pincher95 --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index ec28a01b..015140f8 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/imdario/mergo v0.3.13 github.com/prometheus/client_golang v1.23.2 - github.com/prometheus/common v0.67.1 + github.com/prometheus/common v0.67.2 github.com/prometheus/exporter-toolkit v0.15.0 go.yaml.in/yaml/v3 v3.0.4 ) @@ -41,8 +41,8 @@ require ( github.com/xhit/go-str2duration/v2 v2.1.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect golang.org/x/crypto v0.43.0 // indirect - golang.org/x/net v0.45.0 // indirect - golang.org/x/oauth2 v0.31.0 // indirect + golang.org/x/net v0.46.0 // indirect + golang.org/x/oauth2 v0.32.0 // indirect golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.37.0 // indirect golang.org/x/text v0.30.0 // indirect diff --git a/go.sum b/go.sum index e3eea2f4..398aea67 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= -github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= +github.com/prometheus/common v0.67.2 h1:PcBAckGFTIHt2+L3I33uNRTlKTplNzFctXcWhPyAEN8= +github.com/prometheus/common v0.67.2/go.mod h1:63W3KZb1JOKgcjlIr64WW/LvFGAqKPj0atm+knVGEko= github.com/prometheus/exporter-toolkit v0.15.0 h1:Pcle5sSViwR1x0gdPd0wtYrPQENBieQAM7TmT0qtb2U= github.com/prometheus/exporter-toolkit v0.15.0/go.mod h1:OyRWd2iTo6Xge9Kedvv0IhCrJSBu36JCfJ2yVniRIYk= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= @@ -95,10 +95,10 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= -golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM= -golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= -golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= -golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= +golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= From c62a2ac66652c5bad72b5266e8f32df77055c359 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 21:00:19 -0500 Subject: [PATCH 16/21] Bump the aws group with 4 updates (#1090) Bumps the aws group with 4 updates: [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2), [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2), [github.com/aws/aws-sdk-go-v2/credentials](https://github.com/aws/aws-sdk-go-v2) and [github.com/aws/aws-sdk-go-v2/service/sts](https://github.com/aws/aws-sdk-go-v2). Updates `github.com/aws/aws-sdk-go-v2` from 1.39.2 to 1.39.5 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.39.2...v1.39.5) Updates `github.com/aws/aws-sdk-go-v2/config` from 1.31.12 to 1.31.16 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.31.12...config/v1.31.16) Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.18.16 to 1.18.20 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/config/v1.18.20/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.18.16...config/v1.18.20) Updates `github.com/aws/aws-sdk-go-v2/service/sts` from 1.38.6 to 1.39.0 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/sts/v1.38.6...v1.39.0) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2 dependency-version: 1.39.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aws - dependency-name: github.com/aws/aws-sdk-go-v2/config dependency-version: 1.31.16 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aws - dependency-name: github.com/aws/aws-sdk-go-v2/credentials dependency-version: 1.18.20 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aws - dependency-name: github.com/aws/aws-sdk-go-v2/service/sts dependency-version: 1.39.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: aws ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: pincher95 --- go.mod | 26 +++++++++++++------------- go.sum | 52 ++++++++++++++++++++++++++-------------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index 015140f8..095465c1 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,10 @@ go 1.24.0 require ( github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/aws/aws-sdk-go-v2 v1.39.2 - github.com/aws/aws-sdk-go-v2/config v1.31.12 - github.com/aws/aws-sdk-go-v2/credentials v1.18.16 - github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 + github.com/aws/aws-sdk-go-v2 v1.39.5 + github.com/aws/aws-sdk-go-v2/config v1.31.16 + github.com/aws/aws-sdk-go-v2/credentials v1.18.20 + github.com/aws/aws-sdk-go-v2/service/sts v1.39.0 github.com/blang/semver/v4 v4.0.0 github.com/imdario/mergo v0.3.13 github.com/prometheus/client_golang v1.23.2 @@ -18,15 +18,15 @@ require ( require ( github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 // indirect - github.com/aws/smithy-go v1.23.0 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.12 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4 // indirect + github.com/aws/smithy-go v1.23.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-systemd/v22 v22.6.0 // indirect diff --git a/go.sum b/go.sum index 398aea67..75d6bc63 100644 --- a/go.sum +++ b/go.sum @@ -2,32 +2,32 @@ github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjH github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0= github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= -github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I= -github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= -github.com/aws/aws-sdk-go-v2/config v1.31.12 h1:pYM1Qgy0dKZLHX2cXslNacbcEFMkDMl+Bcj5ROuS6p8= -github.com/aws/aws-sdk-go-v2/config v1.31.12/go.mod h1:/MM0dyD7KSDPR+39p9ZNVKaHDLb9qnfDurvVS2KAhN8= -github.com/aws/aws-sdk-go-v2/credentials v1.18.16 h1:4JHirI4zp958zC026Sm+V4pSDwW4pwLefKrc0bF2lwI= -github.com/aws/aws-sdk-go-v2/credentials v1.18.16/go.mod h1:qQMtGx9OSw7ty1yLclzLxXCRbrkjWAM7JnObZjmCB7I= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 h1:Mv4Bc0mWmv6oDuSWTKnk+wgeqPL5DRFu5bQL9BGPQ8Y= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9/go.mod h1:IKlKfRppK2a1y0gy1yH6zD+yX5uplJ6UuPlgd48dJiQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 h1:se2vOWGD3dWQUtfn4wEjRQJb1HK1XsNIt825gskZ970= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9/go.mod h1:hijCGH2VfbZQxqCDN7bwz/4dzxV+hkyhjawAtdPWKZA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 h1:6RBnKZLkJM4hQ+kN6E7yWFveOTg8NLPHAkqrs4ZPlTU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9/go.mod h1:V9rQKRmK7AWuEsOMnHzKj8WyrIir1yUJbZxDuZLFvXI= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 h1:5r34CgVOD4WZudeEKZ9/iKpiT6cM1JyEROpXjOcdWv8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9/go.mod h1:dB12CEbNWPbzO2uC6QSWHteqOg4JfBVJOojbAoAUb5I= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 h1:A1oRkiSQOWstGh61y4Wc/yQ04sqrQZr1Si/oAXj20/s= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.6/go.mod h1:5PfYspyCU5Vw1wNPsxi15LZovOnULudOQuVxphSflQA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 h1:5fm5RTONng73/QA73LhCNR7UT9RpFH3hR6HWL6bIgVY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1/go.mod h1:xBEjWD13h+6nq+z4AkqSfSvqRKFgDIQeaMguAJndOWo= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 h1:p3jIvqYwUZgu/XYeI48bJxOhvm47hZb5HUQ0tn6Q9kA= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.6/go.mod h1:WtKK+ppze5yKPkZ0XwqIVWD4beCwv056ZbPQNoeHqM8= -github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= -github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/aws-sdk-go-v2 v1.39.5 h1:e/SXuia3rkFtapghJROrydtQpfQaaUgd1cUvyO1mp2w= +github.com/aws/aws-sdk-go-v2 v1.39.5/go.mod h1:yWSxrnioGUZ4WVv9TgMrNUeLV3PFESn/v+6T/Su8gnM= +github.com/aws/aws-sdk-go-v2/config v1.31.16 h1:E4Tz+tJiPc7kGnXwIfCyUj6xHJNpENlY11oKpRTgsjc= +github.com/aws/aws-sdk-go-v2/config v1.31.16/go.mod h1:2S9hBElpCyGMifv14WxQ7EfPumgoeCPZUpuPX8VtW34= +github.com/aws/aws-sdk-go-v2/credentials v1.18.20 h1:KFndAnHd9NUuzikHjQ8D5CfFVO+bgELkmcGY8yAw98Q= +github.com/aws/aws-sdk-go-v2/credentials v1.18.20/go.mod h1:9mCi28a+fmBHSQ0UM79omkz6JtN+PEsvLrnG36uoUv0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12 h1:VO3FIM2TDbm0kqp6sFNR0PbioXJb/HzCDW6NtIZpIWE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12/go.mod h1:6C39gB8kg82tx3r72muZSrNhHia9rjGkX7ORaS2GKNE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.12 h1:p/9flfXdoAnwJnuW9xHEAFY22R3A6skYkW19JFF9F+8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.12/go.mod h1:ZTLHakoVCTtW8AaLGSwJ3LXqHD9uQKnOcv1TrpO6u2k= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.12 h1:2lTWFvRcnWFFLzHWmtddu5MTchc5Oj2OOey++99tPZ0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.12/go.mod h1:hI92pK+ho8HVcWMHKHrK3Uml4pfG7wvL86FzO0LVtQQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 h1:xtuxji5CS0JknaXoACOunXOYOQzgfTvGAc9s2QdCJA4= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2/go.mod h1:zxwi0DIR0rcRcgdbl7E2MSOvxDyyXGBlScvBkARFaLQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.12 h1:MM8imH7NZ0ovIVX7D2RxfMDv7Jt9OiUXkcQ+GqywA7M= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.12/go.mod h1:gf4OGwdNkbEsb7elw2Sy76odfhwNktWII3WgvQgQQ6w= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.0 h1:xHXvxst78wBpJFgDW07xllOx0IAzbryrSdM4nMVQ4Dw= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.0/go.mod h1:/e8m+AO6HNPPqMyfKRtzZ9+mBF5/x1Wk8QiDva4m07I= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4 h1:tBw2Qhf0kj4ZwtsVpDiVRU3zKLvjvjgIjHMKirxXg8M= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4/go.mod h1:Deq4B7sRM6Awq/xyOBlxBdgW8/Z926KYNNaGMW2lrkA= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.0 h1:C+BRMnasSYFcgDw8o9H5hzehKzXyAb9GY5v/8bP9DUY= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.0/go.mod h1:4EjU+4mIx6+JqKQkruye+CaigV7alL3thVPfDd9VlMs= +github.com/aws/smithy-go v1.23.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M= +github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= From 2a9bf15c0827904eebbce7f7b640f9b37fc20afa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 21:17:24 -0500 Subject: [PATCH 17/21] Bump golangci/golangci-lint-action from 7.0.0 to 8.0.0 (#1042) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 7.0.0 to 8.0.0. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/1481404843c368bc19ca9406f87d6e0fc97bdcfd...4afd733a84b1f43292c63897423277bb7f4313a9) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: pincher95 From 130e4e44796d94edca249e040a100f0a157fb93a Mon Sep 17 00:00:00 2001 From: prombot Date: Wed, 5 Nov 2025 17:49:15 +0000 Subject: [PATCH 18/21] Update common Prometheus files Signed-off-by: prombot Signed-off-by: pincher95 --- Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index 6762d0f8..143bf03f 100644 --- a/Makefile.common +++ b/Makefile.common @@ -61,7 +61,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_ SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v2.4.0 +GOLANGCI_LINT_VERSION ?= v2.6.0 GOLANGCI_FMT_OPTS ?= # golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. # windows isn't included here because of the path separator being different. From 47c86f87724055f14534658a2de99dfc7fdb1fc5 Mon Sep 17 00:00:00 2001 From: Joe Adams Date: Tue, 4 Nov 2025 21:10:04 -0500 Subject: [PATCH 19/21] Fix release version for config.file Signed-off-by: Joe Adams Signed-off-by: pincher95 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 08bd9851..ea8b24a8 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ elasticsearch_exporter --help | web.telemetry-path | 1.0.2 | Path under which to expose metrics. | /metrics | | aws.region | 1.5.0 | Region for AWS elasticsearch | | | aws.role-arn | 1.6.0 | Role ARN of an IAM role to assume. | | -| config.file | 2.0.0 | Path to a YAML configuration file that defines `auth_modules:` used by the `/probe` multi-target endpoint. Leave unset when not using multi-target mode. | | +| config.file | 1.10.0 | Path to a YAML configuration file that defines `auth_modules:` used by the `/probe` multi-target endpoint. Leave unset when not using multi-target mode. | | | version | 1.0.2 | Show version info on stdout and exit. | | Commandline parameters start with a single `-` for versions less than `1.1.0rc1`. From 37e7b695382c939c04947e8ab7db4178d49dd933 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Wed, 19 Nov 2025 15:33:22 +0100 Subject: [PATCH 20/21] Refactor README (#1095) Move the metrics list to a separate markdown file to reduce the README size below the 25k bytes limit of Dockerhub. Signed-off-by: SuperQ Signed-off-by: pincher95 --- README.md | 186 +--------------------------------------------------- metrics.md | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 185 deletions(-) create mode 100644 metrics.md diff --git a/README.md b/README.md index ea8b24a8..5099b273 100644 --- a/README.md +++ b/README.md @@ -177,191 +177,7 @@ Notes: ### Metrics -| Name | Type | Cardinality | Help | -|----------------------------------------------------------------------|------------|-------------|-----------------------------------------------------------------------------------------------------| -| elasticsearch_breakers_estimated_size_bytes | gauge | 4 | Estimated size in bytes of breaker | -| elasticsearch_breakers_limit_size_bytes | gauge | 4 | Limit size in bytes for breaker | -| elasticsearch_breakers_tripped | counter | 4 | tripped for breaker | -| elasticsearch_cluster_health_active_primary_shards | gauge | 1 | The number of primary shards in your cluster. This is an aggregate total across all indices. | -| elasticsearch_cluster_health_active_shards | gauge | 1 | Aggregate total of all shards across all indices, which includes replica shards. | -| elasticsearch_cluster_health_delayed_unassigned_shards | gauge | 1 | Shards delayed to reduce reallocation overhead | -| elasticsearch_cluster_health_initializing_shards | gauge | 1 | Count of shards that are being freshly created. | -| elasticsearch_cluster_health_number_of_data_nodes | gauge | 1 | Number of data nodes in the cluster. | -| elasticsearch_cluster_health_number_of_in_flight_fetch | gauge | 1 | The number of ongoing shard info requests. | -| elasticsearch_cluster_health_number_of_nodes | gauge | 1 | Number of nodes in the cluster. | -| elasticsearch_cluster_health_number_of_pending_tasks | gauge | 1 | Cluster level changes which have not yet been executed | -| elasticsearch_cluster_health_task_max_waiting_in_queue_millis | gauge | 1 | Max time in millis that a task is waiting in queue. | -| elasticsearch_cluster_health_relocating_shards | gauge | 1 | The number of shards that are currently moving from one node to another node. | -| elasticsearch_cluster_health_status | gauge | 3 | Whether all primary and replica shards are allocated. | -| elasticsearch_cluster_health_unassigned_shards | gauge | 1 | The number of shards that exist in the cluster state, but cannot be found in the cluster itself. | -| elasticsearch_clustersettings_stats_max_shards_per_node | gauge | 0 | Current maximum number of shards per node setting. | -| elasticsearch_clustersettings_allocation_threshold_enabled | gauge | 0 | Is disk allocation decider enabled. | -| elasticsearch_clustersettings_allocation_watermark_flood_stage_bytes | gauge | 0 | Flood stage watermark as in bytes. | -| elasticsearch_clustersettings_allocation_watermark_high_bytes | gauge | 0 | High watermark for disk usage in bytes. | -| elasticsearch_clustersettings_allocation_watermark_low_bytes | gauge | 0 | Low watermark for disk usage in bytes. | -| elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio | gauge | 0 | Flood stage watermark as a ratio. | -| elasticsearch_clustersettings_allocation_watermark_high_ratio | gauge | 0 | High watermark for disk usage as a ratio. | -| elasticsearch_clustersettings_allocation_watermark_low_ratio | gauge | 0 | Low watermark for disk usage as a ratio. | -| elasticsearch_filesystem_data_available_bytes | gauge | 1 | Available space on block device in bytes | -| elasticsearch_filesystem_data_free_bytes | gauge | 1 | Free space on block device in bytes | -| elasticsearch_filesystem_data_size_bytes | gauge | 1 | Size of block device in bytes | -| elasticsearch_filesystem_io_stats_device_operations_count | gauge | 1 | Count of disk operations | -| elasticsearch_filesystem_io_stats_device_read_operations_count | gauge | 1 | Count of disk read operations | -| elasticsearch_filesystem_io_stats_device_write_operations_count | gauge | 1 | Count of disk write operations | -| elasticsearch_filesystem_io_stats_device_read_size_kilobytes_sum | gauge | 1 | Total kilobytes read from disk | -| elasticsearch_filesystem_io_stats_device_write_size_kilobytes_sum | gauge | 1 | Total kilobytes written to disk | -| elasticsearch_ilm_status | gauge | 1 | Current status of ILM. Status can be `STOPPED`, `RUNNING`, `STOPPING`. | -| elasticsearch_ilm_index_status | gauge | 4 | Status of ILM policy for index | -| elasticsearch_indices_active_queries | gauge | 1 | The number of currently active queries | -| elasticsearch_indices_docs | gauge | 1 | Count of documents on this node | -| elasticsearch_indices_docs_deleted | gauge | 1 | Count of deleted documents on this node | -| elasticsearch_indices_deleted_docs_primary | gauge | 1 | Count of deleted documents with only primary shards | -| elasticsearch_indices_docs_primary | gauge | 1 | Count of documents with only primary shards on all nodes | -| elasticsearch_indices_docs_total | gauge | | Count of documents with shards on all nodes | -| elasticsearch_indices_fielddata_evictions | counter | 1 | Evictions from field data | -| elasticsearch_indices_fielddata_memory_size_bytes | gauge | 1 | Field data cache memory usage in bytes | -| elasticsearch_indices_filter_cache_evictions | counter | 1 | Evictions from filter cache | -| elasticsearch_indices_filter_cache_memory_size_bytes | gauge | 1 | Filter cache memory usage in bytes | -| elasticsearch_indices_flush_time_seconds | counter | 1 | Cumulative flush time in seconds | -| elasticsearch_indices_flush_total | counter | 1 | Total flushes | -| elasticsearch_indices_get_exists_time_seconds | counter | 1 | Total time get exists in seconds | -| elasticsearch_indices_get_exists_total | counter | 1 | Total get exists operations | -| elasticsearch_indices_get_missing_time_seconds | counter | 1 | Total time of get missing in seconds | -| elasticsearch_indices_get_missing_total | counter | 1 | Total get missing | -| elasticsearch_indices_get_time_seconds | counter | 1 | Total get time in seconds | -| elasticsearch_indices_get_total | counter | 1 | Total get | -| elasticsearch_indices_indexing_delete_time_seconds_total | counter | 1 | Total time indexing delete in seconds | -| elasticsearch_indices_indexing_delete_total | counter | 1 | Total indexing deletes | -| elasticsearch_indices_index_current | gauge | 1 | The number of documents currently being indexed to an index | -| elasticsearch_indices_indexing_index_time_seconds_total | counter | 1 | Cumulative index time in seconds | -| elasticsearch_indices_indexing_index_total | counter | 1 | Total index calls | -| elasticsearch_indices_mappings_stats_fields | gauge | 1 | Count of fields currently mapped by index | -| elasticsearch_indices_mappings_stats_json_parse_failures_total | counter | 0 | Number of errors while parsing JSON | -| elasticsearch_indices_mappings_stats_scrapes_total | counter | 0 | Current total Elasticsearch Indices Mappings scrapes | -| elasticsearch_indices_mappings_stats_up | gauge | 0 | Was the last scrape of the Elasticsearch Indices Mappings endpoint successful | -| elasticsearch_indices_merges_docs_total | counter | 1 | Cumulative docs merged | -| elasticsearch_indices_merges_total | counter | 1 | Total merges | -| elasticsearch_indices_merges_total_size_bytes_total | counter | 1 | Total merge size in bytes | -| elasticsearch_indices_merges_total_time_seconds_total | counter | 1 | Total time spent merging in seconds | -| elasticsearch_indices_query_cache_cache_total | counter | 1 | Count of query cache | -| elasticsearch_indices_query_cache_cache_size | gauge | 1 | Size of query cache | -| elasticsearch_indices_query_cache_count | counter | 2 | Count of query cache hit/miss | -| elasticsearch_indices_query_cache_evictions | counter | 1 | Evictions from query cache | -| elasticsearch_indices_query_cache_memory_size_bytes | gauge | 1 | Query cache memory usage in bytes | -| elasticsearch_indices_query_cache_total | counter | 1 | Size of query cache total | -| elasticsearch_indices_refresh_time_seconds_total | counter | 1 | Total time spent refreshing in seconds | -| elasticsearch_indices_refresh_total | counter | 1 | Total refreshes | -| elasticsearch_indices_request_cache_count | counter | 2 | Count of request cache hit/miss | -| elasticsearch_indices_request_cache_evictions | counter | 1 | Evictions from request cache | -| elasticsearch_indices_request_cache_memory_size_bytes | gauge | 1 | Request cache memory usage in bytes | -| elasticsearch_indices_search_fetch_time_seconds | counter | 1 | Total search fetch time in seconds | -| elasticsearch_indices_search_fetch_total | counter | 1 | Total number of fetches | -| elasticsearch_indices_search_query_time_seconds | counter | 1 | Total search query time in seconds | -| elasticsearch_indices_search_query_total | counter | 1 | Total number of queries | -| elasticsearch_indices_segments_count | gauge | 1 | Count of index segments on this node | -| elasticsearch_indices_segments_memory_bytes | gauge | 1 | Current memory size of segments in bytes | -| elasticsearch_indices_settings_creation_timestamp_seconds | gauge | 1 | Timestamp of the index creation in seconds | -| elasticsearch_indices_settings_stats_read_only_indices | gauge | 1 | Count of indices that have read_only_allow_delete=true | -| elasticsearch_indices_settings_total_fields | gauge | | Index setting value for index.mapping.total_fields.limit (total allowable mapped fields in a index) | -| elasticsearch_indices_settings_replicas | gauge | | Index setting value for index.replicas | -| elasticsearch_indices_shards_docs | gauge | 3 | Count of documents on this shard | -| elasticsearch_indices_shards_docs_deleted | gauge | 3 | Count of deleted documents on each shard | -| elasticsearch_indices_store_size_bytes | gauge | 1 | Current size of stored index data in bytes | -| elasticsearch_indices_store_size_bytes_primary | gauge | | Current size of stored index data in bytes with only primary shards on all nodes | -| elasticsearch_indices_store_size_bytes_total | gauge | | Current size of stored index data in bytes with all shards on all nodes | -| elasticsearch_indices_store_throttle_time_seconds_total | counter | 1 | Throttle time for index store in seconds | -| elasticsearch_indices_translog_operations | counter | 1 | Total translog operations | -| elasticsearch_indices_translog_size_in_bytes | counter | 1 | Total translog size in bytes | -| elasticsearch_indices_warmer_time_seconds_total | counter | 1 | Total warmer time in seconds | -| elasticsearch_indices_warmer_total | counter | 1 | Total warmer count | -| elasticsearch_jvm_gc_collection_seconds_count | counter | 2 | Count of JVM GC runs | -| elasticsearch_jvm_gc_collection_seconds_sum | counter | 2 | GC run time in seconds | -| elasticsearch_jvm_memory_committed_bytes | gauge | 2 | JVM memory currently committed by area | -| elasticsearch_jvm_memory_max_bytes | gauge | 1 | JVM memory max | -| elasticsearch_jvm_memory_used_bytes | gauge | 2 | JVM memory currently used by area | -| elasticsearch_jvm_memory_pool_used_bytes | gauge | 3 | JVM memory currently used by pool | -| elasticsearch_jvm_memory_pool_max_bytes | counter | 3 | JVM memory max by pool | -| elasticsearch_jvm_memory_pool_peak_used_bytes | counter | 3 | JVM memory peak used by pool | -| elasticsearch_jvm_memory_pool_peak_max_bytes | counter | 3 | JVM memory peak max by pool | -| elasticsearch_os_cpu_percent | gauge | 1 | Percent CPU used by the OS | -| elasticsearch_os_load1 | gauge | 1 | Shortterm load average | -| elasticsearch_os_load5 | gauge | 1 | Midterm load average | -| elasticsearch_os_load15 | gauge | 1 | Longterm load average | -| elasticsearch_process_cpu_percent | gauge | 1 | Percent CPU used by process | -| elasticsearch_process_cpu_seconds_total | counter | 1 | Process CPU time in seconds | -| elasticsearch_process_mem_resident_size_bytes | gauge | 1 | Resident memory in use by process in bytes | -| elasticsearch_process_mem_share_size_bytes | gauge | 1 | Shared memory in use by process in bytes | -| elasticsearch_process_mem_virtual_size_bytes | gauge | 1 | Total virtual memory used in bytes | -| elasticsearch_process_open_files_count | gauge | 1 | Open file descriptors | -| elasticsearch_snapshot_stats_number_of_snapshots | gauge | 1 | Total number of snapshots | -| elasticsearch_snapshot_stats_oldest_snapshot_timestamp | gauge | 1 | Oldest snapshot timestamp | -| elasticsearch_snapshot_stats_snapshot_start_time_timestamp | gauge | 1 | Last snapshot start timestamp | -| elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds | gauge | 1 | Timestamp of the latest SUCCESS or PARTIAL snapshot | -| elasticsearch_snapshot_stats_snapshot_end_time_timestamp | gauge | 1 | Last snapshot end timestamp | -| elasticsearch_snapshot_stats_snapshot_number_of_failures | gauge | 1 | Last snapshot number of failures | -| elasticsearch_snapshot_stats_snapshot_number_of_indices | gauge | 1 | Last snapshot number of indices | -| elasticsearch_snapshot_stats_snapshot_failed_shards | gauge | 1 | Last snapshot failed shards | -| elasticsearch_snapshot_stats_snapshot_successful_shards | gauge | 1 | Last snapshot successful shards | -| elasticsearch_snapshot_stats_snapshot_total_shards | gauge | 1 | Last snapshot total shard | -| elasticsearch_thread_pool_active_count | gauge | 14 | Thread Pool threads active | -| elasticsearch_thread_pool_completed_count | counter | 14 | Thread Pool operations completed | -| elasticsearch_thread_pool_largest_count | gauge | 14 | Thread Pool largest threads count | -| elasticsearch_thread_pool_queue_count | gauge | 14 | Thread Pool operations queued | -| elasticsearch_thread_pool_rejected_count | counter | 14 | Thread Pool operations rejected | -| elasticsearch_thread_pool_threads_count | gauge | 14 | Thread Pool current threads count | -| elasticsearch_transport_rx_packets_total | counter | 1 | Count of packets received | -| elasticsearch_transport_rx_size_bytes_total | counter | 1 | Total number of bytes received | -| elasticsearch_transport_tx_packets_total | counter | 1 | Count of packets sent | -| elasticsearch_transport_tx_size_bytes_total | counter | 1 | Total number of bytes sent | -| elasticsearch_clusterinfo_last_retrieval_success_ts | gauge | 1 | Timestamp of the last successful cluster info retrieval | -| elasticsearch_clusterinfo_up | gauge | 1 | Up metric for the cluster info collector | -| elasticsearch_clusterinfo_version_info | gauge | 6 | Constant metric with ES version information as labels | -| elasticsearch_slm_stats_up | gauge | 0 | Up metric for SLM collector | -| elasticsearch_slm_stats_total_scrapes | counter | 0 | Number of scrapes for SLM collector | -| elasticsearch_slm_stats_json_parse_failures | counter | 0 | JSON parse failures for SLM collector | -| elasticsearch_slm_stats_retention_runs_total | counter | 0 | Total retention runs | -| elasticsearch_slm_stats_retention_failed_total | counter | 0 | Total failed retention runs | -| elasticsearch_slm_stats_retention_timed_out_total | counter | 0 | Total retention run timeouts | -| elasticsearch_slm_stats_retention_deletion_time_seconds | gauge | 0 | Retention run deletion time | -| elasticsearch_slm_stats_total_snapshots_taken_total | counter | 0 | Total snapshots taken | -| elasticsearch_slm_stats_total_snapshots_failed_total | counter | 0 | Total snapshots failed | -| elasticsearch_slm_stats_total_snapshots_deleted_total | counter | 0 | Total snapshots deleted | -| elasticsearch_slm_stats_total_snapshots_failed_total | counter | 0 | Total snapshots failed | -| elasticsearch_slm_stats_snapshots_taken_total | counter | 1 | Snapshots taken by policy | -| elasticsearch_slm_stats_snapshots_failed_total | counter | 1 | Snapshots failed by policy | -| elasticsearch_slm_stats_snapshots_deleted_total | counter | 1 | Snapshots deleted by policy | -| elasticsearch_slm_stats_snapshot_deletion_failures_total | counter | 1 | Snapshot deletion failures by policy | -| elasticsearch_slm_stats_operation_mode | gauge | 1 | SLM operation mode (Running, stopping, stopped) | -| elasticsearch_data_stream_stats_up | gauge | 0 | Up metric for Data Stream collection | -| elasticsearch_data_stream_stats_total_scrapes | counter | 0 | Total scrapes for Data Stream stats | -| elasticsearch_data_stream_stats_json_parse_failures | counter | 0 | Number of parsing failures for Data Stream stats | -| elasticsearch_data_stream_backing_indices_total | gauge | 1 | Number of backing indices for Data Stream | -| elasticsearch_data_stream_store_size_bytes | gauge | 1 | Current size of data stream backing indices in bytes | -| elasticsearch_health_report_creating_primaries | gauge | 1 | The number of creating primary shards | -| elasticsearch_health_report_creating_replicas | gauge | 1 | The number of creating replica shards | -| elasticsearch_health_report_data_stream_lifecycle_status | gauge | 2 | Data stream lifecycle status | -| elasticsearch_health_report_disk_status | gauge | 2 | disk status | -| elasticsearch_health_report_ilm_policies | gauge | 1 | The number of ILM Policies | -| elasticsearch_health_report_ilm_stagnating_indices | gauge | 1 | The number of stagnating indices | -| elasticsearch_health_report_ilm_status | gauge | 2 | ILM status | -| elasticsearch_health_report_initializing_primaries | gauge | 1 | The number of initializing primary shards | -| elasticsearch_health_report_initializing_replicas | gauge | 1 | The number of initializing replica shards | -| elasticsearch_health_report_master_is_stable_status | gauge | 2 | Master is stable status | -| elasticsearch_health_report_max_shards_in_cluster_data | gauge | 1 | The number of maximum shards in a cluster | -| elasticsearch_health_report_max_shards_in_cluster_frozen | gauge | 1 | The number of maximum frozen shards in a cluster | -| elasticsearch_health_report_repository_integrity_status | gauge | 2 | Repository integrity status | -| elasticsearch_health_report_restarting_primaries | gauge | 1 | The number of restarting primary shards | -| elasticsearch_health_report_restarting_replicas | gauge | 1 | The number of restarting replica shards | -| elasticsearch_health_report_shards_availabilty_status | gauge | 2 | Shards availabilty status | -| elasticsearch_health_report_shards_capacity_status | gauge | 2 | Shards capacity status | -| elasticsearch_health_report_slm_policies | gauge | 1 | The number of SLM policies | -| elasticsearch_health_report_slm_status | gauge | 2 | SLM status | -| elasticsearch_health_report_started_primaries | gauge | 1 | The number of started primary shards | -| elasticsearch_health_report_started_replicas | gauge | 1 | The number of started replica shards | -| elasticsearch_health_report_status | gauge | 2 | Overall cluster status | -| elasticsearch_health_report_total_repositories | gauge | 1 | The number snapshot repositories | -| elasticsearch_health_report_unassigned_primaries | gauge | 1 | The number of unassigned primary shards | -| elasticsearch_health_report_unassigned_replicas | gauge | 1 | The number of unassigned replica shards | +See the [metrics documentation](metrics.md) ### Alerts & Recording Rules diff --git a/metrics.md b/metrics.md new file mode 100644 index 00000000..d1fce9ef --- /dev/null +++ b/metrics.md @@ -0,0 +1,187 @@ +# Metrics + +| Name | Type | Cardinality | Help | +|----------------------------------------------------------------------|------------|-------------|-----------------------------------------------------------------------------------------------------| +| elasticsearch_breakers_estimated_size_bytes | gauge | 4 | Estimated size in bytes of breaker | +| elasticsearch_breakers_limit_size_bytes | gauge | 4 | Limit size in bytes for breaker | +| elasticsearch_breakers_tripped | counter | 4 | tripped for breaker | +| elasticsearch_cluster_health_active_primary_shards | gauge | 1 | The number of primary shards in your cluster. This is an aggregate total across all indices. | +| elasticsearch_cluster_health_active_shards | gauge | 1 | Aggregate total of all shards across all indices, which includes replica shards. | +| elasticsearch_cluster_health_delayed_unassigned_shards | gauge | 1 | Shards delayed to reduce reallocation overhead | +| elasticsearch_cluster_health_initializing_shards | gauge | 1 | Count of shards that are being freshly created. | +| elasticsearch_cluster_health_number_of_data_nodes | gauge | 1 | Number of data nodes in the cluster. | +| elasticsearch_cluster_health_number_of_in_flight_fetch | gauge | 1 | The number of ongoing shard info requests. | +| elasticsearch_cluster_health_number_of_nodes | gauge | 1 | Number of nodes in the cluster. | +| elasticsearch_cluster_health_number_of_pending_tasks | gauge | 1 | Cluster level changes which have not yet been executed | +| elasticsearch_cluster_health_task_max_waiting_in_queue_millis | gauge | 1 | Max time in millis that a task is waiting in queue. | +| elasticsearch_cluster_health_relocating_shards | gauge | 1 | The number of shards that are currently moving from one node to another node. | +| elasticsearch_cluster_health_status | gauge | 3 | Whether all primary and replica shards are allocated. | +| elasticsearch_cluster_health_unassigned_shards | gauge | 1 | The number of shards that exist in the cluster state, but cannot be found in the cluster itself. | +| elasticsearch_clustersettings_stats_max_shards_per_node | gauge | 0 | Current maximum number of shards per node setting. | +| elasticsearch_clustersettings_allocation_threshold_enabled | gauge | 0 | Is disk allocation decider enabled. | +| elasticsearch_clustersettings_allocation_watermark_flood_stage_bytes | gauge | 0 | Flood stage watermark as in bytes. | +| elasticsearch_clustersettings_allocation_watermark_high_bytes | gauge | 0 | High watermark for disk usage in bytes. | +| elasticsearch_clustersettings_allocation_watermark_low_bytes | gauge | 0 | Low watermark for disk usage in bytes. | +| elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio | gauge | 0 | Flood stage watermark as a ratio. | +| elasticsearch_clustersettings_allocation_watermark_high_ratio | gauge | 0 | High watermark for disk usage as a ratio. | +| elasticsearch_clustersettings_allocation_watermark_low_ratio | gauge | 0 | Low watermark for disk usage as a ratio. | +| elasticsearch_filesystem_data_available_bytes | gauge | 1 | Available space on block device in bytes | +| elasticsearch_filesystem_data_free_bytes | gauge | 1 | Free space on block device in bytes | +| elasticsearch_filesystem_data_size_bytes | gauge | 1 | Size of block device in bytes | +| elasticsearch_filesystem_io_stats_device_operations_count | gauge | 1 | Count of disk operations | +| elasticsearch_filesystem_io_stats_device_read_operations_count | gauge | 1 | Count of disk read operations | +| elasticsearch_filesystem_io_stats_device_write_operations_count | gauge | 1 | Count of disk write operations | +| elasticsearch_filesystem_io_stats_device_read_size_kilobytes_sum | gauge | 1 | Total kilobytes read from disk | +| elasticsearch_filesystem_io_stats_device_write_size_kilobytes_sum | gauge | 1 | Total kilobytes written to disk | +| elasticsearch_ilm_status | gauge | 1 | Current status of ILM. Status can be `STOPPED`, `RUNNING`, `STOPPING`. | +| elasticsearch_ilm_index_status | gauge | 4 | Status of ILM policy for index | +| elasticsearch_indices_active_queries | gauge | 1 | The number of currently active queries | +| elasticsearch_indices_docs | gauge | 1 | Count of documents on this node | +| elasticsearch_indices_docs_deleted | gauge | 1 | Count of deleted documents on this node | +| elasticsearch_indices_deleted_docs_primary | gauge | 1 | Count of deleted documents with only primary shards | +| elasticsearch_indices_docs_primary | gauge | 1 | Count of documents with only primary shards on all nodes | +| elasticsearch_indices_docs_total | gauge | | Count of documents with shards on all nodes | +| elasticsearch_indices_fielddata_evictions | counter | 1 | Evictions from field data | +| elasticsearch_indices_fielddata_memory_size_bytes | gauge | 1 | Field data cache memory usage in bytes | +| elasticsearch_indices_filter_cache_evictions | counter | 1 | Evictions from filter cache | +| elasticsearch_indices_filter_cache_memory_size_bytes | gauge | 1 | Filter cache memory usage in bytes | +| elasticsearch_indices_flush_time_seconds | counter | 1 | Cumulative flush time in seconds | +| elasticsearch_indices_flush_total | counter | 1 | Total flushes | +| elasticsearch_indices_get_exists_time_seconds | counter | 1 | Total time get exists in seconds | +| elasticsearch_indices_get_exists_total | counter | 1 | Total get exists operations | +| elasticsearch_indices_get_missing_time_seconds | counter | 1 | Total time of get missing in seconds | +| elasticsearch_indices_get_missing_total | counter | 1 | Total get missing | +| elasticsearch_indices_get_time_seconds | counter | 1 | Total get time in seconds | +| elasticsearch_indices_get_total | counter | 1 | Total get | +| elasticsearch_indices_indexing_delete_time_seconds_total | counter | 1 | Total time indexing delete in seconds | +| elasticsearch_indices_indexing_delete_total | counter | 1 | Total indexing deletes | +| elasticsearch_indices_index_current | gauge | 1 | The number of documents currently being indexed to an index | +| elasticsearch_indices_indexing_index_time_seconds_total | counter | 1 | Cumulative index time in seconds | +| elasticsearch_indices_indexing_index_total | counter | 1 | Total index calls | +| elasticsearch_indices_mappings_stats_fields | gauge | 1 | Count of fields currently mapped by index | +| elasticsearch_indices_mappings_stats_json_parse_failures_total | counter | 0 | Number of errors while parsing JSON | +| elasticsearch_indices_mappings_stats_scrapes_total | counter | 0 | Current total Elasticsearch Indices Mappings scrapes | +| elasticsearch_indices_mappings_stats_up | gauge | 0 | Was the last scrape of the Elasticsearch Indices Mappings endpoint successful | +| elasticsearch_indices_merges_docs_total | counter | 1 | Cumulative docs merged | +| elasticsearch_indices_merges_total | counter | 1 | Total merges | +| elasticsearch_indices_merges_total_size_bytes_total | counter | 1 | Total merge size in bytes | +| elasticsearch_indices_merges_total_time_seconds_total | counter | 1 | Total time spent merging in seconds | +| elasticsearch_indices_query_cache_cache_total | counter | 1 | Count of query cache | +| elasticsearch_indices_query_cache_cache_size | gauge | 1 | Size of query cache | +| elasticsearch_indices_query_cache_count | counter | 2 | Count of query cache hit/miss | +| elasticsearch_indices_query_cache_evictions | counter | 1 | Evictions from query cache | +| elasticsearch_indices_query_cache_memory_size_bytes | gauge | 1 | Query cache memory usage in bytes | +| elasticsearch_indices_query_cache_total | counter | 1 | Size of query cache total | +| elasticsearch_indices_refresh_time_seconds_total | counter | 1 | Total time spent refreshing in seconds | +| elasticsearch_indices_refresh_total | counter | 1 | Total refreshes | +| elasticsearch_indices_request_cache_count | counter | 2 | Count of request cache hit/miss | +| elasticsearch_indices_request_cache_evictions | counter | 1 | Evictions from request cache | +| elasticsearch_indices_request_cache_memory_size_bytes | gauge | 1 | Request cache memory usage in bytes | +| elasticsearch_indices_search_fetch_time_seconds | counter | 1 | Total search fetch time in seconds | +| elasticsearch_indices_search_fetch_total | counter | 1 | Total number of fetches | +| elasticsearch_indices_search_query_time_seconds | counter | 1 | Total search query time in seconds | +| elasticsearch_indices_search_query_total | counter | 1 | Total number of queries | +| elasticsearch_indices_segments_count | gauge | 1 | Count of index segments on this node | +| elasticsearch_indices_segments_memory_bytes | gauge | 1 | Current memory size of segments in bytes | +| elasticsearch_indices_settings_creation_timestamp_seconds | gauge | 1 | Timestamp of the index creation in seconds | +| elasticsearch_indices_settings_stats_read_only_indices | gauge | 1 | Count of indices that have read_only_allow_delete=true | +| elasticsearch_indices_settings_total_fields | gauge | | Index setting value for index.mapping.total_fields.limit (total allowable mapped fields in a index) | +| elasticsearch_indices_settings_replicas | gauge | | Index setting value for index.replicas | +| elasticsearch_indices_shards_docs | gauge | 3 | Count of documents on this shard | +| elasticsearch_indices_shards_docs_deleted | gauge | 3 | Count of deleted documents on each shard | +| elasticsearch_indices_store_size_bytes | gauge | 1 | Current size of stored index data in bytes | +| elasticsearch_indices_store_size_bytes_primary | gauge | | Current size of stored index data in bytes with only primary shards on all nodes | +| elasticsearch_indices_store_size_bytes_total | gauge | | Current size of stored index data in bytes with all shards on all nodes | +| elasticsearch_indices_store_throttle_time_seconds_total | counter | 1 | Throttle time for index store in seconds | +| elasticsearch_indices_translog_operations | counter | 1 | Total translog operations | +| elasticsearch_indices_translog_size_in_bytes | counter | 1 | Total translog size in bytes | +| elasticsearch_indices_warmer_time_seconds_total | counter | 1 | Total warmer time in seconds | +| elasticsearch_indices_warmer_total | counter | 1 | Total warmer count | +| elasticsearch_jvm_gc_collection_seconds_count | counter | 2 | Count of JVM GC runs | +| elasticsearch_jvm_gc_collection_seconds_sum | counter | 2 | GC run time in seconds | +| elasticsearch_jvm_memory_committed_bytes | gauge | 2 | JVM memory currently committed by area | +| elasticsearch_jvm_memory_max_bytes | gauge | 1 | JVM memory max | +| elasticsearch_jvm_memory_used_bytes | gauge | 2 | JVM memory currently used by area | +| elasticsearch_jvm_memory_pool_used_bytes | gauge | 3 | JVM memory currently used by pool | +| elasticsearch_jvm_memory_pool_max_bytes | counter | 3 | JVM memory max by pool | +| elasticsearch_jvm_memory_pool_peak_used_bytes | counter | 3 | JVM memory peak used by pool | +| elasticsearch_jvm_memory_pool_peak_max_bytes | counter | 3 | JVM memory peak max by pool | +| elasticsearch_os_cpu_percent | gauge | 1 | Percent CPU used by the OS | +| elasticsearch_os_load1 | gauge | 1 | Shortterm load average | +| elasticsearch_os_load5 | gauge | 1 | Midterm load average | +| elasticsearch_os_load15 | gauge | 1 | Longterm load average | +| elasticsearch_process_cpu_percent | gauge | 1 | Percent CPU used by process | +| elasticsearch_process_cpu_seconds_total | counter | 1 | Process CPU time in seconds | +| elasticsearch_process_mem_resident_size_bytes | gauge | 1 | Resident memory in use by process in bytes | +| elasticsearch_process_mem_share_size_bytes | gauge | 1 | Shared memory in use by process in bytes | +| elasticsearch_process_mem_virtual_size_bytes | gauge | 1 | Total virtual memory used in bytes | +| elasticsearch_process_open_files_count | gauge | 1 | Open file descriptors | +| elasticsearch_snapshot_stats_number_of_snapshots | gauge | 1 | Total number of snapshots | +| elasticsearch_snapshot_stats_oldest_snapshot_timestamp | gauge | 1 | Oldest snapshot timestamp | +| elasticsearch_snapshot_stats_snapshot_start_time_timestamp | gauge | 1 | Last snapshot start timestamp | +| elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds | gauge | 1 | Timestamp of the latest SUCCESS or PARTIAL snapshot | +| elasticsearch_snapshot_stats_snapshot_end_time_timestamp | gauge | 1 | Last snapshot end timestamp | +| elasticsearch_snapshot_stats_snapshot_number_of_failures | gauge | 1 | Last snapshot number of failures | +| elasticsearch_snapshot_stats_snapshot_number_of_indices | gauge | 1 | Last snapshot number of indices | +| elasticsearch_snapshot_stats_snapshot_failed_shards | gauge | 1 | Last snapshot failed shards | +| elasticsearch_snapshot_stats_snapshot_successful_shards | gauge | 1 | Last snapshot successful shards | +| elasticsearch_snapshot_stats_snapshot_total_shards | gauge | 1 | Last snapshot total shard | +| elasticsearch_thread_pool_active_count | gauge | 14 | Thread Pool threads active | +| elasticsearch_thread_pool_completed_count | counter | 14 | Thread Pool operations completed | +| elasticsearch_thread_pool_largest_count | gauge | 14 | Thread Pool largest threads count | +| elasticsearch_thread_pool_queue_count | gauge | 14 | Thread Pool operations queued | +| elasticsearch_thread_pool_rejected_count | counter | 14 | Thread Pool operations rejected | +| elasticsearch_thread_pool_threads_count | gauge | 14 | Thread Pool current threads count | +| elasticsearch_transport_rx_packets_total | counter | 1 | Count of packets received | +| elasticsearch_transport_rx_size_bytes_total | counter | 1 | Total number of bytes received | +| elasticsearch_transport_tx_packets_total | counter | 1 | Count of packets sent | +| elasticsearch_transport_tx_size_bytes_total | counter | 1 | Total number of bytes sent | +| elasticsearch_clusterinfo_last_retrieval_success_ts | gauge | 1 | Timestamp of the last successful cluster info retrieval | +| elasticsearch_clusterinfo_up | gauge | 1 | Up metric for the cluster info collector | +| elasticsearch_clusterinfo_version_info | gauge | 6 | Constant metric with ES version information as labels | +| elasticsearch_slm_stats_up | gauge | 0 | Up metric for SLM collector | +| elasticsearch_slm_stats_total_scrapes | counter | 0 | Number of scrapes for SLM collector | +| elasticsearch_slm_stats_json_parse_failures | counter | 0 | JSON parse failures for SLM collector | +| elasticsearch_slm_stats_retention_runs_total | counter | 0 | Total retention runs | +| elasticsearch_slm_stats_retention_failed_total | counter | 0 | Total failed retention runs | +| elasticsearch_slm_stats_retention_timed_out_total | counter | 0 | Total retention run timeouts | +| elasticsearch_slm_stats_retention_deletion_time_seconds | gauge | 0 | Retention run deletion time | +| elasticsearch_slm_stats_total_snapshots_taken_total | counter | 0 | Total snapshots taken | +| elasticsearch_slm_stats_total_snapshots_failed_total | counter | 0 | Total snapshots failed | +| elasticsearch_slm_stats_total_snapshots_deleted_total | counter | 0 | Total snapshots deleted | +| elasticsearch_slm_stats_total_snapshots_failed_total | counter | 0 | Total snapshots failed | +| elasticsearch_slm_stats_snapshots_taken_total | counter | 1 | Snapshots taken by policy | +| elasticsearch_slm_stats_snapshots_failed_total | counter | 1 | Snapshots failed by policy | +| elasticsearch_slm_stats_snapshots_deleted_total | counter | 1 | Snapshots deleted by policy | +| elasticsearch_slm_stats_snapshot_deletion_failures_total | counter | 1 | Snapshot deletion failures by policy | +| elasticsearch_slm_stats_operation_mode | gauge | 1 | SLM operation mode (Running, stopping, stopped) | +| elasticsearch_data_stream_stats_up | gauge | 0 | Up metric for Data Stream collection | +| elasticsearch_data_stream_stats_total_scrapes | counter | 0 | Total scrapes for Data Stream stats | +| elasticsearch_data_stream_stats_json_parse_failures | counter | 0 | Number of parsing failures for Data Stream stats | +| elasticsearch_data_stream_backing_indices_total | gauge | 1 | Number of backing indices for Data Stream | +| elasticsearch_data_stream_store_size_bytes | gauge | 1 | Current size of data stream backing indices in bytes | +| elasticsearch_health_report_creating_primaries | gauge | 1 | The number of creating primary shards | +| elasticsearch_health_report_creating_replicas | gauge | 1 | The number of creating replica shards | +| elasticsearch_health_report_data_stream_lifecycle_status | gauge | 2 | Data stream lifecycle status | +| elasticsearch_health_report_disk_status | gauge | 2 | disk status | +| elasticsearch_health_report_ilm_policies | gauge | 1 | The number of ILM Policies | +| elasticsearch_health_report_ilm_stagnating_indices | gauge | 1 | The number of stagnating indices | +| elasticsearch_health_report_ilm_status | gauge | 2 | ILM status | +| elasticsearch_health_report_initializing_primaries | gauge | 1 | The number of initializing primary shards | +| elasticsearch_health_report_initializing_replicas | gauge | 1 | The number of initializing replica shards | +| elasticsearch_health_report_master_is_stable_status | gauge | 2 | Master is stable status | +| elasticsearch_health_report_max_shards_in_cluster_data | gauge | 1 | The number of maximum shards in a cluster | +| elasticsearch_health_report_max_shards_in_cluster_frozen | gauge | 1 | The number of maximum frozen shards in a cluster | +| elasticsearch_health_report_repository_integrity_status | gauge | 2 | Repository integrity status | +| elasticsearch_health_report_restarting_primaries | gauge | 1 | The number of restarting primary shards | +| elasticsearch_health_report_restarting_replicas | gauge | 1 | The number of restarting replica shards | +| elasticsearch_health_report_shards_availabilty_status | gauge | 2 | Shards availabilty status | +| elasticsearch_health_report_shards_capacity_status | gauge | 2 | Shards capacity status | +| elasticsearch_health_report_slm_policies | gauge | 1 | The number of SLM policies | +| elasticsearch_health_report_slm_status | gauge | 2 | SLM status | +| elasticsearch_health_report_started_primaries | gauge | 1 | The number of started primary shards | +| elasticsearch_health_report_started_replicas | gauge | 1 | The number of started replica shards | +| elasticsearch_health_report_status | gauge | 2 | Overall cluster status | +| elasticsearch_health_report_total_repositories | gauge | 1 | The number snapshot repositories | +| elasticsearch_health_report_unassigned_primaries | gauge | 1 | The number of unassigned primary shards | +| elasticsearch_health_report_unassigned_replicas | gauge | 1 | The number of unassigned replica shards | From eccabe230e0bf300130eb6cc9d02a64da3662230 Mon Sep 17 00:00:00 2001 From: pincher95 Date: Wed, 26 Nov 2025 08:31:13 -0500 Subject: [PATCH 21/21] Add node label to elasticsearch_nodes_roles metric - Add 'node' (node ID) label to elasticsearch_nodes_roles metric - Node ID comes from the map key in nodes stats response (no extra API calls) - Update tests for ES versions 5.6.16, 6.8.8, and 7.13.1 Signed-off-by: pincher95 --- collector/nodes.go | 5 +-- collector/nodes_test.go | 72 ++++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/collector/nodes.go b/collector/nodes.go index b830ec3f..cea7ef06 100644 --- a/collector/nodes.go +++ b/collector/nodes.go @@ -77,7 +77,7 @@ var nodesRolesMetric = prometheus.NewDesc( var ( defaultNodeLabels = []string{"cluster", "host", "name", "es_master_node", "es_data_node", "es_ingest_node", "es_client_node"} - defaultRoleLabels = []string{"cluster", "host", "name"} + defaultRoleLabels = []string{"cluster", "host", "name", "node"} defaultThreadPoolLabels = append(defaultNodeLabels, "type") defaultBreakerLabels = append(defaultNodeLabels, "breaker") defaultIndexingPressureLabels = []string{"cluster", "host", "name", "indexing_pressure"} @@ -1905,7 +1905,7 @@ func (c *Nodes) Collect(ch chan<- prometheus.Metric) { return } - for _, node := range nodeStatsResp.Nodes { + for nodeID, node := range nodeStatsResp.Nodes { // Handle the node labels metric roles := getRoles(node) @@ -1919,6 +1919,7 @@ func (c *Nodes) Collect(ch chan<- prometheus.Metric) { nodeStatsResp.ClusterName, node.Host, node.Name, + nodeID, role, } diff --git a/collector/nodes_test.go b/collector/nodes_test.go index 3275d18e..6b7944e6 100644 --- a/collector/nodes_test.go +++ b/collector/nodes_test.go @@ -340,18 +340,18 @@ func TestNodesStats(t *testing.T) { elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="mapped"} 14.845 # HELP elasticsearch_nodes_roles Node roles # TYPE elasticsearch_nodes_roles gauge - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_cold"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_content"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_frozen"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_hot"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_warm"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="ingest"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="master"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="ml"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="remote_cluster_client"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="transform"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_cold"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_content"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_frozen"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_hot"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="data_warm"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="ml"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="remote_cluster_client"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",node="bVrN1HxvQLy795ZLNg2XNw",role="transform"} 0 # HELP elasticsearch_os_cpu_percent Percent CPU used by OS # TYPE elasticsearch_os_cpu_percent gauge elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 23 @@ -799,18 +799,18 @@ func TestNodesStats(t *testing.T) { elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="mapped"} 16.456 # HELP elasticsearch_nodes_roles Node roles # TYPE elasticsearch_nodes_roles gauge - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_cold"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_content"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_frozen"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_hot"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_warm"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="ingest"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="master"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="ml"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="remote_cluster_client"} 0 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="transform"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_cold"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_content"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_frozen"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_hot"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="data_warm"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="ml"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="remote_cluster_client"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",node="9_P7yuiySjG7OAN6NRbBRA",role="transform"} 0 # HELP elasticsearch_os_cpu_percent Percent CPU used by OS # TYPE elasticsearch_os_cpu_percent gauge elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 30 @@ -1322,18 +1322,18 @@ func TestNodesStats(t *testing.T) { elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="mapped"} 21.844 # HELP elasticsearch_nodes_roles Node roles # TYPE elasticsearch_nodes_roles gauge - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_cold"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_content"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_frozen"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_hot"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_warm"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="ingest"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="master"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="ml"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="remote_cluster_client"} 1 - elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="transform"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_cold"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_content"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_frozen"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_hot"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="data_warm"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="ml"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="remote_cluster_client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",node="byoDEtBRSRGZyMKaIpmhCQ",role="transform"} 1 # HELP elasticsearch_os_cpu_percent Percent CPU used by OS # TYPE elasticsearch_os_cpu_percent gauge elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 37