From 5d458955be0f5e31a53ea52fca67df2cf5d2f247 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Wed, 26 Mar 2025 09:46:27 +0100 Subject: [PATCH 01/13] Update Go to 1.24 (#3273) * Update Go to 1.24 for all builds. * Update minimum Go version to 1.23. * Bump procfs library. Signed-off-by: Ben Kochie --- .circleci/config.yml | 10 +++++----- .github/workflows/bsd.yml | 28 ++++++++++++++-------------- .promu-cgo.yml | 2 +- .promu.yml | 2 +- go.mod | 8 ++++---- go.sum | 12 ++++++------ 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 96b38cff..478aa310 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,10 +7,10 @@ executors: # should also be updated. golang: docker: - - image: cimg/go:1.23 + - image: cimg/go:1.24 arm: docker: - - image: cimg/go:1.23 + - image: cimg/go:1.24 resource_class: arm.medium jobs: @@ -42,7 +42,7 @@ jobs: - run: git diff --exit-code build: machine: - image: ubuntu-2204:current + image: ubuntu-2404:current parallelism: 3 steps: - prometheus/setup_environment @@ -68,9 +68,9 @@ jobs: destination: /build test_docker: machine: - image: ubuntu-2204:current + image: ubuntu-2404:current environment: - DOCKER_TEST_IMAGE_NAME: quay.io/prometheus/golang-builder:1.23-base + DOCKER_TEST_IMAGE_NAME: quay.io/prometheus/golang-builder:1.24-base REPO_PATH: github.com/prometheus/node_exporter steps: - prometheus/setup_environment diff --git a/.github/workflows/bsd.yml b/.github/workflows/bsd.yml index 09aa1b5c..2f314913 100644 --- a/.github/workflows/bsd.yml +++ b/.github/workflows/bsd.yml @@ -13,11 +13,11 @@ permissions: env: GNU_TAR_VERSION: "1.35" - GO_VERSION_DRAGONFLY: "1.23.3" + GO_VERSION_DRAGONFLY: "1.24.1" GO_VERSION_FREEBSD: "123" - GO_VERSION_NETBSD: "1.23.3" + GO_VERSION_NETBSD: "1.24.1" GO_VERSION_OPENBSD: "1.23.1" - GO_VERSION_SOLARIS: "1.23.3" + GO_VERSION_SOLARIS: "1.24.1" # To spin up one of the VMs below, see the "Debug Shell" section here: https://github.com/vmactions jobs: @@ -26,9 +26,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: test-e2e - uses: vmactions/freebsd-vm@v1 + uses: vmactions/freebsd-vm@8873d98fd1413b5977cb2f7348fe329775159892 # v1.1.9 with: copyback: false envs: 'GO_VERSION_FREEBSD GNU_TAR_VERSION' @@ -73,9 +73,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: test-e2e - uses: vmactions/openbsd-vm@v1 + uses: vmactions/openbsd-vm@7ac70b6de6f33efc74a90c1964afa3bcf0ee4401 # v1.1.6 with: copyback: false envs: 'GO_VERSION_OPENBSD GNU_TAR_VERSION' @@ -119,9 +119,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: test-e2e - uses: vmactions/netbsd-vm@v1 + uses: vmactions/netbsd-vm@46a58bbf03682b4cb24142b97fa315ae52bed573 # v1.1.8 with: copyback: false envs: 'GO_VERSION_NETBSD GNU_TAR_VERSION' @@ -167,9 +167,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: test-e2e - uses: vmactions/dragonflybsd-vm@v1 + uses: vmactions/dragonflybsd-vm@e3c420e8a2362c2496fca6e76a291abd46f5d8e7 # v1.1.0 with: copyback: false envs: 'GO_VERSION_DRAGONFLY' @@ -217,9 +217,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: test-e2e - uses: vmactions/solaris-vm@v1 + uses: vmactions/solaris-vm@cc8f82fa1a7cc746153ec3f71bf11f311f16e225 # v1.1.1 with: copyback: false envs: 'GO_VERSION_SOLARIS' @@ -276,7 +276,7 @@ jobs: runs-on: macos-latest steps: - name: Checkout the repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install dependencies run: | brew install \ diff --git a/.promu-cgo.yml b/.promu-cgo.yml index 542f51e2..7ce1b201 100644 --- a/.promu-cgo.yml +++ b/.promu-cgo.yml @@ -1,7 +1,7 @@ go: # Whenever the Go version is updated here, .circle/config.yml and # .promu.yml should also be updated. - version: 1.23 + version: 1.24 cgo: true repository: path: github.com/prometheus/node_exporter diff --git a/.promu.yml b/.promu.yml index fcba92d0..b38799f8 100644 --- a/.promu.yml +++ b/.promu.yml @@ -1,7 +1,7 @@ go: # Whenever the Go version is updated here, .circle/config.yml and # .promu-cgo.yml should also be updated. - version: 1.23 + version: 1.24 repository: path: github.com/prometheus/node_exporter build: diff --git a/go.mod b/go.mod index d8318e12..75a5d6ba 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/prometheus/node_exporter -go 1.22.0 +go 1.23.0 require ( github.com/alecthomas/kingpin/v2 v2.4.0 @@ -26,7 +26,7 @@ require ( github.com/prometheus/client_model v0.6.1 github.com/prometheus/common v0.62.0 github.com/prometheus/exporter-toolkit v0.14.0 - github.com/prometheus/procfs v0.15.2-0.20240603130017-1754b780536b // == v0.15.1 + https://github.com/prometheus/procfs/commit/1754b780536bb81082baa913e04cc4fff4d2baea + github.com/prometheus/procfs v0.16.0 github.com/safchain/ethtool v0.5.10 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/sys v0.30.0 @@ -38,7 +38,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dennwc/ioctl v1.0.0 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/kylelemons/godebug v1.1.0 // indirect @@ -54,7 +54,7 @@ require ( golang.org/x/crypto v0.32.0 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sync v0.10.0 // indirect + golang.org/x/sync v0.11.0 // indirect golang.org/x/text v0.21.0 // indirect google.golang.org/protobuf v1.36.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index ded35a69..6c9ae14f 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,8 @@ github.com/ema/qdisc v1.0.0/go.mod h1:FhIc0fLYi7f+lK5maMsesDqwYojIOh3VfRs8EVd5YJ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/hashicorp/go-envparse v0.1.0 h1:bE++6bhIsNCPLvgDZkYqo3nA+/PFI51pkrHdmPSDFPY= github.com/hashicorp/go-envparse v0.1.0/go.mod h1:OHheN1GoygLlAkTlXLXvAdnXdZxy8JUweQ1rAXx1xnc= github.com/hodgesds/perf-utils v0.7.0 h1:7KlHGMuig4FRH5fNw68PV6xLmgTe7jKs9hgAcEAbioU= @@ -83,8 +83,8 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= 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.15.2-0.20240603130017-1754b780536b h1:4EJkx3vycI+n5JY5ht+bnSUGamkmmXkpcNeO/OBT/0A= -github.com/prometheus/procfs v0.15.2-0.20240603130017-1754b780536b/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= +github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= 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/safchain/ethtool v0.5.10 h1:Im294gZtuf4pSGJRAOGKaASNi3wMeFaGaWuSaomedpc= @@ -110,8 +110,8 @@ golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= From 47e2bb34cefacf2f645389901035b2d31e1078a8 Mon Sep 17 00:00:00 2001 From: Rolf Klemenz Date: Wed, 26 Mar 2025 15:30:46 +0100 Subject: [PATCH 02/13] Avoid memory leak by using value rather than reference. (#3277) Signed-off-by: Rolf Klemenz --- collector/filesystem_common.go | 7 +++---- collector/filesystem_macos.go | 17 ++++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/collector/filesystem_common.go b/collector/filesystem_common.go index 272366b3..4161b3fe 100644 --- a/collector/filesystem_common.go +++ b/collector/filesystem_common.go @@ -89,7 +89,7 @@ type filesystemStats struct { labels filesystemLabels size, free, avail float64 files, filesFree float64 - purgeable *float64 + purgeable float64 ro, deviceError float64 } @@ -232,11 +232,10 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) error { c.mountInfoDesc, prometheus.GaugeValue, 1.0, s.labels.device, s.labels.major, s.labels.minor, s.labels.mountPoint, ) - if s.purgeable != nil { + if s.purgeable >= 0 { ch <- prometheus.MustNewConstMetric( c.purgeableDesc, prometheus.GaugeValue, - *s.purgeable, s.labels.device, s.labels.mountPoint, - s.labels.fsType, s.labels.deviceError, + s.purgeable, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, ) } } diff --git a/collector/filesystem_macos.go b/collector/filesystem_macos.go index 0894cabc..26b30644 100644 --- a/collector/filesystem_macos.go +++ b/collector/filesystem_macos.go @@ -20,23 +20,22 @@ package collector #cgo CFLAGS: -x objective-c #cgo LDFLAGS: -framework Foundation #import -Float64 *purgeable(char *path) { +Float64 purgeable(char *path) { CFNumberRef tmp; - Float64 *value; NSError *error = nil; NSString *str = [NSString stringWithUTF8String:path]; NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:str]; NSDictionary *results = [fileURL resourceValuesForKeys:@[NSURLVolumeAvailableCapacityForImportantUsageKey] error:&error]; if (results) { - if ((tmp = CFDictionaryGetValue((CFDictionaryRef)results, NSURLVolumeAvailableCapacityForImportantUsageKey)) == NULL) - return NULL; - value = (Float64 *)malloc(sizeof(Float64)); - if (CFNumberGetValue(tmp, kCFNumberFloat64Type, value)) { + if ((tmp = CFDictionaryGetValue((CFDictionaryRef)results, NSURLVolumeAvailableCapacityForImportantUsageKey)) == NULL) { + return -1.0f; + } + Float64 value; + if (CFNumberGetValue(tmp, kCFNumberFloat64Type, &value)) { return value; } } - free(value); - return NULL; + return -1.0f; } */ import "C" @@ -100,7 +99,7 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) { avail: float64(mnt[i].f_bavail) * float64(mnt[i].f_bsize), files: float64(mnt[i].f_files), filesFree: float64(mnt[i].f_ffree), - purgeable: (*float64)(C.purgeable(C.CString(mountpoint))), + purgeable: float64(C.purgeable(C.CString(mountpoint))), ro: ro, }) } From 58ac08e2160a3e0e9d5893722f2bf2c41b842403 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Thu, 27 Mar 2025 09:57:33 +0100 Subject: [PATCH 03/13] Fix linter warning (#3280) Fix S1009: should omit nil check; len() for nil maps is defined as zero (gosimple) Signed-off-by: Ben Kochie --- collector/ethtool_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collector/ethtool_linux.go b/collector/ethtool_linux.go index 78f7afe2..01410d64 100644 --- a/collector/ethtool_linux.go +++ b/collector/ethtool_linux.go @@ -446,7 +446,7 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error { } } - if stats == nil || len(stats) < 1 { + if len(stats) == 0 { // No stats returned; device does not support ethtool stats. continue } From 9b898b8df47b5c125db30d3c0f5a19e56c2829bc Mon Sep 17 00:00:00 2001 From: PrometheusBot Date: Thu, 27 Mar 2025 11:45:52 +0100 Subject: [PATCH 04/13] Update common Prometheus files (#3264) Signed-off-by: prombot Co-authored-by: Ben Kochie --- .github/workflows/golangci-lint.yml | 6 +++--- Makefile.common | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index def9007a..e36a9f1a 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -28,12 +28,12 @@ jobs: - name: Install Go uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: - go-version: 1.23.x + go-version: 1.24.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: Lint - uses: golangci/golangci-lint-action@ec5d18412c0aeab7936cb16880d708ba2a64e1ae # v6.2.0 + uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 # v6.5.0 with: args: --verbose - version: v1.63.4 + version: v1.64.6 diff --git a/Makefile.common b/Makefile.common index d1576bb3..8cb38385 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 ?= v1.63.4 +GOLANGCI_LINT_VERSION ?= v1.64.6 # 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. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) From 93b79b44bd46a9e8188690828da5a3f484a73d2e Mon Sep 17 00:00:00 2001 From: PrometheusBot Date: Thu, 27 Mar 2025 18:56:08 +0100 Subject: [PATCH 05/13] Update common Prometheus files (#3286) Signed-off-by: prombot --- .github/workflows/golangci-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index e36a9f1a..b404ce7c 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -33,7 +33,7 @@ jobs: run: sudo apt-get update && sudo apt-get -y install libsnmp-dev if: github.repository == 'prometheus/snmp_exporter' - name: Lint - uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 # v6.5.0 + uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # v6.5.2 with: args: --verbose version: v1.64.6 From e768aad83de2a466897626147757cdb827dd5768 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Fri, 28 Mar 2025 10:48:44 +0100 Subject: [PATCH 06/13] Fix flaky Solaris test (#3289) Ignore `node_cpu_frequency_max_hertz` to fix flaky Solaris end-to-end test. Signed-off-by: Ben Kochie --- collector/fixtures/e2e-output-solaris.txt | 6 ------ end-to-end-test.sh | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/collector/fixtures/e2e-output-solaris.txt b/collector/fixtures/e2e-output-solaris.txt index 2f39a5f6..9ac18df9 100644 --- a/collector/fixtures/e2e-output-solaris.txt +++ b/collector/fixtures/e2e-output-solaris.txt @@ -91,12 +91,6 @@ node_buddyinfo_blocks{node="0",size="8",zone="Normal"} 0 node_buddyinfo_blocks{node="0",size="9",zone="DMA"} 1 node_buddyinfo_blocks{node="0",size="9",zone="DMA32"} 0 node_buddyinfo_blocks{node="0",size="9",zone="Normal"} 0 -# HELP node_cpu_frequency_max_hertz Maximum CPU thread frequency in hertz. -# TYPE node_cpu_frequency_max_hertz gauge -node_cpu_frequency_max_hertz{cpu="0"} 2.445e+09 -node_cpu_frequency_max_hertz{cpu="1"} 2.445e+09 -node_cpu_frequency_max_hertz{cpu="2"} 2.445e+09 -node_cpu_frequency_max_hertz{cpu="3"} 2.445e+09 # HELP node_exporter_build_info A metric with a constant '1' value labeled by version, revision, branch, goversion from which node_exporter was built, and the goos and goarch for the build. # TYPE node_exporter_build_info gauge # HELP node_os_info A metric with a constant '1' value labeled by build_id, id, id_like, image_id, image_version, name, pretty_name, variant, variant_id, version, version_codename, version_id. diff --git a/end-to-end-test.sh b/end-to-end-test.sh index 944bdc0e..df3f4938 100755 --- a/end-to-end-test.sh +++ b/end-to-end-test.sh @@ -325,6 +325,7 @@ get "127.0.0.1:${port}/metrics" | grep --text -E -v "${skip_re}" > "${generated_ non_deterministic_metrics=$(cat << METRICS node_boot_time_seconds node_cpu_frequency_hertz + node_cpu_frequency_max_hertz node_cpu_seconds_total node_disk_io_time_seconds_total node_disk_read_bytes_total From 729a03136f7f33b91a024ee8d2073f838a33cb84 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Mon, 31 Mar 2025 11:00:34 +0200 Subject: [PATCH 07/13] Fix OpenBSD interrupt device parsing (#3288) Sanitize zero terminated strings from OpenBSD device name parsing. * Add byte-to-string util function. Fixes: https://github.com/prometheus/node_exporter/issues/3287 Signed-off-by: Ben Kochie --- collector/interrupts_openbsd_amd64.go | 4 +++- collector/utils/utils.go | 20 ++++++++++++++++++ collector/utils/utils_test.go | 30 +++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 collector/utils/utils_test.go diff --git a/collector/interrupts_openbsd_amd64.go b/collector/interrupts_openbsd_amd64.go index 69851a22..f52a1b81 100644 --- a/collector/interrupts_openbsd_amd64.go +++ b/collector/interrupts_openbsd_amd64.go @@ -21,6 +21,8 @@ import ( "strconv" "unsafe" + "github.com/prometheus/node_exporter/collector/utils" + "github.com/prometheus/client_golang/prometheus" "golang.org/x/sys/unix" ) @@ -49,7 +51,7 @@ func intr(idx _C_int) (itr interrupt, err error) { return } dev := *(*[128]byte)(unsafe.Pointer(&buf[0])) - itr.device = string(dev[:]) + itr.device = utils.SafeBytesToString(dev[:]) mib[2] = KERN_INTRCNT_VECTOR buf, err = sysctl(mib[:]) diff --git a/collector/utils/utils.go b/collector/utils/utils.go index aa5b7540..9bcaf4c8 100644 --- a/collector/utils/utils.go +++ b/collector/utils/utils.go @@ -13,6 +13,11 @@ package utils +import ( + "bytes" + "strings" +) + func SafeDereference[T any](s ...*T) []T { var resolved []T for _, v := range s { @@ -25,3 +30,18 @@ func SafeDereference[T any](s ...*T) []T { } return resolved } + +// SafeBytesToString takes a slice of bytes and sanitizes it for Prometheus label +// values. +// * Terminate the string at the first null byte. +// * Convert any invalid UTF-8 to "�". +func SafeBytesToString(b []byte) string { + var s string + zeroIndex := bytes.IndexByte(b, 0) + if zeroIndex == -1 { + s = string(b) + } else { + s = string(b[:zeroIndex]) + } + return strings.ToValidUTF8(s, "�") +} diff --git a/collector/utils/utils_test.go b/collector/utils/utils_test.go new file mode 100644 index 00000000..3246ebc3 --- /dev/null +++ b/collector/utils/utils_test.go @@ -0,0 +1,30 @@ +// Copyright 2025 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file ewcept 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 utils + +import ( + "testing" +) + +func TestSafeBytesToString(t *testing.T) { + foo := []byte("foo\x00") + if want, got := SafeBytesToString(foo), "foo"; want != got { + t.Errorf("Expected: %s, Got: %s", want, got) + } + + foo = []byte{115, 97, 110, 101, 253, 190, 214} + if want, got := SafeBytesToString(foo), "sane�"; want != got { + t.Errorf("Expected: %s, Got: %s", want, got) + } +} From 8c3f1a2da3b51d46ab9848e21df42b3f3c3c0755 Mon Sep 17 00:00:00 2001 From: PrometheusBot Date: Mon, 31 Mar 2025 11:00:53 +0200 Subject: [PATCH 08/13] Update common Prometheus files (#3291) Signed-off-by: prombot --- .github/workflows/golangci-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index b404ce7c..5342cbe0 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@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 + uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 with: go-version: 1.24.x - name: Install snmp_exporter/generator dependencies From e5caa394c8edf8d1da11627da0d5af36a49627c6 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Mon, 31 Mar 2025 12:46:39 +0200 Subject: [PATCH 09/13] Sanitize darwin thermal strings (#3294) Use `utils.SafeBytesToString()` to sanitize C strings the Darwin thermal collector. Signed-off-by: Ben Kochie --- collector/thermal_darwin.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collector/thermal_darwin.go b/collector/thermal_darwin.go index 0a3b8981..9a74fdbd 100644 --- a/collector/thermal_darwin.go +++ b/collector/thermal_darwin.go @@ -50,6 +50,8 @@ import ( "log/slog" "unsafe" + "github.com/prometheus/node_exporter/collector/utils" + "github.com/prometheus/client_golang/prometheus" ) @@ -176,7 +178,7 @@ func mappingCFStringToString(s C.CFStringRef) string { buf := make([]byte, maxBufLen) var usedBufLen C.CFIndex _ = C.CFStringGetBytes(s, C.CFRange{0, length}, C.kCFStringEncodingUTF8, C.UInt8(0), C.false, (*C.UInt8)(&buf[0]), maxBufLen, &usedBufLen) - return string(buf[:usedBufLen]) + return utils.SafeBytesToString(buf[:usedBufLen]) } func mappingCFNumberLongToInt(n C.CFNumberRef) int { From 8804ce1551d022ce6823b50e7129ff6306ec1569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Mon, 31 Mar 2025 12:47:22 +0200 Subject: [PATCH 10/13] diskstats: Simplify condition (#3290) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the comment says, this can be simplified now. Signed-off-by: Manuel Rüger --- collector/diskstats_linux.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/collector/diskstats_linux.go b/collector/diskstats_linux.go index c083a3f0..ad6ff3cb 100644 --- a/collector/diskstats_linux.go +++ b/collector/diskstats_linux.go @@ -398,15 +398,9 @@ func getUdevDeviceProperties(major, minor uint32) (udevInfo, error) { line = strings.TrimPrefix(line, udevDevicePropertyPrefix) - /* TODO: After we drop support for Go 1.17, the condition below can be simplified to: - if name, value, found := strings.Cut(line, "="); found { info[name] = value } - */ - if fields := strings.SplitN(line, "=", 2); len(fields) == 2 { - info[fields[0]] = fields[1] - } } return info, nil From e44309c825bdf51f85f99c39a7b84773601229b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 12:47:39 +0200 Subject: [PATCH 11/13] build(deps): bump github.com/prometheus/client_golang from 1.20.5 to 1.21.0 (#3262) * build(deps): bump github.com/prometheus/client_golang Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.5 to 1.21.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.20.5...v1.21.0) Signed-off-by: Ben Kochie --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update e2e fixtures for new client_golang. Signed-off-by: Ben Kochie --------- Signed-off-by: dependabot[bot] Signed-off-by: Ben Kochie Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ben Kochie --- collector/fixtures/e2e-64k-page-output.txt | 6 +++--- collector/fixtures/e2e-output-darwin.txt | 20 +++++++++++++++++--- collector/fixtures/e2e-output-dragonfly.txt | 6 +++--- collector/fixtures/e2e-output-freebsd.txt | 6 +++--- collector/fixtures/e2e-output-netbsd.txt | 6 +++--- collector/fixtures/e2e-output-openbsd.txt | 6 +++--- collector/fixtures/e2e-output-solaris.txt | 6 +++--- collector/fixtures/e2e-output.txt | 6 +++--- go.mod | 4 ++-- go.sum | 8 ++++---- 10 files changed, 44 insertions(+), 30 deletions(-) diff --git a/collector/fixtures/e2e-64k-page-output.txt b/collector/fixtures/e2e-64k-page-output.txt index 4ff32889..107d713b 100644 --- a/collector/fixtures/e2e-64k-page-output.txt +++ b/collector/fixtures/e2e-64k-page-output.txt @@ -1,8 +1,8 @@ # HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles. # TYPE go_gc_duration_seconds summary -# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent +# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent. # TYPE go_gc_gogc_percent gauge -# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes +# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes. # TYPE go_gc_gomemlimit_bytes gauge # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge @@ -52,7 +52,7 @@ # TYPE go_memstats_stack_sys_bytes gauge # HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte. # TYPE go_memstats_sys_bytes gauge -# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads +# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads. # TYPE go_sched_gomaxprocs_threads gauge # HELP go_threads Number of OS threads created. # TYPE go_threads gauge diff --git a/collector/fixtures/e2e-output-darwin.txt b/collector/fixtures/e2e-output-darwin.txt index 77eb45cb..61b36997 100644 --- a/collector/fixtures/e2e-output-darwin.txt +++ b/collector/fixtures/e2e-output-darwin.txt @@ -1,8 +1,8 @@ # HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles. # TYPE go_gc_duration_seconds summary -# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent +# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent. # TYPE go_gc_gogc_percent gauge -# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes +# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes. # TYPE go_gc_gomemlimit_bytes gauge # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge @@ -52,7 +52,7 @@ # TYPE go_memstats_stack_sys_bytes gauge # HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte. # TYPE go_memstats_sys_bytes gauge -# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads +# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads. # TYPE go_sched_gomaxprocs_threads gauge # HELP go_threads Number of OS threads created. # TYPE go_threads gauge @@ -251,6 +251,20 @@ node_xfrm_out_state_proto_error_packets_total 4542 # HELP node_xfrm_out_state_seq_error_packets_total Sequence error i.e. Sequence number overflow # TYPE node_xfrm_out_state_seq_error_packets_total counter node_xfrm_out_state_seq_error_packets_total 543 +# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds. +# TYPE process_cpu_seconds_total counter +# HELP process_max_fds Maximum number of open file descriptors. +# TYPE process_max_fds gauge +# HELP process_open_fds Number of open file descriptors. +# TYPE process_open_fds gauge +# HELP process_resident_memory_bytes Resident memory size in bytes. +# TYPE process_resident_memory_bytes gauge +# HELP process_start_time_seconds Start time of the process since unix epoch in seconds. +# TYPE process_start_time_seconds gauge +# HELP process_virtual_memory_bytes Virtual memory size in bytes. +# TYPE process_virtual_memory_bytes gauge +# HELP process_virtual_memory_max_bytes Maximum amount of virtual memory available in bytes. +# TYPE process_virtual_memory_max_bytes gauge # HELP promhttp_metric_handler_errors_total Total number of internal errors encountered by the promhttp metric handler. # TYPE promhttp_metric_handler_errors_total counter promhttp_metric_handler_errors_total{cause="encoding"} 0 diff --git a/collector/fixtures/e2e-output-dragonfly.txt b/collector/fixtures/e2e-output-dragonfly.txt index b6a828ad..638d0afc 100644 --- a/collector/fixtures/e2e-output-dragonfly.txt +++ b/collector/fixtures/e2e-output-dragonfly.txt @@ -1,8 +1,8 @@ # HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles. # TYPE go_gc_duration_seconds summary -# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent +# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent. # TYPE go_gc_gogc_percent gauge -# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes +# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes. # TYPE go_gc_gomemlimit_bytes gauge # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge @@ -52,7 +52,7 @@ # TYPE go_memstats_stack_sys_bytes gauge # HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte. # TYPE go_memstats_sys_bytes gauge -# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads +# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads. # TYPE go_sched_gomaxprocs_threads gauge # HELP go_threads Number of OS threads created. # TYPE go_threads gauge diff --git a/collector/fixtures/e2e-output-freebsd.txt b/collector/fixtures/e2e-output-freebsd.txt index e7b1dd50..fad76e6f 100644 --- a/collector/fixtures/e2e-output-freebsd.txt +++ b/collector/fixtures/e2e-output-freebsd.txt @@ -1,8 +1,8 @@ # HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles. # TYPE go_gc_duration_seconds summary -# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent +# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent. # TYPE go_gc_gogc_percent gauge -# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes +# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes. # TYPE go_gc_gomemlimit_bytes gauge # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge @@ -52,7 +52,7 @@ # TYPE go_memstats_stack_sys_bytes gauge # HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte. # TYPE go_memstats_sys_bytes gauge -# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads +# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads. # TYPE go_sched_gomaxprocs_threads gauge # HELP go_threads Number of OS threads created. # TYPE go_threads gauge diff --git a/collector/fixtures/e2e-output-netbsd.txt b/collector/fixtures/e2e-output-netbsd.txt index 1a6f1402..f6e73e2a 100644 --- a/collector/fixtures/e2e-output-netbsd.txt +++ b/collector/fixtures/e2e-output-netbsd.txt @@ -1,8 +1,8 @@ # HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles. # TYPE go_gc_duration_seconds summary -# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent +# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent. # TYPE go_gc_gogc_percent gauge -# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes +# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes. # TYPE go_gc_gomemlimit_bytes gauge # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge @@ -52,7 +52,7 @@ # TYPE go_memstats_stack_sys_bytes gauge # HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte. # TYPE go_memstats_sys_bytes gauge -# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads +# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads. # TYPE go_sched_gomaxprocs_threads gauge # HELP go_threads Number of OS threads created. # TYPE go_threads gauge diff --git a/collector/fixtures/e2e-output-openbsd.txt b/collector/fixtures/e2e-output-openbsd.txt index 96d2109d..8dc23cec 100644 --- a/collector/fixtures/e2e-output-openbsd.txt +++ b/collector/fixtures/e2e-output-openbsd.txt @@ -1,8 +1,8 @@ # HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles. # TYPE go_gc_duration_seconds summary -# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent +# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent. # TYPE go_gc_gogc_percent gauge -# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes +# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes. # TYPE go_gc_gomemlimit_bytes gauge # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge @@ -52,7 +52,7 @@ # TYPE go_memstats_stack_sys_bytes gauge # HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte. # TYPE go_memstats_sys_bytes gauge -# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads +# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads. # TYPE go_sched_gomaxprocs_threads gauge # HELP go_threads Number of OS threads created. # TYPE go_threads gauge diff --git a/collector/fixtures/e2e-output-solaris.txt b/collector/fixtures/e2e-output-solaris.txt index 9ac18df9..2f0f1d47 100644 --- a/collector/fixtures/e2e-output-solaris.txt +++ b/collector/fixtures/e2e-output-solaris.txt @@ -1,8 +1,8 @@ # HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles. # TYPE go_gc_duration_seconds summary -# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent +# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent. # TYPE go_gc_gogc_percent gauge -# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes +# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes. # TYPE go_gc_gomemlimit_bytes gauge # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge @@ -52,7 +52,7 @@ # TYPE go_memstats_stack_sys_bytes gauge # HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte. # TYPE go_memstats_sys_bytes gauge -# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads +# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads. # TYPE go_sched_gomaxprocs_threads gauge # HELP go_threads Number of OS threads created. # TYPE go_threads gauge diff --git a/collector/fixtures/e2e-output.txt b/collector/fixtures/e2e-output.txt index 66178b2d..45938a2b 100644 --- a/collector/fixtures/e2e-output.txt +++ b/collector/fixtures/e2e-output.txt @@ -1,8 +1,8 @@ # HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles. # TYPE go_gc_duration_seconds summary -# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent +# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent. # TYPE go_gc_gogc_percent gauge -# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes +# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes. # TYPE go_gc_gomemlimit_bytes gauge # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge @@ -52,7 +52,7 @@ # TYPE go_memstats_stack_sys_bytes gauge # HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte. # TYPE go_memstats_sys_bytes gauge -# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads +# HELP go_sched_gomaxprocs_threads The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously. Sourced from /sched/gomaxprocs:threads. # TYPE go_sched_gomaxprocs_threads gauge # HELP go_threads Number of OS threads created. # TYPE go_threads gauge diff --git a/go.mod b/go.mod index 75a5d6ba..e0670c58 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/opencontainers/selinux v1.11.1 github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 github.com/prometheus-community/go-runit v0.1.0 - github.com/prometheus/client_golang v1.20.5 + github.com/prometheus/client_golang v1.21.1 github.com/prometheus/client_model v0.6.1 github.com/prometheus/common v0.62.0 github.com/prometheus/exporter-toolkit v0.14.0 @@ -40,7 +40,7 @@ require ( github.com/dennwc/ioctl v1.0.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mdlayher/genetlink v1.3.2 // indirect github.com/mdlayher/socket v0.4.1 // indirect diff --git a/go.sum b/go.sum index 6c9ae14f..ed6eb97d 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,8 @@ github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2E github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jsimonetti/rtnetlink/v2 v2.0.2 h1:ZKlbCujrIpp4/u3V2Ka0oxlf4BCkt6ojkvpy3nZoCBY= github.com/jsimonetti/rtnetlink/v2 v2.0.2/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -75,8 +75,8 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus-community/go-runit v0.1.0 h1:uTWEj/Fn2RoLdfg/etSqwzgYNOYPrARx1BHUN052tGA= github.com/prometheus-community/go-runit v0.1.0/go.mod h1:AvJ9Jo3gAFu2lbM4+qfjdpq30FfiLDJZKbQ015u08IQ= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= +github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= From 2401158dd77d8cd775d882799aff9db784a1e449 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 12:47:56 +0200 Subject: [PATCH 12/13] build(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 (#3266) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.33.0 to 0.36.0. - [Commits](https://github.com/golang/net/compare/v0.33.0...v0.36.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index e0670c58..c7a2580a 100644 --- a/go.mod +++ b/go.mod @@ -51,11 +51,11 @@ require ( github.com/xhit/go-str2duration/v2 v2.1.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.33.0 // indirect + golang.org/x/crypto v0.35.0 // indirect + golang.org/x/net v0.36.0 // indirect golang.org/x/oauth2 v0.24.0 // indirect golang.org/x/sync v0.11.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/text v0.22.0 // indirect google.golang.org/protobuf v1.36.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index ed6eb97d..ef94789f 100644 --- a/go.sum +++ b/go.sum @@ -102,12 +102,12 @@ go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= @@ -117,8 +117,8 @@ golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 38d32a397720dfdaf547429ea1b40ab8cfa57e85 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Mon, 31 Mar 2025 17:52:53 +0200 Subject: [PATCH 13/13] pressure: Fix missing IRQ on older kernels (#3263) Fix "no data" error on kernels that support some PSI status, but don't yet have IRQ presure metrics. Only report "no data" error if `pressure` is enabled and no PSI metrics were found. Fixes: https://github.com/prometheus/node_exporter/issues/3259 Signed-off-by: Ben Kochie --- collector/pressure_linux.go | 39 +++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/collector/pressure_linux.go b/collector/pressure_linux.go index 7338b7e6..63b32d2a 100644 --- a/collector/pressure_linux.go +++ b/collector/pressure_linux.go @@ -27,8 +27,15 @@ import ( "github.com/prometheus/procfs" ) +const ( + psiResourceCPU = "cpu" + psiResourceIO = "io" + psiResourceMemory = "memory" + psiResourceIRQ = "irq" +) + var ( - psiResources = []string{"cpu", "io", "memory", "irq"} + psiResources = []string{psiResourceCPU, psiResourceIO, psiResourceMemory, psiResourceIRQ} ) type pressureStatsCollector struct { @@ -93,13 +100,18 @@ func NewPressureStatsCollector(logger *slog.Logger) (Collector, error) { // Update calls procfs.NewPSIStatsForResource for the different resources and updates the values func (c *pressureStatsCollector) Update(ch chan<- prometheus.Metric) error { + foundResources := 0 for _, res := range psiResources { c.logger.Debug("collecting statistics for resource", "resource", res) vals, err := c.fs.PSIStatsForResource(res) if err != nil { - if errors.Is(err, os.ErrNotExist) { - c.logger.Debug("pressure information is unavailable, you need a Linux kernel >= 4.20 and/or CONFIG_PSI enabled for your kernel") - return ErrNoData + if errors.Is(err, os.ErrNotExist) && res != psiResourceIRQ { + c.logger.Debug("pressure information is unavailable, you need a Linux kernel >= 4.20 and/or CONFIG_PSI enabled for your kernel", "resource", res) + continue + } + if errors.Is(err, os.ErrNotExist) && res == psiResourceIRQ { + c.logger.Debug("IRQ pressure information is unavailable, you need a Linux kernel >= 6.1 and/or CONFIG_PSI enabled for your kernel", "resource", res) + continue } if errors.Is(err, syscall.ENOTSUP) { c.logger.Debug("pressure information is disabled, add psi=1 kernel command line to enable it") @@ -109,28 +121,35 @@ func (c *pressureStatsCollector) Update(ch chan<- prometheus.Metric) error { } // IRQ pressure does not have 'some' data. // See https://github.com/torvalds/linux/blob/v6.9/include/linux/psi_types.h#L65 - if vals.Some == nil && res != "irq" { + if vals.Some == nil && res != psiResourceIRQ { c.logger.Debug("pressure information returned no 'some' data") return ErrNoData } - if vals.Full == nil && res != "cpu" { + if vals.Full == nil && res != psiResourceCPU { c.logger.Debug("pressure information returned no 'full' data") return ErrNoData } switch res { - case "cpu": + case psiResourceCPU: ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, float64(vals.Some.Total)/1000.0/1000.0) - case "io": + case psiResourceIO: ch <- prometheus.MustNewConstMetric(c.io, prometheus.CounterValue, float64(vals.Some.Total)/1000.0/1000.0) ch <- prometheus.MustNewConstMetric(c.ioFull, prometheus.CounterValue, float64(vals.Full.Total)/1000.0/1000.0) - case "memory": + case psiResourceMemory: ch <- prometheus.MustNewConstMetric(c.mem, prometheus.CounterValue, float64(vals.Some.Total)/1000.0/1000.0) ch <- prometheus.MustNewConstMetric(c.memFull, prometheus.CounterValue, float64(vals.Full.Total)/1000.0/1000.0) - case "irq": + case psiResourceIRQ: ch <- prometheus.MustNewConstMetric(c.irqFull, prometheus.CounterValue, float64(vals.Full.Total)/1000.0/1000.0) default: c.logger.Debug("did not account for resource", "resource", res) + continue } + foundResources++ + } + + if foundResources == 0 { + c.logger.Debug("pressure information is unavailable, you need a Linux kernel >= 4.20 and/or CONFIG_PSI enabled for your kernel") + return ErrNoData } return nil