mirror of
https://github.com/prometheus/node_exporter.git
synced 2025-08-20 18:33:52 -07:00
Compare commits
No commits in common. "master" and "v1.9.0" have entirely different histories.
|
@ -7,10 +7,10 @@ executors:
|
||||||
# should also be updated.
|
# should also be updated.
|
||||||
golang:
|
golang:
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/go:1.24
|
- image: cimg/go:1.23
|
||||||
arm:
|
arm:
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/go:1.24
|
- image: cimg/go:1.23
|
||||||
resource_class: arm.medium
|
resource_class: arm.medium
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -42,7 +42,7 @@ jobs:
|
||||||
- run: git diff --exit-code
|
- run: git diff --exit-code
|
||||||
build:
|
build:
|
||||||
machine:
|
machine:
|
||||||
image: ubuntu-2404:current
|
image: ubuntu-2204:current
|
||||||
parallelism: 3
|
parallelism: 3
|
||||||
steps:
|
steps:
|
||||||
- prometheus/setup_environment
|
- prometheus/setup_environment
|
||||||
|
@ -68,9 +68,9 @@ jobs:
|
||||||
destination: /build
|
destination: /build
|
||||||
test_docker:
|
test_docker:
|
||||||
machine:
|
machine:
|
||||||
image: ubuntu-2404:current
|
image: ubuntu-2204:current
|
||||||
environment:
|
environment:
|
||||||
DOCKER_TEST_IMAGE_NAME: quay.io/prometheus/golang-builder:1.24-base
|
DOCKER_TEST_IMAGE_NAME: quay.io/prometheus/golang-builder:1.23-base
|
||||||
REPO_PATH: github.com/prometheus/node_exporter
|
REPO_PATH: github.com/prometheus/node_exporter
|
||||||
steps:
|
steps:
|
||||||
- prometheus/setup_environment
|
- prometheus/setup_environment
|
||||||
|
|
28
.github/workflows/bsd.yml
vendored
28
.github/workflows/bsd.yml
vendored
|
@ -13,11 +13,11 @@ permissions:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GNU_TAR_VERSION: "1.35"
|
GNU_TAR_VERSION: "1.35"
|
||||||
GO_VERSION_DRAGONFLY: "1.24.1"
|
GO_VERSION_DRAGONFLY: "1.23.3"
|
||||||
GO_VERSION_FREEBSD: "123"
|
GO_VERSION_FREEBSD: "123"
|
||||||
GO_VERSION_NETBSD: "1.24.1"
|
GO_VERSION_NETBSD: "1.23.3"
|
||||||
GO_VERSION_OPENBSD: "1.23.1"
|
GO_VERSION_OPENBSD: "1.23.1"
|
||||||
GO_VERSION_SOLARIS: "1.24.1"
|
GO_VERSION_SOLARIS: "1.23.3"
|
||||||
|
|
||||||
# To spin up one of the VMs below, see the "Debug Shell" section here: https://github.com/vmactions
|
# To spin up one of the VMs below, see the "Debug Shell" section here: https://github.com/vmactions
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -26,9 +26,9 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@v4
|
||||||
- name: test-e2e
|
- name: test-e2e
|
||||||
uses: vmactions/freebsd-vm@8873d98fd1413b5977cb2f7348fe329775159892 # v1.1.9
|
uses: vmactions/freebsd-vm@v1
|
||||||
with:
|
with:
|
||||||
copyback: false
|
copyback: false
|
||||||
envs: 'GO_VERSION_FREEBSD GNU_TAR_VERSION'
|
envs: 'GO_VERSION_FREEBSD GNU_TAR_VERSION'
|
||||||
|
@ -73,9 +73,9 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@v4
|
||||||
- name: test-e2e
|
- name: test-e2e
|
||||||
uses: vmactions/openbsd-vm@7ac70b6de6f33efc74a90c1964afa3bcf0ee4401 # v1.1.6
|
uses: vmactions/openbsd-vm@v1
|
||||||
with:
|
with:
|
||||||
copyback: false
|
copyback: false
|
||||||
envs: 'GO_VERSION_OPENBSD GNU_TAR_VERSION'
|
envs: 'GO_VERSION_OPENBSD GNU_TAR_VERSION'
|
||||||
|
@ -119,9 +119,9 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@v4
|
||||||
- name: test-e2e
|
- name: test-e2e
|
||||||
uses: vmactions/netbsd-vm@46a58bbf03682b4cb24142b97fa315ae52bed573 # v1.1.8
|
uses: vmactions/netbsd-vm@v1
|
||||||
with:
|
with:
|
||||||
copyback: false
|
copyback: false
|
||||||
envs: 'GO_VERSION_NETBSD GNU_TAR_VERSION'
|
envs: 'GO_VERSION_NETBSD GNU_TAR_VERSION'
|
||||||
|
@ -167,9 +167,9 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@v4
|
||||||
- name: test-e2e
|
- name: test-e2e
|
||||||
uses: vmactions/dragonflybsd-vm@e3c420e8a2362c2496fca6e76a291abd46f5d8e7 # v1.1.0
|
uses: vmactions/dragonflybsd-vm@v1
|
||||||
with:
|
with:
|
||||||
copyback: false
|
copyback: false
|
||||||
envs: 'GO_VERSION_DRAGONFLY'
|
envs: 'GO_VERSION_DRAGONFLY'
|
||||||
|
@ -217,9 +217,9 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@v4
|
||||||
- name: test-e2e
|
- name: test-e2e
|
||||||
uses: vmactions/solaris-vm@cc8f82fa1a7cc746153ec3f71bf11f311f16e225 # v1.1.1
|
uses: vmactions/solaris-vm@v1
|
||||||
with:
|
with:
|
||||||
copyback: false
|
copyback: false
|
||||||
envs: 'GO_VERSION_SOLARIS'
|
envs: 'GO_VERSION_SOLARIS'
|
||||||
|
@ -276,7 +276,7 @@ jobs:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@v4
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
brew install \
|
brew install \
|
||||||
|
|
8
.github/workflows/golangci-lint.yml
vendored
8
.github/workflows/golangci-lint.yml
vendored
|
@ -26,14 +26,14 @@ jobs:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0
|
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.24.x
|
go-version: 1.23.x
|
||||||
- name: Install snmp_exporter/generator dependencies
|
- name: Install snmp_exporter/generator dependencies
|
||||||
run: sudo apt-get update && sudo apt-get -y install libsnmp-dev
|
run: sudo apt-get update && sudo apt-get -y install libsnmp-dev
|
||||||
if: github.repository == 'prometheus/snmp_exporter'
|
if: github.repository == 'prometheus/snmp_exporter'
|
||||||
- name: Lint
|
- name: Lint
|
||||||
uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # v6.5.2
|
uses: golangci/golangci-lint-action@ec5d18412c0aeab7936cb16880d708ba2a64e1ae # v6.2.0
|
||||||
with:
|
with:
|
||||||
args: --verbose
|
args: --verbose
|
||||||
version: v1.64.6
|
version: v1.63.4
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
go:
|
go:
|
||||||
# Whenever the Go version is updated here, .circle/config.yml and
|
# Whenever the Go version is updated here, .circle/config.yml and
|
||||||
# .promu.yml should also be updated.
|
# .promu.yml should also be updated.
|
||||||
version: 1.24
|
version: 1.23
|
||||||
cgo: true
|
cgo: true
|
||||||
repository:
|
repository:
|
||||||
path: github.com/prometheus/node_exporter
|
path: github.com/prometheus/node_exporter
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
go:
|
go:
|
||||||
# Whenever the Go version is updated here, .circle/config.yml and
|
# Whenever the Go version is updated here, .circle/config.yml and
|
||||||
# .promu-cgo.yml should also be updated.
|
# .promu-cgo.yml should also be updated.
|
||||||
version: 1.24
|
version: 1.23
|
||||||
repository:
|
repository:
|
||||||
path: github.com/prometheus/node_exporter
|
path: github.com/prometheus/node_exporter
|
||||||
build:
|
build:
|
||||||
|
|
|
@ -61,7 +61,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_
|
||||||
SKIP_GOLANGCI_LINT :=
|
SKIP_GOLANGCI_LINT :=
|
||||||
GOLANGCI_LINT :=
|
GOLANGCI_LINT :=
|
||||||
GOLANGCI_LINT_OPTS ?=
|
GOLANGCI_LINT_OPTS ?=
|
||||||
GOLANGCI_LINT_VERSION ?= v1.64.6
|
GOLANGCI_LINT_VERSION ?= v1.63.4
|
||||||
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
|
# 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.
|
# windows isn't included here because of the path separator being different.
|
||||||
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
|
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
# Node exporter
|
# Node exporter
|
||||||
|
|
||||||
[][circleci]
|
[][circleci]
|
||||||

|
[](https://buildkite.com/prometheus/node-exporter)
|
||||||

|
|
||||||
[][quay]
|
[][quay]
|
||||||
[][hub]
|
[][hub]
|
||||||
[][goreportcard]
|
[][goreportcard]
|
||||||
|
@ -201,7 +200,6 @@ logind | Exposes session counts from [logind](http://www.freedesktop.org/wiki/So
|
||||||
meminfo\_numa | Exposes memory statistics from `/sys/devices/system/node/node[0-9]*/meminfo`, `/sys/devices/system/node/node[0-9]*/numastat`. | Linux
|
meminfo\_numa | Exposes memory statistics from `/sys/devices/system/node/node[0-9]*/meminfo`, `/sys/devices/system/node/node[0-9]*/numastat`. | Linux
|
||||||
mountstats | Exposes filesystem statistics from `/proc/self/mountstats`. Exposes detailed NFS client statistics. | Linux
|
mountstats | Exposes filesystem statistics from `/proc/self/mountstats`. Exposes detailed NFS client statistics. | Linux
|
||||||
network_route | Exposes the routing table as metrics | Linux
|
network_route | Exposes the routing table as metrics | Linux
|
||||||
pcidevice | Exposes pci devices' information including their link status and parent devices. | Linux
|
|
||||||
perf | Exposes perf based metrics (Warning: Metrics are dependent on kernel configuration and settings). | Linux
|
perf | Exposes perf based metrics (Warning: Metrics are dependent on kernel configuration and settings). | Linux
|
||||||
processes | Exposes aggregate process statistics from `/proc`. | Linux
|
processes | Exposes aggregate process statistics from `/proc`. | Linux
|
||||||
qdisc | Exposes [queuing discipline](https://en.wikipedia.org/wiki/Network_scheduler#Linux_kernel) statistics | Linux
|
qdisc | Exposes [queuing discipline](https://en.wikipedia.org/wiki/Network_scheduler#Linux_kernel) statistics | Linux
|
||||||
|
|
|
@ -69,7 +69,7 @@ func (c *btrfsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
|
|
||||||
for _, s := range stats {
|
for _, s := range stats {
|
||||||
// match up procfs and ioctl info by filesystem UUID (without dashes)
|
// match up procfs and ioctl info by filesystem UUID (without dashes)
|
||||||
var fsUUID = strings.ReplaceAll(s.UUID, "-", "")
|
var fsUUID = strings.Replace(s.UUID, "-", "", -1)
|
||||||
ioctlStats := ioctlStatsMap[fsUUID]
|
ioctlStats := ioctlStatsMap[fsUUID]
|
||||||
c.updateBtrfsStats(ch, s, ioctlStats)
|
c.updateBtrfsStats(ch, s, ioctlStats)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,50 +30,22 @@ import (
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
nodeCPUPhysicalSecondsDesc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "physical_seconds_total"),
|
|
||||||
"Seconds the physical CPUs spent in each mode.",
|
|
||||||
[]string{"cpu", "mode"}, nil,
|
|
||||||
)
|
|
||||||
nodeCPUSRunQueueDesc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "runqueue"),
|
|
||||||
"Length of the run queue.", []string{"cpu"}, nil,
|
|
||||||
)
|
|
||||||
nodeCPUFlagsDesc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "flags"),
|
|
||||||
"CPU flags.",
|
|
||||||
[]string{"cpu", "flag"}, nil,
|
|
||||||
)
|
|
||||||
nodeCPUContextSwitchDesc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "context_switches_total"),
|
|
||||||
"Number of context switches.",
|
|
||||||
[]string{"cpu"}, nil,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
type cpuCollector struct {
|
type cpuCollector struct {
|
||||||
cpu typedDesc
|
cpu typedDesc
|
||||||
cpuPhysical typedDesc
|
logger *slog.Logger
|
||||||
cpuRunQueue typedDesc
|
tickPerSecond int64
|
||||||
cpuFlags typedDesc
|
|
||||||
cpuContextSwitch typedDesc
|
|
||||||
|
|
||||||
logger *slog.Logger
|
|
||||||
tickPerSecond float64
|
|
||||||
purrTicksPerSecond float64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerCollector("cpu", defaultEnabled, NewCpuCollector)
|
registerCollector("cpu", defaultEnabled, NewCpuCollector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func tickPerSecond() (float64, error) {
|
func tickPerSecond() (int64, error) {
|
||||||
ticks, err := C.sysconf(C._SC_CLK_TCK)
|
ticks, err := C.sysconf(C._SC_CLK_TCK)
|
||||||
if ticks == -1 || err != nil {
|
if ticks == -1 || err != nil {
|
||||||
return 0, fmt.Errorf("failed to get clock ticks per second: %v", err)
|
return 0, fmt.Errorf("failed to get clock ticks per second: %v", err)
|
||||||
}
|
}
|
||||||
return float64(ticks), nil
|
return int64(ticks), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCpuCollector(logger *slog.Logger) (Collector, error) {
|
func NewCpuCollector(logger *slog.Logger) (Collector, error) {
|
||||||
|
@ -81,22 +53,10 @@ func NewCpuCollector(logger *slog.Logger) (Collector, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pconfig, err := perfstat.PartitionStat()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &cpuCollector{
|
return &cpuCollector{
|
||||||
cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue},
|
cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue},
|
||||||
cpuPhysical: typedDesc{nodeCPUPhysicalSecondsDesc, prometheus.CounterValue},
|
logger: logger,
|
||||||
cpuRunQueue: typedDesc{nodeCPUSRunQueueDesc, prometheus.GaugeValue},
|
tickPerSecond: ticks,
|
||||||
cpuFlags: typedDesc{nodeCPUFlagsDesc, prometheus.GaugeValue},
|
|
||||||
cpuContextSwitch: typedDesc{nodeCPUContextSwitchDesc, prometheus.CounterValue},
|
|
||||||
logger: logger,
|
|
||||||
tickPerSecond: ticks,
|
|
||||||
purrTicksPerSecond: float64(pconfig.ProcessorMhz * 1e6),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,26 +67,10 @@ func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for n, stat := range stats {
|
for n, stat := range stats {
|
||||||
// LPAR metrics
|
ch <- c.cpu.mustNewConstMetric(float64(stat.User/c.tickPerSecond), strconv.Itoa(n), "user")
|
||||||
ch <- c.cpu.mustNewConstMetric(float64(stat.User)/c.tickPerSecond, strconv.Itoa(n), "user")
|
ch <- c.cpu.mustNewConstMetric(float64(stat.Sys/c.tickPerSecond), strconv.Itoa(n), "system")
|
||||||
ch <- c.cpu.mustNewConstMetric(float64(stat.Sys)/c.tickPerSecond, strconv.Itoa(n), "system")
|
ch <- c.cpu.mustNewConstMetric(float64(stat.Idle/c.tickPerSecond), strconv.Itoa(n), "idle")
|
||||||
ch <- c.cpu.mustNewConstMetric(float64(stat.Idle)/c.tickPerSecond, strconv.Itoa(n), "idle")
|
ch <- c.cpu.mustNewConstMetric(float64(stat.Wait/c.tickPerSecond), strconv.Itoa(n), "wait")
|
||||||
ch <- c.cpu.mustNewConstMetric(float64(stat.Wait)/c.tickPerSecond, strconv.Itoa(n), "wait")
|
|
||||||
|
|
||||||
// Physical CPU metrics
|
|
||||||
ch <- c.cpuPhysical.mustNewConstMetric(float64(stat.PIdle)/c.purrTicksPerSecond, strconv.Itoa(n), "pidle")
|
|
||||||
ch <- c.cpuPhysical.mustNewConstMetric(float64(stat.PUser)/c.purrTicksPerSecond, strconv.Itoa(n), "puser")
|
|
||||||
ch <- c.cpuPhysical.mustNewConstMetric(float64(stat.PSys)/c.purrTicksPerSecond, strconv.Itoa(n), "psys")
|
|
||||||
ch <- c.cpuPhysical.mustNewConstMetric(float64(stat.PWait)/c.purrTicksPerSecond, strconv.Itoa(n), "pwait")
|
|
||||||
|
|
||||||
// Run queue length
|
|
||||||
ch <- c.cpuRunQueue.mustNewConstMetric(float64(stat.RunQueue), strconv.Itoa(n))
|
|
||||||
|
|
||||||
// Flags
|
|
||||||
ch <- c.cpuFlags.mustNewConstMetric(float64(stat.SpurrFlag), strconv.Itoa(n), "spurr")
|
|
||||||
|
|
||||||
// Context switches
|
|
||||||
ch <- c.cpuContextSwitch.mustNewConstMetric(float64(stat.CSwitches), strconv.Itoa(n))
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ func NewCPUCollector(logger *slog.Logger) (Collector, error) {
|
||||||
isolcpus, err := sfs.IsolatedCPUs()
|
isolcpus, err := sfs.IsolatedCPUs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
return nil, fmt.Errorf("unable to get isolated cpus: %w", err)
|
return nil, fmt.Errorf("Unable to get isolated cpus: %w", err)
|
||||||
}
|
}
|
||||||
logger.Debug("Could not open isolated file", "error", err)
|
logger.Debug("Could not open isolated file", "error", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ func getCPUTemperatures() (map[int]float64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
keys := sortFilterSysmonProperties(props, "coretemp")
|
keys := sortFilterSysmonProperties(props, "coretemp")
|
||||||
for idx := range keys {
|
for idx, _ := range keys {
|
||||||
convertTemperatures(props[keys[idx]], res)
|
convertTemperatures(props[keys[idx]], res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
cpuVulnerabilitiesCollectorSubsystem = "cpu_vulnerabilities"
|
cpuVulerabilitiesCollector = "cpu_vulnerabilities"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
vulnerabilityDesc = prometheus.NewDesc(
|
vulnerabilityDesc = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(namespace, cpuVulnerabilitiesCollectorSubsystem, "info"),
|
prometheus.BuildFQName(namespace, cpuVulerabilitiesCollector, "info"),
|
||||||
"Details of each CPU vulnerability reported by sysfs. The value of the series is an int encoded state of the vulnerability. The same state is stored as a string in the label",
|
"Details of each CPU vulnerability reported by sysfs. The value of the series is an int encoded state of the vulnerability. The same state is stored as a string in the label",
|
||||||
[]string{"codename", "state", "mitigation"},
|
[]string{"codename", "state", "mitigation"},
|
||||||
nil,
|
nil,
|
||||||
|
@ -37,7 +37,7 @@ var (
|
||||||
type cpuVulnerabilitiesCollector struct{}
|
type cpuVulnerabilitiesCollector struct{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerCollector(cpuVulnerabilitiesCollectorSubsystem, defaultDisabled, NewVulnerabilitySysfsCollector)
|
registerCollector(cpuVulerabilitiesCollector, defaultDisabled, NewVulnerabilitySysfsCollector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVulnerabilitySysfsCollector(logger *slog.Logger) (Collector, error) {
|
func NewVulnerabilitySysfsCollector(logger *slog.Logger) (Collector, error) {
|
||||||
|
|
|
@ -30,19 +30,11 @@ type diskstatsCollector struct {
|
||||||
rbytes typedDesc
|
rbytes typedDesc
|
||||||
wbytes typedDesc
|
wbytes typedDesc
|
||||||
time typedDesc
|
time typedDesc
|
||||||
bsize typedDesc
|
|
||||||
qdepth typedDesc
|
|
||||||
|
|
||||||
rserv typedDesc
|
|
||||||
wserv typedDesc
|
|
||||||
|
|
||||||
xfers typedDesc
|
|
||||||
xrate typedDesc
|
|
||||||
|
|
||||||
deviceFilter deviceFilter
|
deviceFilter deviceFilter
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
|
|
||||||
tickPerSecond float64
|
tickPerSecond int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -65,54 +57,6 @@ func NewDiskstatsCollector(logger *slog.Logger) (Collector, error) {
|
||||||
wbytes: typedDesc{writtenBytesDesc, prometheus.CounterValue},
|
wbytes: typedDesc{writtenBytesDesc, prometheus.CounterValue},
|
||||||
time: typedDesc{ioTimeSecondsDesc, prometheus.CounterValue},
|
time: typedDesc{ioTimeSecondsDesc, prometheus.CounterValue},
|
||||||
|
|
||||||
bsize: typedDesc{
|
|
||||||
prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, diskSubsystem, "block_size_bytes"),
|
|
||||||
"Size of the block device in bytes.",
|
|
||||||
diskLabelNames, nil,
|
|
||||||
),
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
},
|
|
||||||
qdepth: typedDesc{
|
|
||||||
prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, diskSubsystem, "queue_depth"),
|
|
||||||
"Number of requests in the queue.",
|
|
||||||
diskLabelNames, nil,
|
|
||||||
),
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
},
|
|
||||||
rserv: typedDesc{
|
|
||||||
prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, diskSubsystem, "read_time_seconds_total"),
|
|
||||||
"The total time spent servicing read requests.",
|
|
||||||
diskLabelNames, nil,
|
|
||||||
),
|
|
||||||
prometheus.CounterValue,
|
|
||||||
},
|
|
||||||
wserv: typedDesc{
|
|
||||||
prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, diskSubsystem, "write_time_seconds_total"),
|
|
||||||
"The total time spent servicing write requests.",
|
|
||||||
diskLabelNames, nil,
|
|
||||||
),
|
|
||||||
prometheus.CounterValue,
|
|
||||||
},
|
|
||||||
xfers: typedDesc{
|
|
||||||
prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, diskSubsystem, "transfers_total"),
|
|
||||||
"The total number of transfers to/from disk.",
|
|
||||||
diskLabelNames, nil,
|
|
||||||
),
|
|
||||||
prometheus.CounterValue,
|
|
||||||
},
|
|
||||||
xrate: typedDesc{
|
|
||||||
prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, diskSubsystem, "transfers_to_disk_total"),
|
|
||||||
"The total number of transfers from disk.",
|
|
||||||
diskLabelNames, nil,
|
|
||||||
),
|
|
||||||
prometheus.CounterValue,
|
|
||||||
},
|
|
||||||
deviceFilter: deviceFilter,
|
deviceFilter: deviceFilter,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
|
||||||
|
@ -132,14 +76,7 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
}
|
}
|
||||||
ch <- c.rbytes.mustNewConstMetric(float64(stat.Rblks*512), stat.Name)
|
ch <- c.rbytes.mustNewConstMetric(float64(stat.Rblks*512), stat.Name)
|
||||||
ch <- c.wbytes.mustNewConstMetric(float64(stat.Wblks*512), stat.Name)
|
ch <- c.wbytes.mustNewConstMetric(float64(stat.Wblks*512), stat.Name)
|
||||||
ch <- c.time.mustNewConstMetric(float64(stat.Time)/float64(c.tickPerSecond), stat.Name)
|
ch <- c.time.mustNewConstMetric(float64(stat.Time/c.tickPerSecond), stat.Name)
|
||||||
|
|
||||||
ch <- c.bsize.mustNewConstMetric(float64(stat.BSize), stat.Name)
|
|
||||||
ch <- c.qdepth.mustNewConstMetric(float64(stat.QDepth), stat.Name)
|
|
||||||
ch <- c.rserv.mustNewConstMetric(float64(stat.Rserv)/1e9, stat.Name)
|
|
||||||
ch <- c.wserv.mustNewConstMetric(float64(stat.Wserv)/1e9, stat.Name)
|
|
||||||
ch <- c.xfers.mustNewConstMetric(float64(stat.Xfers), stat.Name)
|
|
||||||
ch <- c.xrate.mustNewConstMetric(float64(stat.XRate), stat.Name)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,9 +398,15 @@ func getUdevDeviceProperties(major, minor uint32) (udevInfo, error) {
|
||||||
|
|
||||||
line = strings.TrimPrefix(line, udevDevicePropertyPrefix)
|
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 {
|
if name, value, found := strings.Cut(line, "="); found {
|
||||||
info[name] = value
|
info[name] = value
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
if fields := strings.SplitN(line, "=", 2); len(fields) == 2 {
|
||||||
|
info[fields[0]] = fields[1]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return info, nil
|
return info, nil
|
||||||
|
|
|
@ -446,14 +446,13 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(stats) == 0 {
|
if stats == nil || len(stats) < 1 {
|
||||||
// No stats returned; device does not support ethtool stats.
|
// No stats returned; device does not support ethtool stats.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanitizing the metric names can lead to duplicate metric names. Therefore check for clashes beforehand.
|
// Sanitizing the metric names can lead to duplicate metric names. Therefore check for clashes beforehand.
|
||||||
metricFQNames := make(map[string]string)
|
metricFQNames := make(map[string]string)
|
||||||
renamedStats := make(map[string]uint64, len(stats))
|
|
||||||
for metric := range stats {
|
for metric := range stats {
|
||||||
metricName := SanitizeMetricName(metric)
|
metricName := SanitizeMetricName(metric)
|
||||||
if !c.metricsPattern.MatchString(metricName) {
|
if !c.metricsPattern.MatchString(metricName) {
|
||||||
|
@ -468,8 +467,6 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
metricFQNames[metricFQName] = ""
|
metricFQNames[metricFQName] = ""
|
||||||
} else {
|
} else {
|
||||||
metricFQNames[metricFQName] = metricName
|
metricFQNames[metricFQName] = metricName
|
||||||
// Later we'll go look for the stat with the "sanitized" metric name, so we can copy it there already
|
|
||||||
renamedStats[metricName] = stats[metric]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +484,7 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val := renamedStats[metric]
|
val := stats[metric]
|
||||||
|
|
||||||
// Check to see if this metric exists; if not then create it and store it in c.entries.
|
// Check to see if this metric exists; if not then create it and store it in c.entries.
|
||||||
entry := c.entryWithCreate(metric, metricFQName)
|
entry := c.entryWithCreate(metric, metricFQName)
|
||||||
|
|
|
@ -212,18 +212,16 @@ func (e *EthtoolFixture) LinkInfo(intf string) (ethtool.EthtoolCmd, error) {
|
||||||
|
|
||||||
items := strings.Split(line, ": ")
|
items := strings.Split(line, ": ")
|
||||||
if items[0] == "Supported pause frame use" {
|
if items[0] == "Supported pause frame use" {
|
||||||
switch items[1] {
|
if items[1] == "Symmetric" {
|
||||||
case "Symmetric":
|
|
||||||
res.Supported |= (1 << unix.ETHTOOL_LINK_MODE_Pause_BIT)
|
res.Supported |= (1 << unix.ETHTOOL_LINK_MODE_Pause_BIT)
|
||||||
case "Receive-only":
|
} else if items[1] == "Receive-only" {
|
||||||
res.Supported |= (1 << unix.ETHTOOL_LINK_MODE_Asym_Pause_BIT)
|
res.Supported |= (1 << unix.ETHTOOL_LINK_MODE_Asym_Pause_BIT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if items[0] == "Advertised pause frame use" {
|
if items[0] == "Advertised pause frame use" {
|
||||||
switch items[1] {
|
if items[1] == "Symmetric" {
|
||||||
case "Symmetric":
|
|
||||||
res.Advertising |= (1 << unix.ETHTOOL_LINK_MODE_Pause_BIT)
|
res.Advertising |= (1 << unix.ETHTOOL_LINK_MODE_Pause_BIT)
|
||||||
case "Receive-only":
|
} else if items[1] == "Receive-only" {
|
||||||
res.Advertising |= (1 << unix.ETHTOOL_LINK_MODE_Asym_Pause_BIT)
|
res.Advertising |= (1 << unix.ETHTOOL_LINK_MODE_Asym_Pause_BIT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,7 +269,6 @@ func NewEthtoolTestCollector(logger *slog.Logger) (Collector, error) {
|
||||||
|
|
||||||
func TestBuildEthtoolFQName(t *testing.T) {
|
func TestBuildEthtoolFQName(t *testing.T) {
|
||||||
testcases := map[string]string{
|
testcases := map[string]string{
|
||||||
"port.rx_errors": "node_ethtool_port_received_errors",
|
|
||||||
"rx_errors": "node_ethtool_received_errors",
|
"rx_errors": "node_ethtool_received_errors",
|
||||||
"Queue[0] AllocFails": "node_ethtool_queue_0_allocfails",
|
"Queue[0] AllocFails": "node_ethtool_queue_0_allocfails",
|
||||||
"Tx LPI entry count": "node_ethtool_transmitted_lpi_entry_count",
|
"Tx LPI entry count": "node_ethtool_transmitted_lpi_entry_count",
|
||||||
|
@ -295,9 +292,6 @@ node_ethtool_align_errors{device="eth0"} 0
|
||||||
# HELP node_ethtool_info A metric with a constant '1' value labeled by bus_info, device, driver, expansion_rom_version, firmware_version, version.
|
# HELP node_ethtool_info A metric with a constant '1' value labeled by bus_info, device, driver, expansion_rom_version, firmware_version, version.
|
||||||
# TYPE node_ethtool_info gauge
|
# TYPE node_ethtool_info gauge
|
||||||
node_ethtool_info{bus_info="0000:00:1f.6",device="eth0",driver="e1000e",expansion_rom_version="",firmware_version="0.5-4",version="5.11.0-22-generic"} 1
|
node_ethtool_info{bus_info="0000:00:1f.6",device="eth0",driver="e1000e",expansion_rom_version="",firmware_version="0.5-4",version="5.11.0-22-generic"} 1
|
||||||
# HELP node_ethtool_port_received_dropped Network interface port_rx_dropped
|
|
||||||
# TYPE node_ethtool_port_received_dropped untyped
|
|
||||||
node_ethtool_port_received_dropped{device="eth0"} 12028
|
|
||||||
# HELP node_ethtool_received_broadcast Network interface rx_broadcast
|
# HELP node_ethtool_received_broadcast Network interface rx_broadcast
|
||||||
# TYPE node_ethtool_received_broadcast untyped
|
# TYPE node_ethtool_received_broadcast untyped
|
||||||
node_ethtool_received_broadcast{device="eth0"} 5792
|
node_ethtool_received_broadcast{device="eth0"} 5792
|
||||||
|
|
|
@ -53,9 +53,9 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) {
|
||||||
mountPoint: stat.MountPoint,
|
mountPoint: stat.MountPoint,
|
||||||
fsType: fstype,
|
fsType: fstype,
|
||||||
},
|
},
|
||||||
size: float64(stat.TotalBlocks * 512.0),
|
size: float64(stat.TotalBlocks / 512.0),
|
||||||
free: float64(stat.FreeBlocks * 512.0),
|
free: float64(stat.FreeBlocks / 512.0),
|
||||||
avail: float64(stat.FreeBlocks * 512.0), // AIX doesn't distinguish between free and available blocks.
|
avail: float64(stat.FreeBlocks / 512.0), // AIX doesn't distinguish between free and available blocks.
|
||||||
files: float64(stat.TotalInodes),
|
files: float64(stat.TotalInodes),
|
||||||
filesFree: float64(stat.FreeInodes),
|
filesFree: float64(stat.FreeInodes),
|
||||||
ro: ro,
|
ro: ro,
|
||||||
|
|
|
@ -89,7 +89,7 @@ type filesystemStats struct {
|
||||||
labels filesystemLabels
|
labels filesystemLabels
|
||||||
size, free, avail float64
|
size, free, avail float64
|
||||||
files, filesFree float64
|
files, filesFree float64
|
||||||
purgeable float64
|
purgeable *float64
|
||||||
ro, deviceError float64
|
ro, deviceError float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,10 +232,11 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
c.mountInfoDesc, prometheus.GaugeValue,
|
c.mountInfoDesc, prometheus.GaugeValue,
|
||||||
1.0, s.labels.device, s.labels.major, s.labels.minor, s.labels.mountPoint,
|
1.0, s.labels.device, s.labels.major, s.labels.minor, s.labels.mountPoint,
|
||||||
)
|
)
|
||||||
if s.purgeable >= 0 {
|
if s.purgeable != nil {
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.purgeableDesc, prometheus.GaugeValue,
|
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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,8 +215,8 @@ func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) {
|
||||||
|
|
||||||
// Ensure we handle the translation of \040 and \011
|
// Ensure we handle the translation of \040 and \011
|
||||||
// as per fstab(5).
|
// as per fstab(5).
|
||||||
parts[4] = strings.ReplaceAll(parts[4], "\\040", " ")
|
parts[4] = strings.Replace(parts[4], "\\040", " ", -1)
|
||||||
parts[4] = strings.ReplaceAll(parts[4], "\\011", "\t")
|
parts[4] = strings.Replace(parts[4], "\\011", "\t", -1)
|
||||||
|
|
||||||
filesystems = append(filesystems, filesystemLabels{
|
filesystems = append(filesystems, filesystemLabels{
|
||||||
device: parts[m+3],
|
device: parts[m+3],
|
||||||
|
|
|
@ -20,26 +20,23 @@ package collector
|
||||||
#cgo CFLAGS: -x objective-c
|
#cgo CFLAGS: -x objective-c
|
||||||
#cgo LDFLAGS: -framework Foundation
|
#cgo LDFLAGS: -framework Foundation
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
Float64 purgeable(char *path) {
|
Float64 *purgeable(char *path) {
|
||||||
Float64 value = -1.0f;
|
CFNumberRef tmp;
|
||||||
|
Float64 *value;
|
||||||
@autoreleasepool {
|
NSError *error = nil;
|
||||||
NSError *error = nil;
|
NSString *str = [NSString stringWithUTF8String:path];
|
||||||
NSString *str = [NSString stringWithUTF8String:path];
|
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:str];
|
||||||
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:str];
|
NSDictionary *results = [fileURL resourceValuesForKeys:@[NSURLVolumeAvailableCapacityForImportantUsageKey] error:&error];
|
||||||
|
if (results) {
|
||||||
NSDictionary *results = [fileURL resourceValuesForKeys:@[NSURLVolumeAvailableCapacityForImportantUsageKey] error:&error];
|
if ((tmp = CFDictionaryGetValue((CFDictionaryRef)results, NSURLVolumeAvailableCapacityForImportantUsageKey)) == NULL)
|
||||||
if (results) {
|
return NULL;
|
||||||
CFNumberRef tmp = CFDictionaryGetValue((CFDictionaryRef)results, NSURLVolumeAvailableCapacityForImportantUsageKey);
|
value = (Float64 *)malloc(sizeof(Float64));
|
||||||
if (tmp != NULL) {
|
if (CFNumberGetValue(tmp, kCFNumberFloat64Type, value)) {
|
||||||
CFNumberGetValue(tmp, kCFNumberFloat64Type, &value);
|
return value;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[fileURL release];
|
|
||||||
}
|
}
|
||||||
|
free(value);
|
||||||
return value;
|
return NULL;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
@ -92,9 +89,6 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) {
|
||||||
ro = 1
|
ro = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
mountpointCString := C.CString(mountpoint)
|
|
||||||
defer C.free(unsafe.Pointer(mountpointCString))
|
|
||||||
|
|
||||||
stats = append(stats, filesystemStats{
|
stats = append(stats, filesystemStats{
|
||||||
labels: filesystemLabels{
|
labels: filesystemLabels{
|
||||||
device: device,
|
device: device,
|
||||||
|
@ -106,7 +100,7 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) {
|
||||||
avail: float64(mnt[i].f_bavail) * float64(mnt[i].f_bsize),
|
avail: float64(mnt[i].f_bavail) * float64(mnt[i].f_bsize),
|
||||||
files: float64(mnt[i].f_files),
|
files: float64(mnt[i].f_files),
|
||||||
filesFree: float64(mnt[i].f_ffree),
|
filesFree: float64(mnt[i].f_ffree),
|
||||||
purgeable: float64(C.purgeable(mountpointCString)),
|
purgeable: (*float64)(C.purgeable(C.CString(mountpoint))),
|
||||||
ro: ro,
|
ro: ro,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.
|
# 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
|
# 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
|
# 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
|
# TYPE go_gc_gomemlimit_bytes gauge
|
||||||
# HELP go_goroutines Number of goroutines that currently exist.
|
# HELP go_goroutines Number of goroutines that currently exist.
|
||||||
# TYPE go_goroutines gauge
|
# TYPE go_goroutines gauge
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
# TYPE go_memstats_stack_sys_bytes gauge
|
# TYPE go_memstats_stack_sys_bytes gauge
|
||||||
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
||||||
# TYPE go_memstats_sys_bytes gauge
|
# 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
|
# TYPE go_sched_gomaxprocs_threads gauge
|
||||||
# HELP go_threads Number of OS threads created.
|
# HELP go_threads Number of OS threads created.
|
||||||
# TYPE go_threads gauge
|
# TYPE go_threads gauge
|
||||||
|
@ -1585,14 +1585,6 @@ node_md_blocks_synced{device="md6"} 1.6775552e+07
|
||||||
node_md_blocks_synced{device="md7"} 7.813735424e+09
|
node_md_blocks_synced{device="md7"} 7.813735424e+09
|
||||||
node_md_blocks_synced{device="md8"} 1.6775552e+07
|
node_md_blocks_synced{device="md8"} 1.6775552e+07
|
||||||
node_md_blocks_synced{device="md9"} 0
|
node_md_blocks_synced{device="md9"} 0
|
||||||
# HELP node_md_degraded Number of degraded disks on device.
|
|
||||||
# TYPE node_md_degraded gauge
|
|
||||||
node_md_degraded{device="md0"} 0
|
|
||||||
node_md_degraded{device="md1"} 0
|
|
||||||
node_md_degraded{device="md10"} 0
|
|
||||||
node_md_degraded{device="md4"} 0
|
|
||||||
node_md_degraded{device="md5"} 1
|
|
||||||
node_md_degraded{device="md6"} 1
|
|
||||||
# HELP node_md_disks Number of active/failed/spare disks of device.
|
# HELP node_md_disks Number of active/failed/spare disks of device.
|
||||||
# TYPE node_md_disks gauge
|
# TYPE node_md_disks gauge
|
||||||
node_md_disks{device="md0",state="active"} 2
|
node_md_disks{device="md0",state="active"} 2
|
||||||
|
@ -1665,14 +1657,6 @@ node_md_disks_required{device="md6"} 2
|
||||||
node_md_disks_required{device="md7"} 4
|
node_md_disks_required{device="md7"} 4
|
||||||
node_md_disks_required{device="md8"} 2
|
node_md_disks_required{device="md8"} 2
|
||||||
node_md_disks_required{device="md9"} 4
|
node_md_disks_required{device="md9"} 4
|
||||||
# HELP node_md_raid_disks Number of raid disks on device.
|
|
||||||
# TYPE node_md_raid_disks gauge
|
|
||||||
node_md_raid_disks{device="md0"} 2
|
|
||||||
node_md_raid_disks{device="md1"} 2
|
|
||||||
node_md_raid_disks{device="md10"} 4
|
|
||||||
node_md_raid_disks{device="md4"} 3
|
|
||||||
node_md_raid_disks{device="md5"} 3
|
|
||||||
node_md_raid_disks{device="md6"} 4
|
|
||||||
# HELP node_md_state Indicates the state of md-device.
|
# HELP node_md_state Indicates the state of md-device.
|
||||||
# TYPE node_md_state gauge
|
# TYPE node_md_state gauge
|
||||||
node_md_state{device="md0",state="active"} 1
|
node_md_state{device="md0",state="active"} 1
|
||||||
|
@ -2832,26 +2816,6 @@ node_os_info{build_id="",id="ubuntu",id_like="debian",image_id="",image_version=
|
||||||
# HELP node_os_version Metric containing the major.minor part of the OS version.
|
# HELP node_os_version Metric containing the major.minor part of the OS version.
|
||||||
# TYPE node_os_version gauge
|
# TYPE node_os_version gauge
|
||||||
node_os_version{id="ubuntu",id_like="debian",name="Ubuntu"} 20.04
|
node_os_version{id="ubuntu",id_like="debian",name="Ubuntu"} 20.04
|
||||||
# HELP node_pcidevice_current_link_transfers_per_second Value of current link's transfers per second (T/s)
|
|
||||||
# TYPE node_pcidevice_current_link_transfers_per_second gauge
|
|
||||||
node_pcidevice_current_link_transfers_per_second{bus="00",device="02",function="1",segment="0000"} 8e+09
|
|
||||||
node_pcidevice_current_link_transfers_per_second{bus="01",device="00",function="0",segment="0000"} 8e+09
|
|
||||||
# HELP node_pcidevice_current_link_width Value of current link's width (number of lanes)
|
|
||||||
# TYPE node_pcidevice_current_link_width gauge
|
|
||||||
node_pcidevice_current_link_width{bus="00",device="02",function="1",segment="0000"} 4
|
|
||||||
node_pcidevice_current_link_width{bus="01",device="00",function="0",segment="0000"} 4
|
|
||||||
# HELP node_pcidevice_info Non-numeric data from /sys/bus/pci/devices/<location>, value is always 1.
|
|
||||||
# TYPE node_pcidevice_info gauge
|
|
||||||
node_pcidevice_info{bus="00",class_id="0x060400",device="02",function="1",parent_bus="*",parent_device="*",parent_function="*",parent_segment="*",revision="0x00",segment="0000",subsystem_device_id="0x5095",subsystem_vendor_id="0x17aa",vendor_id="0x1634"} 1
|
|
||||||
node_pcidevice_info{bus="01",class_id="0x010802",device="00",function="0",parent_bus="00",parent_device="02",parent_function="1",parent_segment="0000",revision="0x01",segment="0000",subsystem_device_id="0x5021",subsystem_vendor_id="0xc0a9",vendor_id="0x540a"} 1
|
|
||||||
# HELP node_pcidevice_max_link_transfers_per_second Value of maximum link's transfers per second (T/s)
|
|
||||||
# TYPE node_pcidevice_max_link_transfers_per_second gauge
|
|
||||||
node_pcidevice_max_link_transfers_per_second{bus="00",device="02",function="1",segment="0000"} 8e+09
|
|
||||||
node_pcidevice_max_link_transfers_per_second{bus="01",device="00",function="0",segment="0000"} 1.6e+10
|
|
||||||
# HELP node_pcidevice_max_link_width Value of maximum link's width (number of lanes)
|
|
||||||
# TYPE node_pcidevice_max_link_width gauge
|
|
||||||
node_pcidevice_max_link_width{bus="00",device="02",function="1",segment="0000"} 8
|
|
||||||
node_pcidevice_max_link_width{bus="01",device="00",function="0",segment="0000"} 4
|
|
||||||
# HELP node_power_supply_capacity capacity value of /sys/class/power_supply/<power_supply>.
|
# HELP node_power_supply_capacity capacity value of /sys/class/power_supply/<power_supply>.
|
||||||
# TYPE node_power_supply_capacity gauge
|
# TYPE node_power_supply_capacity gauge
|
||||||
node_power_supply_capacity{power_supply="BAT0"} 81
|
node_power_supply_capacity{power_supply="BAT0"} 81
|
||||||
|
@ -3011,7 +2975,6 @@ node_scrape_collector_success{collector="nfs"} 1
|
||||||
node_scrape_collector_success{collector="nfsd"} 1
|
node_scrape_collector_success{collector="nfsd"} 1
|
||||||
node_scrape_collector_success{collector="nvme"} 1
|
node_scrape_collector_success{collector="nvme"} 1
|
||||||
node_scrape_collector_success{collector="os"} 1
|
node_scrape_collector_success{collector="os"} 1
|
||||||
node_scrape_collector_success{collector="pcidevice"} 1
|
|
||||||
node_scrape_collector_success{collector="powersupplyclass"} 1
|
node_scrape_collector_success{collector="powersupplyclass"} 1
|
||||||
node_scrape_collector_success{collector="pressure"} 1
|
node_scrape_collector_success{collector="pressure"} 1
|
||||||
node_scrape_collector_success{collector="processes"} 1
|
node_scrape_collector_success{collector="processes"} 1
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.
|
# 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
|
# 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
|
# 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
|
# TYPE go_gc_gomemlimit_bytes gauge
|
||||||
# HELP go_goroutines Number of goroutines that currently exist.
|
# HELP go_goroutines Number of goroutines that currently exist.
|
||||||
# TYPE go_goroutines gauge
|
# TYPE go_goroutines gauge
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
# TYPE go_memstats_stack_sys_bytes gauge
|
# TYPE go_memstats_stack_sys_bytes gauge
|
||||||
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
||||||
# TYPE go_memstats_sys_bytes gauge
|
# 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
|
# TYPE go_sched_gomaxprocs_threads gauge
|
||||||
# HELP go_threads Number of OS threads created.
|
# HELP go_threads Number of OS threads created.
|
||||||
# TYPE go_threads gauge
|
# TYPE go_threads gauge
|
||||||
|
@ -251,20 +251,6 @@ 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
|
# 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
|
# TYPE node_xfrm_out_state_seq_error_packets_total counter
|
||||||
node_xfrm_out_state_seq_error_packets_total 543
|
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.
|
# HELP promhttp_metric_handler_errors_total Total number of internal errors encountered by the promhttp metric handler.
|
||||||
# TYPE promhttp_metric_handler_errors_total counter
|
# TYPE promhttp_metric_handler_errors_total counter
|
||||||
promhttp_metric_handler_errors_total{cause="encoding"} 0
|
promhttp_metric_handler_errors_total{cause="encoding"} 0
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.
|
# 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
|
# 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
|
# 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
|
# TYPE go_gc_gomemlimit_bytes gauge
|
||||||
# HELP go_goroutines Number of goroutines that currently exist.
|
# HELP go_goroutines Number of goroutines that currently exist.
|
||||||
# TYPE go_goroutines gauge
|
# TYPE go_goroutines gauge
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
# TYPE go_memstats_stack_sys_bytes gauge
|
# TYPE go_memstats_stack_sys_bytes gauge
|
||||||
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
||||||
# TYPE go_memstats_sys_bytes gauge
|
# 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
|
# TYPE go_sched_gomaxprocs_threads gauge
|
||||||
# HELP go_threads Number of OS threads created.
|
# HELP go_threads Number of OS threads created.
|
||||||
# TYPE go_threads gauge
|
# TYPE go_threads gauge
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.
|
# 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
|
# 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
|
# 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
|
# TYPE go_gc_gomemlimit_bytes gauge
|
||||||
# HELP go_goroutines Number of goroutines that currently exist.
|
# HELP go_goroutines Number of goroutines that currently exist.
|
||||||
# TYPE go_goroutines gauge
|
# TYPE go_goroutines gauge
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
# TYPE go_memstats_stack_sys_bytes gauge
|
# TYPE go_memstats_stack_sys_bytes gauge
|
||||||
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
||||||
# TYPE go_memstats_sys_bytes gauge
|
# 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
|
# TYPE go_sched_gomaxprocs_threads gauge
|
||||||
# HELP go_threads Number of OS threads created.
|
# HELP go_threads Number of OS threads created.
|
||||||
# TYPE go_threads gauge
|
# TYPE go_threads gauge
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.
|
# 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
|
# 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
|
# 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
|
# TYPE go_gc_gomemlimit_bytes gauge
|
||||||
# HELP go_goroutines Number of goroutines that currently exist.
|
# HELP go_goroutines Number of goroutines that currently exist.
|
||||||
# TYPE go_goroutines gauge
|
# TYPE go_goroutines gauge
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
# TYPE go_memstats_stack_sys_bytes gauge
|
# TYPE go_memstats_stack_sys_bytes gauge
|
||||||
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
||||||
# TYPE go_memstats_sys_bytes gauge
|
# 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
|
# TYPE go_sched_gomaxprocs_threads gauge
|
||||||
# HELP go_threads Number of OS threads created.
|
# HELP go_threads Number of OS threads created.
|
||||||
# TYPE go_threads gauge
|
# TYPE go_threads gauge
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.
|
# 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
|
# 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
|
# 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
|
# TYPE go_gc_gomemlimit_bytes gauge
|
||||||
# HELP go_goroutines Number of goroutines that currently exist.
|
# HELP go_goroutines Number of goroutines that currently exist.
|
||||||
# TYPE go_goroutines gauge
|
# TYPE go_goroutines gauge
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
# TYPE go_memstats_stack_sys_bytes gauge
|
# TYPE go_memstats_stack_sys_bytes gauge
|
||||||
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
||||||
# TYPE go_memstats_sys_bytes gauge
|
# 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
|
# TYPE go_sched_gomaxprocs_threads gauge
|
||||||
# HELP go_threads Number of OS threads created.
|
# HELP go_threads Number of OS threads created.
|
||||||
# TYPE go_threads gauge
|
# TYPE go_threads gauge
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.
|
# 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
|
# 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
|
# 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
|
# TYPE go_gc_gomemlimit_bytes gauge
|
||||||
# HELP go_goroutines Number of goroutines that currently exist.
|
# HELP go_goroutines Number of goroutines that currently exist.
|
||||||
# TYPE go_goroutines gauge
|
# TYPE go_goroutines gauge
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
# TYPE go_memstats_stack_sys_bytes gauge
|
# TYPE go_memstats_stack_sys_bytes gauge
|
||||||
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
||||||
# TYPE go_memstats_sys_bytes gauge
|
# 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
|
# TYPE go_sched_gomaxprocs_threads gauge
|
||||||
# HELP go_threads Number of OS threads created.
|
# HELP go_threads Number of OS threads created.
|
||||||
# TYPE go_threads gauge
|
# TYPE go_threads gauge
|
||||||
|
@ -91,6 +91,12 @@ 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="DMA"} 1
|
||||||
node_buddyinfo_blocks{node="0",size="9",zone="DMA32"} 0
|
node_buddyinfo_blocks{node="0",size="9",zone="DMA32"} 0
|
||||||
node_buddyinfo_blocks{node="0",size="9",zone="Normal"} 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.
|
# 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
|
# 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.
|
# 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.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.
|
# 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
|
# 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
|
# 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
|
# TYPE go_gc_gomemlimit_bytes gauge
|
||||||
# HELP go_goroutines Number of goroutines that currently exist.
|
# HELP go_goroutines Number of goroutines that currently exist.
|
||||||
# TYPE go_goroutines gauge
|
# TYPE go_goroutines gauge
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
# TYPE go_memstats_stack_sys_bytes gauge
|
# TYPE go_memstats_stack_sys_bytes gauge
|
||||||
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
# HELP go_memstats_sys_bytes Number of bytes obtained from system. Equals to /memory/classes/total:byte.
|
||||||
# TYPE go_memstats_sys_bytes gauge
|
# 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
|
# TYPE go_sched_gomaxprocs_threads gauge
|
||||||
# HELP go_threads Number of OS threads created.
|
# HELP go_threads Number of OS threads created.
|
||||||
# TYPE go_threads gauge
|
# TYPE go_threads gauge
|
||||||
|
@ -1607,14 +1607,6 @@ node_md_blocks_synced{device="md6"} 1.6775552e+07
|
||||||
node_md_blocks_synced{device="md7"} 7.813735424e+09
|
node_md_blocks_synced{device="md7"} 7.813735424e+09
|
||||||
node_md_blocks_synced{device="md8"} 1.6775552e+07
|
node_md_blocks_synced{device="md8"} 1.6775552e+07
|
||||||
node_md_blocks_synced{device="md9"} 0
|
node_md_blocks_synced{device="md9"} 0
|
||||||
# HELP node_md_degraded Number of degraded disks on device.
|
|
||||||
# TYPE node_md_degraded gauge
|
|
||||||
node_md_degraded{device="md0"} 0
|
|
||||||
node_md_degraded{device="md1"} 0
|
|
||||||
node_md_degraded{device="md10"} 0
|
|
||||||
node_md_degraded{device="md4"} 0
|
|
||||||
node_md_degraded{device="md5"} 1
|
|
||||||
node_md_degraded{device="md6"} 1
|
|
||||||
# HELP node_md_disks Number of active/failed/spare disks of device.
|
# HELP node_md_disks Number of active/failed/spare disks of device.
|
||||||
# TYPE node_md_disks gauge
|
# TYPE node_md_disks gauge
|
||||||
node_md_disks{device="md0",state="active"} 2
|
node_md_disks{device="md0",state="active"} 2
|
||||||
|
@ -1687,14 +1679,6 @@ node_md_disks_required{device="md6"} 2
|
||||||
node_md_disks_required{device="md7"} 4
|
node_md_disks_required{device="md7"} 4
|
||||||
node_md_disks_required{device="md8"} 2
|
node_md_disks_required{device="md8"} 2
|
||||||
node_md_disks_required{device="md9"} 4
|
node_md_disks_required{device="md9"} 4
|
||||||
# HELP node_md_raid_disks Number of raid disks on device.
|
|
||||||
# TYPE node_md_raid_disks gauge
|
|
||||||
node_md_raid_disks{device="md0"} 2
|
|
||||||
node_md_raid_disks{device="md1"} 2
|
|
||||||
node_md_raid_disks{device="md10"} 4
|
|
||||||
node_md_raid_disks{device="md4"} 3
|
|
||||||
node_md_raid_disks{device="md5"} 3
|
|
||||||
node_md_raid_disks{device="md6"} 4
|
|
||||||
# HELP node_md_state Indicates the state of md-device.
|
# HELP node_md_state Indicates the state of md-device.
|
||||||
# TYPE node_md_state gauge
|
# TYPE node_md_state gauge
|
||||||
node_md_state{device="md0",state="active"} 1
|
node_md_state{device="md0",state="active"} 1
|
||||||
|
@ -2854,26 +2838,6 @@ node_os_info{build_id="",id="ubuntu",id_like="debian",image_id="",image_version=
|
||||||
# HELP node_os_version Metric containing the major.minor part of the OS version.
|
# HELP node_os_version Metric containing the major.minor part of the OS version.
|
||||||
# TYPE node_os_version gauge
|
# TYPE node_os_version gauge
|
||||||
node_os_version{id="ubuntu",id_like="debian",name="Ubuntu"} 20.04
|
node_os_version{id="ubuntu",id_like="debian",name="Ubuntu"} 20.04
|
||||||
# HELP node_pcidevice_current_link_transfers_per_second Value of current link's transfers per second (T/s)
|
|
||||||
# TYPE node_pcidevice_current_link_transfers_per_second gauge
|
|
||||||
node_pcidevice_current_link_transfers_per_second{bus="00",device="02",function="1",segment="0000"} 8e+09
|
|
||||||
node_pcidevice_current_link_transfers_per_second{bus="01",device="00",function="0",segment="0000"} 8e+09
|
|
||||||
# HELP node_pcidevice_current_link_width Value of current link's width (number of lanes)
|
|
||||||
# TYPE node_pcidevice_current_link_width gauge
|
|
||||||
node_pcidevice_current_link_width{bus="00",device="02",function="1",segment="0000"} 4
|
|
||||||
node_pcidevice_current_link_width{bus="01",device="00",function="0",segment="0000"} 4
|
|
||||||
# HELP node_pcidevice_info Non-numeric data from /sys/bus/pci/devices/<location>, value is always 1.
|
|
||||||
# TYPE node_pcidevice_info gauge
|
|
||||||
node_pcidevice_info{bus="00",class_id="0x060400",device="02",function="1",parent_bus="*",parent_device="*",parent_function="*",parent_segment="*",revision="0x00",segment="0000",subsystem_device_id="0x5095",subsystem_vendor_id="0x17aa",vendor_id="0x1634"} 1
|
|
||||||
node_pcidevice_info{bus="01",class_id="0x010802",device="00",function="0",parent_bus="00",parent_device="02",parent_function="1",parent_segment="0000",revision="0x01",segment="0000",subsystem_device_id="0x5021",subsystem_vendor_id="0xc0a9",vendor_id="0x540a"} 1
|
|
||||||
# HELP node_pcidevice_max_link_transfers_per_second Value of maximum link's transfers per second (T/s)
|
|
||||||
# TYPE node_pcidevice_max_link_transfers_per_second gauge
|
|
||||||
node_pcidevice_max_link_transfers_per_second{bus="00",device="02",function="1",segment="0000"} 8e+09
|
|
||||||
node_pcidevice_max_link_transfers_per_second{bus="01",device="00",function="0",segment="0000"} 1.6e+10
|
|
||||||
# HELP node_pcidevice_max_link_width Value of maximum link's width (number of lanes)
|
|
||||||
# TYPE node_pcidevice_max_link_width gauge
|
|
||||||
node_pcidevice_max_link_width{bus="00",device="02",function="1",segment="0000"} 8
|
|
||||||
node_pcidevice_max_link_width{bus="01",device="00",function="0",segment="0000"} 4
|
|
||||||
# HELP node_power_supply_capacity capacity value of /sys/class/power_supply/<power_supply>.
|
# HELP node_power_supply_capacity capacity value of /sys/class/power_supply/<power_supply>.
|
||||||
# TYPE node_power_supply_capacity gauge
|
# TYPE node_power_supply_capacity gauge
|
||||||
node_power_supply_capacity{power_supply="BAT0"} 81
|
node_power_supply_capacity{power_supply="BAT0"} 81
|
||||||
|
@ -3033,7 +2997,6 @@ node_scrape_collector_success{collector="nfs"} 1
|
||||||
node_scrape_collector_success{collector="nfsd"} 1
|
node_scrape_collector_success{collector="nfsd"} 1
|
||||||
node_scrape_collector_success{collector="nvme"} 1
|
node_scrape_collector_success{collector="nvme"} 1
|
||||||
node_scrape_collector_success{collector="os"} 1
|
node_scrape_collector_success{collector="os"} 1
|
||||||
node_scrape_collector_success{collector="pcidevice"} 1
|
|
||||||
node_scrape_collector_success{collector="powersupplyclass"} 1
|
node_scrape_collector_success{collector="powersupplyclass"} 1
|
||||||
node_scrape_collector_success{collector="pressure"} 1
|
node_scrape_collector_success{collector="pressure"} 1
|
||||||
node_scrape_collector_success{collector="processes"} 1
|
node_scrape_collector_success{collector="processes"} 1
|
||||||
|
|
|
@ -4,7 +4,6 @@ NIC statistics:
|
||||||
rx_packets: 1260062
|
rx_packets: 1260062
|
||||||
tx_errors: 0
|
tx_errors: 0
|
||||||
rx_errors: 0
|
rx_errors: 0
|
||||||
port.rx_dropped: 12028
|
|
||||||
rx_missed: 401
|
rx_missed: 401
|
||||||
align_errors: 0
|
align_errors: 0
|
||||||
tx_single_collisions: 0
|
tx_single_collisions: 0
|
||||||
|
|
|
@ -2,4 +2,4 @@ net 70 70 69 45
|
||||||
rpc 1218785755 374636 1218815394
|
rpc 1218785755 374636 1218815394
|
||||||
proc2 18 16 57 74 52 71 73 45 86 0 52 83 61 17 53 50 23 70 82
|
proc2 18 16 57 74 52 71 73 45 86 0 52 83 61 17 53 50 23 70 82
|
||||||
proc3 22 0 1061909262 48906 4077635 117661341 5 29391916 2570425 2993289 590 0 0 7815 15 1130 0 3983 92385 13332 2 1 23729
|
proc3 22 0 1061909262 48906 4077635 117661341 5 29391916 2570425 2993289 590 0 0 7815 15 1130 0 3983 92385 13332 2 1 23729
|
||||||
proc4 48 98 51 54 83 85 23 24 1 28 73 68 83 12 84 39 68 59 58 88 29 74 69 96 21 84 15 53 86 54 66 56 97 36 49 32 85 81 11 58 32 67 13 28 35 1 90 26 0
|
proc4 48 98 51 54 83 85 23 24 1 28 73 68 83 12 84 39 68 59 58 88 29 74 69 96 21 84 15 53 86 54 66 56 97 36 49 32 85 81 11 58 32 67 13 28 35 90 1 26 0
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,8 +21,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/prometheus/node_exporter/collector/utils"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
@ -51,7 +49,7 @@ func intr(idx _C_int) (itr interrupt, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dev := *(*[128]byte)(unsafe.Pointer(&buf[0]))
|
dev := *(*[128]byte)(unsafe.Pointer(&buf[0]))
|
||||||
itr.device = utils.SafeBytesToString(dev[:])
|
itr.device = string(dev[:])
|
||||||
|
|
||||||
mib[2] = KERN_INTRCNT_VECTOR
|
mib[2] = KERN_INTRCNT_VECTOR
|
||||||
buf, err = sysctl(mib[:])
|
buf, err = sysctl(mib[:])
|
||||||
|
|
|
@ -22,8 +22,6 @@ import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/prometheus/procfs/sysfs"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/procfs"
|
"github.com/prometheus/procfs"
|
||||||
)
|
)
|
||||||
|
@ -100,30 +98,17 @@ var (
|
||||||
[]string{"device"},
|
[]string{"device"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
mdraidDisks = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, "md", "raid_disks"),
|
|
||||||
"Number of raid disks on device.",
|
|
||||||
[]string{"device"},
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
|
|
||||||
mdraidDegradedDisksDesc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, "md", "degraded"),
|
|
||||||
"Number of degraded disks on device.",
|
|
||||||
[]string{"device"},
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
procFS, err := procfs.NewFS(*procPath)
|
fs, err := procfs.NewFS(*procPath)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open procfs: %w", err)
|
return fmt.Errorf("failed to open procfs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mdStats, err := procFS.MDStat()
|
mdStats, err := fs.MDStat()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
c.logger.Debug("Not collecting mdstat, file does not exist", "file", *procPath)
|
c.logger.Debug("Not collecting mdstat, file does not exist", "file", *procPath)
|
||||||
|
@ -216,34 +201,5 @@ func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
sysFS, err := sysfs.NewFS(*sysPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to open sysfs: %w", err)
|
|
||||||
}
|
|
||||||
mdraids, err := sysFS.Mdraids()
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
|
||||||
c.logger.Debug("Not collecting mdraids, file does not exist", "file", *sysPath)
|
|
||||||
return ErrNoData
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("error parsing mdraids: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, mdraid := range mdraids {
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
mdraidDisks,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
float64(mdraid.Disks),
|
|
||||||
mdraid.Device,
|
|
||||||
)
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
mdraidDegradedDisksDesc,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
float64(mdraid.DegradedDisks),
|
|
||||||
mdraid.Device,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,294 +0,0 @@
|
||||||
// Copyright 2024 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.
|
|
||||||
|
|
||||||
//go:build !nomdadm
|
|
||||||
// +build !nomdadm
|
|
||||||
|
|
||||||
package collector
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
"github.com/prometheus/client_golang/prometheus/testutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
type testMdadmCollector struct {
|
|
||||||
mc Collector
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c testMdadmCollector) Collect(ch chan<- prometheus.Metric) {
|
|
||||||
c.mc.Update(ch)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c testMdadmCollector) Describe(ch chan<- *prometheus.Desc) {
|
|
||||||
prometheus.DescribeByCollect(c, ch)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTestMdadmCollector(logger *slog.Logger) (prometheus.Collector, error) {
|
|
||||||
mc, err := NewMdadmCollector(logger)
|
|
||||||
if err != nil {
|
|
||||||
return testMdadmCollector{}, err
|
|
||||||
}
|
|
||||||
return &testMdadmCollector{mc}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMdadmStats(t *testing.T) {
|
|
||||||
*sysPath = "fixtures/sys"
|
|
||||||
*procPath = "fixtures/proc"
|
|
||||||
testcase := `# HELP node_md_blocks Total number of blocks on device.
|
|
||||||
# TYPE node_md_blocks gauge
|
|
||||||
node_md_blocks{device="md0"} 248896
|
|
||||||
node_md_blocks{device="md00"} 4.186624e+06
|
|
||||||
node_md_blocks{device="md10"} 3.14159265e+08
|
|
||||||
node_md_blocks{device="md101"} 322560
|
|
||||||
node_md_blocks{device="md11"} 4.190208e+06
|
|
||||||
node_md_blocks{device="md12"} 3.886394368e+09
|
|
||||||
node_md_blocks{device="md120"} 2.095104e+06
|
|
||||||
node_md_blocks{device="md126"} 1.855870976e+09
|
|
||||||
node_md_blocks{device="md127"} 3.12319552e+08
|
|
||||||
node_md_blocks{device="md201"} 1.993728e+06
|
|
||||||
node_md_blocks{device="md219"} 7932
|
|
||||||
node_md_blocks{device="md3"} 5.853468288e+09
|
|
||||||
node_md_blocks{device="md4"} 4.883648e+06
|
|
||||||
node_md_blocks{device="md6"} 1.95310144e+08
|
|
||||||
node_md_blocks{device="md7"} 7.813735424e+09
|
|
||||||
node_md_blocks{device="md8"} 1.95310144e+08
|
|
||||||
node_md_blocks{device="md9"} 523968
|
|
||||||
# HELP node_md_blocks_synced Number of blocks synced on device.
|
|
||||||
# TYPE node_md_blocks_synced gauge
|
|
||||||
node_md_blocks_synced{device="md0"} 248896
|
|
||||||
node_md_blocks_synced{device="md00"} 4.186624e+06
|
|
||||||
node_md_blocks_synced{device="md10"} 3.14159265e+08
|
|
||||||
node_md_blocks_synced{device="md101"} 322560
|
|
||||||
node_md_blocks_synced{device="md11"} 0
|
|
||||||
node_md_blocks_synced{device="md12"} 3.886394368e+09
|
|
||||||
node_md_blocks_synced{device="md120"} 2.095104e+06
|
|
||||||
node_md_blocks_synced{device="md126"} 1.855870976e+09
|
|
||||||
node_md_blocks_synced{device="md127"} 3.12319552e+08
|
|
||||||
node_md_blocks_synced{device="md201"} 114176
|
|
||||||
node_md_blocks_synced{device="md219"} 7932
|
|
||||||
node_md_blocks_synced{device="md3"} 5.853468288e+09
|
|
||||||
node_md_blocks_synced{device="md4"} 4.883648e+06
|
|
||||||
node_md_blocks_synced{device="md6"} 1.6775552e+07
|
|
||||||
node_md_blocks_synced{device="md7"} 7.813735424e+09
|
|
||||||
node_md_blocks_synced{device="md8"} 1.6775552e+07
|
|
||||||
node_md_blocks_synced{device="md9"} 0
|
|
||||||
# HELP node_md_degraded Number of degraded disks on device.
|
|
||||||
# TYPE node_md_degraded gauge
|
|
||||||
node_md_degraded{device="md0"} 0
|
|
||||||
node_md_degraded{device="md1"} 0
|
|
||||||
node_md_degraded{device="md10"} 0
|
|
||||||
node_md_degraded{device="md4"} 0
|
|
||||||
node_md_degraded{device="md5"} 1
|
|
||||||
node_md_degraded{device="md6"} 1
|
|
||||||
# HELP node_md_disks Number of active/failed/spare disks of device.
|
|
||||||
# TYPE node_md_disks gauge
|
|
||||||
node_md_disks{device="md0",state="active"} 2
|
|
||||||
node_md_disks{device="md0",state="failed"} 0
|
|
||||||
node_md_disks{device="md0",state="spare"} 0
|
|
||||||
node_md_disks{device="md00",state="active"} 1
|
|
||||||
node_md_disks{device="md00",state="failed"} 0
|
|
||||||
node_md_disks{device="md00",state="spare"} 0
|
|
||||||
node_md_disks{device="md10",state="active"} 2
|
|
||||||
node_md_disks{device="md10",state="failed"} 0
|
|
||||||
node_md_disks{device="md10",state="spare"} 0
|
|
||||||
node_md_disks{device="md101",state="active"} 3
|
|
||||||
node_md_disks{device="md101",state="failed"} 0
|
|
||||||
node_md_disks{device="md101",state="spare"} 0
|
|
||||||
node_md_disks{device="md11",state="active"} 2
|
|
||||||
node_md_disks{device="md11",state="failed"} 1
|
|
||||||
node_md_disks{device="md11",state="spare"} 2
|
|
||||||
node_md_disks{device="md12",state="active"} 2
|
|
||||||
node_md_disks{device="md12",state="failed"} 0
|
|
||||||
node_md_disks{device="md12",state="spare"} 0
|
|
||||||
node_md_disks{device="md120",state="active"} 2
|
|
||||||
node_md_disks{device="md120",state="failed"} 0
|
|
||||||
node_md_disks{device="md120",state="spare"} 0
|
|
||||||
node_md_disks{device="md126",state="active"} 2
|
|
||||||
node_md_disks{device="md126",state="failed"} 0
|
|
||||||
node_md_disks{device="md126",state="spare"} 0
|
|
||||||
node_md_disks{device="md127",state="active"} 2
|
|
||||||
node_md_disks{device="md127",state="failed"} 0
|
|
||||||
node_md_disks{device="md127",state="spare"} 0
|
|
||||||
node_md_disks{device="md201",state="active"} 2
|
|
||||||
node_md_disks{device="md201",state="failed"} 0
|
|
||||||
node_md_disks{device="md201",state="spare"} 0
|
|
||||||
node_md_disks{device="md219",state="active"} 0
|
|
||||||
node_md_disks{device="md219",state="failed"} 0
|
|
||||||
node_md_disks{device="md219",state="spare"} 3
|
|
||||||
node_md_disks{device="md3",state="active"} 8
|
|
||||||
node_md_disks{device="md3",state="failed"} 0
|
|
||||||
node_md_disks{device="md3",state="spare"} 2
|
|
||||||
node_md_disks{device="md4",state="active"} 0
|
|
||||||
node_md_disks{device="md4",state="failed"} 1
|
|
||||||
node_md_disks{device="md4",state="spare"} 1
|
|
||||||
node_md_disks{device="md6",state="active"} 1
|
|
||||||
node_md_disks{device="md6",state="failed"} 1
|
|
||||||
node_md_disks{device="md6",state="spare"} 1
|
|
||||||
node_md_disks{device="md7",state="active"} 3
|
|
||||||
node_md_disks{device="md7",state="failed"} 1
|
|
||||||
node_md_disks{device="md7",state="spare"} 0
|
|
||||||
node_md_disks{device="md8",state="active"} 2
|
|
||||||
node_md_disks{device="md8",state="failed"} 0
|
|
||||||
node_md_disks{device="md8",state="spare"} 2
|
|
||||||
node_md_disks{device="md9",state="active"} 4
|
|
||||||
node_md_disks{device="md9",state="failed"} 2
|
|
||||||
node_md_disks{device="md9",state="spare"} 1
|
|
||||||
# HELP node_md_disks_required Total number of disks of device.
|
|
||||||
# TYPE node_md_disks_required gauge
|
|
||||||
node_md_disks_required{device="md0"} 2
|
|
||||||
node_md_disks_required{device="md00"} 1
|
|
||||||
node_md_disks_required{device="md10"} 2
|
|
||||||
node_md_disks_required{device="md101"} 3
|
|
||||||
node_md_disks_required{device="md11"} 2
|
|
||||||
node_md_disks_required{device="md12"} 2
|
|
||||||
node_md_disks_required{device="md120"} 2
|
|
||||||
node_md_disks_required{device="md126"} 2
|
|
||||||
node_md_disks_required{device="md127"} 2
|
|
||||||
node_md_disks_required{device="md201"} 2
|
|
||||||
node_md_disks_required{device="md219"} 0
|
|
||||||
node_md_disks_required{device="md3"} 8
|
|
||||||
node_md_disks_required{device="md4"} 0
|
|
||||||
node_md_disks_required{device="md6"} 2
|
|
||||||
node_md_disks_required{device="md7"} 4
|
|
||||||
node_md_disks_required{device="md8"} 2
|
|
||||||
node_md_disks_required{device="md9"} 4
|
|
||||||
# HELP node_md_raid_disks Number of raid disks on device.
|
|
||||||
# TYPE node_md_raid_disks gauge
|
|
||||||
node_md_raid_disks{device="md0"} 2
|
|
||||||
node_md_raid_disks{device="md1"} 2
|
|
||||||
node_md_raid_disks{device="md10"} 4
|
|
||||||
node_md_raid_disks{device="md4"} 3
|
|
||||||
node_md_raid_disks{device="md5"} 3
|
|
||||||
node_md_raid_disks{device="md6"} 4
|
|
||||||
# HELP node_md_state Indicates the state of md-device.
|
|
||||||
# TYPE node_md_state gauge
|
|
||||||
node_md_state{device="md0",state="active"} 1
|
|
||||||
node_md_state{device="md0",state="check"} 0
|
|
||||||
node_md_state{device="md0",state="inactive"} 0
|
|
||||||
node_md_state{device="md0",state="recovering"} 0
|
|
||||||
node_md_state{device="md0",state="resync"} 0
|
|
||||||
node_md_state{device="md00",state="active"} 1
|
|
||||||
node_md_state{device="md00",state="check"} 0
|
|
||||||
node_md_state{device="md00",state="inactive"} 0
|
|
||||||
node_md_state{device="md00",state="recovering"} 0
|
|
||||||
node_md_state{device="md00",state="resync"} 0
|
|
||||||
node_md_state{device="md10",state="active"} 1
|
|
||||||
node_md_state{device="md10",state="check"} 0
|
|
||||||
node_md_state{device="md10",state="inactive"} 0
|
|
||||||
node_md_state{device="md10",state="recovering"} 0
|
|
||||||
node_md_state{device="md10",state="resync"} 0
|
|
||||||
node_md_state{device="md101",state="active"} 1
|
|
||||||
node_md_state{device="md101",state="check"} 0
|
|
||||||
node_md_state{device="md101",state="inactive"} 0
|
|
||||||
node_md_state{device="md101",state="recovering"} 0
|
|
||||||
node_md_state{device="md101",state="resync"} 0
|
|
||||||
node_md_state{device="md11",state="active"} 0
|
|
||||||
node_md_state{device="md11",state="check"} 0
|
|
||||||
node_md_state{device="md11",state="inactive"} 0
|
|
||||||
node_md_state{device="md11",state="recovering"} 0
|
|
||||||
node_md_state{device="md11",state="resync"} 1
|
|
||||||
node_md_state{device="md12",state="active"} 1
|
|
||||||
node_md_state{device="md12",state="check"} 0
|
|
||||||
node_md_state{device="md12",state="inactive"} 0
|
|
||||||
node_md_state{device="md12",state="recovering"} 0
|
|
||||||
node_md_state{device="md12",state="resync"} 0
|
|
||||||
node_md_state{device="md120",state="active"} 1
|
|
||||||
node_md_state{device="md120",state="check"} 0
|
|
||||||
node_md_state{device="md120",state="inactive"} 0
|
|
||||||
node_md_state{device="md120",state="recovering"} 0
|
|
||||||
node_md_state{device="md120",state="resync"} 0
|
|
||||||
node_md_state{device="md126",state="active"} 1
|
|
||||||
node_md_state{device="md126",state="check"} 0
|
|
||||||
node_md_state{device="md126",state="inactive"} 0
|
|
||||||
node_md_state{device="md126",state="recovering"} 0
|
|
||||||
node_md_state{device="md126",state="resync"} 0
|
|
||||||
node_md_state{device="md127",state="active"} 1
|
|
||||||
node_md_state{device="md127",state="check"} 0
|
|
||||||
node_md_state{device="md127",state="inactive"} 0
|
|
||||||
node_md_state{device="md127",state="recovering"} 0
|
|
||||||
node_md_state{device="md127",state="resync"} 0
|
|
||||||
node_md_state{device="md201",state="active"} 0
|
|
||||||
node_md_state{device="md201",state="check"} 1
|
|
||||||
node_md_state{device="md201",state="inactive"} 0
|
|
||||||
node_md_state{device="md201",state="recovering"} 0
|
|
||||||
node_md_state{device="md201",state="resync"} 0
|
|
||||||
node_md_state{device="md219",state="active"} 0
|
|
||||||
node_md_state{device="md219",state="check"} 0
|
|
||||||
node_md_state{device="md219",state="inactive"} 1
|
|
||||||
node_md_state{device="md219",state="recovering"} 0
|
|
||||||
node_md_state{device="md219",state="resync"} 0
|
|
||||||
node_md_state{device="md3",state="active"} 1
|
|
||||||
node_md_state{device="md3",state="check"} 0
|
|
||||||
node_md_state{device="md3",state="inactive"} 0
|
|
||||||
node_md_state{device="md3",state="recovering"} 0
|
|
||||||
node_md_state{device="md3",state="resync"} 0
|
|
||||||
node_md_state{device="md4",state="active"} 0
|
|
||||||
node_md_state{device="md4",state="check"} 0
|
|
||||||
node_md_state{device="md4",state="inactive"} 1
|
|
||||||
node_md_state{device="md4",state="recovering"} 0
|
|
||||||
node_md_state{device="md4",state="resync"} 0
|
|
||||||
node_md_state{device="md6",state="active"} 0
|
|
||||||
node_md_state{device="md6",state="check"} 0
|
|
||||||
node_md_state{device="md6",state="inactive"} 0
|
|
||||||
node_md_state{device="md6",state="recovering"} 1
|
|
||||||
node_md_state{device="md6",state="resync"} 0
|
|
||||||
node_md_state{device="md7",state="active"} 1
|
|
||||||
node_md_state{device="md7",state="check"} 0
|
|
||||||
node_md_state{device="md7",state="inactive"} 0
|
|
||||||
node_md_state{device="md7",state="recovering"} 0
|
|
||||||
node_md_state{device="md7",state="resync"} 0
|
|
||||||
node_md_state{device="md8",state="active"} 0
|
|
||||||
node_md_state{device="md8",state="check"} 0
|
|
||||||
node_md_state{device="md8",state="inactive"} 0
|
|
||||||
node_md_state{device="md8",state="recovering"} 0
|
|
||||||
node_md_state{device="md8",state="resync"} 1
|
|
||||||
node_md_state{device="md9",state="active"} 0
|
|
||||||
node_md_state{device="md9",state="check"} 0
|
|
||||||
node_md_state{device="md9",state="inactive"} 0
|
|
||||||
node_md_state{device="md9",state="recovering"} 0
|
|
||||||
node_md_state{device="md9",state="resync"} 1
|
|
||||||
`
|
|
||||||
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
|
|
||||||
Level: slog.LevelError,
|
|
||||||
AddSource: true,
|
|
||||||
}))
|
|
||||||
collector, err := NewMdadmCollector(logger)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
c, err := NewTestMdadmCollector(logger)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
reg := prometheus.NewRegistry()
|
|
||||||
reg.MustRegister(c)
|
|
||||||
|
|
||||||
sink := make(chan prometheus.Metric)
|
|
||||||
go func() {
|
|
||||||
err := collector.Update(sink)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
close(sink)
|
|
||||||
}()
|
|
||||||
|
|
||||||
err = testutil.GatherAndCompare(reg, strings.NewReader(testcase))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -40,12 +40,8 @@ func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return map[string]float64{
|
return map[string]float64{
|
||||||
"total_bytes": float64(stats.RealTotal * 4096),
|
"total_bytes": float64(stats.RealTotal * 4096),
|
||||||
"free_bytes": float64(stats.RealFree * 4096),
|
"free_bytes": float64(stats.RealFree * 4096),
|
||||||
"available_bytes": float64(stats.RealAvailable * 4096),
|
"available_bytes": float64(stats.RealAvailable * 4096),
|
||||||
"process_bytes": float64(stats.RealProcess * 4096),
|
|
||||||
"paging_space_total_bytes": float64(stats.PgSpTotal * 4096),
|
|
||||||
"paging_space_free_bytes": float64(stats.PgSpFree * 4096),
|
|
||||||
"page_scans_total": float64(stats.Scans),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ func NewMeminfoCollector(logger *slog.Logger) (Collector, error) {
|
||||||
func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
|
func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
|
||||||
meminfo, err := c.fs.Meminfo()
|
meminfo, err := c.fs.Meminfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get memory info: %w", err)
|
return nil, fmt.Errorf("Failed to get memory info: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics := make(map[string]float64)
|
metrics := make(map[string]float64)
|
||||||
|
|
|
@ -32,20 +32,16 @@ func getNetDevStats(filter *deviceFilter, logger *slog.Logger) (netDevStats, err
|
||||||
|
|
||||||
for _, stat := range stats {
|
for _, stat := range stats {
|
||||||
netDev[stat.Name] = map[string]uint64{
|
netDev[stat.Name] = map[string]uint64{
|
||||||
"receive_bytes": uint64(stat.RxBytes),
|
"receive_packets": uint64(stat.RxPackets),
|
||||||
"receive_dropped": uint64(stat.RxPacketsDropped),
|
"transmit_packets": uint64(stat.TxPackets),
|
||||||
"receive_errors": uint64(stat.RxErrors),
|
"receive_bytes": uint64(stat.RxBytes),
|
||||||
"receive_multicast": uint64(stat.RxMulticastPackets),
|
"transmit_bytes": uint64(stat.TxBytes),
|
||||||
"receive_packets": uint64(stat.RxPackets),
|
"receive_errors": uint64(stat.RxErrors),
|
||||||
"receive_collision_errors": uint64(stat.RxCollisionErrors),
|
"transmit_errors": uint64(stat.TxErrors),
|
||||||
"transmit_bytes": uint64(stat.TxBytes),
|
"receive_dropped": uint64(stat.RxPacketsDropped),
|
||||||
"transmit_dropped": uint64(stat.TxPacketsDropped),
|
"transmit_dropped": uint64(stat.TxPacketsDropped),
|
||||||
"transmit_errors": uint64(stat.TxErrors),
|
"receive_multicast": uint64(stat.RxMulticastPackets),
|
||||||
"transmit_multicast": uint64(stat.TxMulticastPackets),
|
"transmit_multicast": uint64(stat.TxMulticastPackets),
|
||||||
"transmit_packets": uint64(stat.TxPackets),
|
|
||||||
"transmit_queue_overflow": uint64(stat.TxQueueOverflow),
|
|
||||||
"transmit_collision_single_errors": uint64(stat.TxSingleCollisionCount),
|
|
||||||
"transmit_collision_multiple_errors": uint64(stat.TxMultipleCollisionCount),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
@ -72,107 +71,51 @@ func getIfaceData(index int) (*ifMsghdr2, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = binary.Read(bytes.NewReader(rawData), binary.LittleEndian, &data)
|
err = binary.Read(bytes.NewReader(rawData), binary.LittleEndian, &data)
|
||||||
if err != nil {
|
|
||||||
return &data, err
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
As of macOS Ventura 13.2.1, there’s a kernel bug which truncates traffic values at the 4GiB mark.
|
|
||||||
This is a workaround to fetch the interface traffic metrics using a sysctl call.
|
|
||||||
Apple wants to prevent fingerprinting by 3rdparty apps and might fix this bug in future which would break this implementation.
|
|
||||||
*/
|
|
||||||
mib := []int32{
|
|
||||||
unix.CTL_NET,
|
|
||||||
unix.AF_LINK,
|
|
||||||
0, // NETLINK_GENERIC: functions not specific to a type of iface
|
|
||||||
2, //IFMIB_IFDATA: per-interface data table
|
|
||||||
int32(index),
|
|
||||||
1, // IFDATA_GENERAL: generic stats for all kinds of ifaces
|
|
||||||
}
|
|
||||||
|
|
||||||
var mibData ifMibData
|
|
||||||
size := unsafe.Sizeof(mibData)
|
|
||||||
|
|
||||||
if _, _, errno := unix.Syscall6(
|
|
||||||
unix.SYS___SYSCTL,
|
|
||||||
uintptr(unsafe.Pointer(&mib[0])),
|
|
||||||
uintptr(len(mib)),
|
|
||||||
uintptr(unsafe.Pointer(&mibData)),
|
|
||||||
uintptr(unsafe.Pointer(&size)),
|
|
||||||
uintptr(unsafe.Pointer(nil)),
|
|
||||||
0,
|
|
||||||
); errno != 0 {
|
|
||||||
return &data, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var ifdata ifData64
|
|
||||||
err = binary.Read(bytes.NewReader(mibData.Data[:]), binary.LittleEndian, &ifdata)
|
|
||||||
if err != nil {
|
|
||||||
return &data, err
|
|
||||||
}
|
|
||||||
|
|
||||||
data.Data.Ibytes = ifdata.Ibytes
|
|
||||||
data.Data.Obytes = ifdata.Obytes
|
|
||||||
return &data, err
|
return &data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/apple-oss-distributions/xnu/blob/main/bsd/net/if.h#L220-L232
|
|
||||||
type ifMsghdr2 struct {
|
type ifMsghdr2 struct {
|
||||||
Msglen uint16 // to skip over non-understood messages
|
Msglen uint16
|
||||||
Version uint8 // future binary compatabilit
|
Version uint8
|
||||||
Type uint8 // message type
|
Type uint8
|
||||||
Addrs int32 // like rtm_addrs
|
Addrs int32
|
||||||
Flags int32 // value of if_flags
|
Flags int32
|
||||||
Index uint16 // index for associated ifp
|
Index uint16
|
||||||
_ [2]byte // padding for alignment
|
_ [2]byte
|
||||||
SndLen int32 // instantaneous length of send queue
|
SndLen int32
|
||||||
SndMaxlen int32 // maximum length of send queue
|
SndMaxlen int32
|
||||||
SndDrops int32 // number of drops in send queue
|
SndDrops int32
|
||||||
Timer int32 // time until if_watchdog called
|
Timer int32
|
||||||
Data ifData64 // statistics and other data
|
Data ifData64
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/apple-oss-distributions/xnu/blob/main/bsd/net/if_var.h#L207-L235
|
// https://github.com/apple/darwin-xnu/blob/main/bsd/net/if_var.h#L199-L231
|
||||||
type ifData64 struct {
|
type ifData64 struct {
|
||||||
Type uint8 // ethernet, tokenring, etc
|
Type uint8
|
||||||
Typelen uint8 // Length of frame type id
|
Typelen uint8
|
||||||
Physical uint8 // e.g., AUI, Thinnet, 10base-T, etc
|
Physical uint8
|
||||||
Addrlen uint8 // media address length
|
Addrlen uint8
|
||||||
Hdrlen uint8 // media header length
|
Hdrlen uint8
|
||||||
Recvquota uint8 // polling quota for receive intrs
|
Recvquota uint8
|
||||||
Xmitquota uint8 // polling quota for xmit intrs
|
Xmitquota uint8
|
||||||
Unused1 uint8 // for future use
|
Unused1 uint8
|
||||||
Mtu uint32 // maximum transmission unit
|
Mtu uint32
|
||||||
Metric uint32 // routing metric (external only)
|
Metric uint32
|
||||||
Baudrate uint64 // linespeed
|
Baudrate uint64
|
||||||
|
Ipackets uint64
|
||||||
// volatile statistics
|
Ierrors uint64
|
||||||
Ipackets uint64 // packets received on interface
|
Opackets uint64
|
||||||
Ierrors uint64 // input errors on interface
|
Oerrors uint64
|
||||||
Opackets uint64 // packets sent on interface
|
Collisions uint64
|
||||||
Oerrors uint64 // output errors on interface
|
Ibytes uint64
|
||||||
Collisions uint64 // collisions on csma interfaces
|
Obytes uint64
|
||||||
Ibytes uint64 // total number of octets received
|
Imcasts uint64
|
||||||
Obytes uint64 // total number of octets sent
|
Omcasts uint64
|
||||||
Imcasts uint64 // packets received via multicast
|
Iqdrops uint64
|
||||||
Omcasts uint64 // packets sent via multicast
|
Noproto uint64
|
||||||
Iqdrops uint64 // dropped on input, this interface
|
Recvtiming uint32
|
||||||
Noproto uint64 // destined for unsupported protocol
|
Xmittiming uint32
|
||||||
Recvtiming uint32 // usec spent receiving when timing
|
Lastchange unix.Timeval32
|
||||||
Xmittiming uint32 // usec spent xmitting when timing
|
|
||||||
Lastchange unix.Timeval32 // time of last administrative change
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/apple-oss-distributions/xnu/blob/main/bsd/net/if_mib.h#L65-L74
|
|
||||||
type ifMibData struct {
|
|
||||||
Name [16]byte // name of interface
|
|
||||||
PCount uint32 // number of promiscuous listeners
|
|
||||||
Flags uint32 // interface flags
|
|
||||||
SendLength uint32 // instantaneous length of send queue
|
|
||||||
MaxSendLength uint32 // maximum length of send queue
|
|
||||||
SendDrops uint32 // number of drops in send queue
|
|
||||||
_ [4]uint32 // for future expansion
|
|
||||||
Data [128]byte // generic information and statistics
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNetDevLabels() (map[string]map[string]string, error) {
|
func getNetDevLabels() (map[string]map[string]string, error) {
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
// Copyright 2025 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.
|
|
||||||
|
|
||||||
//go:build !nonetinterface
|
|
||||||
// +build !nonetinterface
|
|
||||||
|
|
||||||
package collector
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log/slog"
|
|
||||||
|
|
||||||
"github.com/power-devops/perfstat"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
|
||||||
|
|
||||||
type netinterfaceCollector struct {
|
|
||||||
logger *slog.Logger
|
|
||||||
collisions *prometheus.Desc
|
|
||||||
ibytes *prometheus.Desc
|
|
||||||
ipackets *prometheus.Desc
|
|
||||||
obytes *prometheus.Desc
|
|
||||||
opackets *prometheus.Desc
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
netinterfaceSubsystem = "netinterface"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
registerCollector("netinterface", defaultEnabled, NewNetinterfaceCollector)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNetinterfaceCollector(logger *slog.Logger) (Collector, error) {
|
|
||||||
labels := []string{"interface"}
|
|
||||||
return &netinterfaceCollector{
|
|
||||||
logger: logger,
|
|
||||||
collisions: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, netinterfaceSubsystem, "collisions_total"),
|
|
||||||
"Total number of CSMA collisions on the interface.", labels, nil,
|
|
||||||
),
|
|
||||||
ibytes: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, netinterfaceSubsystem, "receive_bytes_total"),
|
|
||||||
"Total number of bytes received on the interface.", labels, nil,
|
|
||||||
),
|
|
||||||
ipackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, netinterfaceSubsystem, "receive_packets_total"),
|
|
||||||
"Total number of packets received on the interface.", labels, nil,
|
|
||||||
),
|
|
||||||
obytes: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, netinterfaceSubsystem, "transmit_bytes_total"),
|
|
||||||
"Total number of bytes transmitted on the interface.", labels, nil,
|
|
||||||
),
|
|
||||||
opackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, netinterfaceSubsystem, "transmit_packets_total"),
|
|
||||||
"Total number of packets transmitted on the interface.", labels, nil,
|
|
||||||
),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *netinterfaceCollector) Update(ch chan<- prometheus.Metric) error {
|
|
||||||
stats, err := perfstat.NetIfaceStat()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, stat := range stats {
|
|
||||||
iface := stat.Name
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.collisions, prometheus.CounterValue, float64(stat.Collisions), iface)
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.ibytes, prometheus.CounterValue, float64(stat.IBytes), iface)
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.ipackets, prometheus.CounterValue, float64(stat.IPackets), iface)
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.obytes, prometheus.CounterValue, float64(stat.OBytes), iface)
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.opackets, prometheus.CounterValue, float64(stat.OPackets), iface)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
// Copyright 2025 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.
|
|
||||||
|
|
||||||
//go:build !nopartition
|
|
||||||
// +build !nopartition
|
|
||||||
|
|
||||||
package collector
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log/slog"
|
|
||||||
|
|
||||||
"github.com/power-devops/perfstat"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
|
||||||
|
|
||||||
type partitionCollector struct {
|
|
||||||
logger *slog.Logger
|
|
||||||
entitledCapacity *prometheus.Desc
|
|
||||||
memoryMax *prometheus.Desc
|
|
||||||
memoryOnline *prometheus.Desc
|
|
||||||
cpuOnline *prometheus.Desc
|
|
||||||
cpuSys *prometheus.Desc
|
|
||||||
cpuPool *prometheus.Desc
|
|
||||||
powerSaveMode *prometheus.Desc
|
|
||||||
smtThreads *prometheus.Desc
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
partitionCollectorSubsystem = "partition"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
registerCollector("partition", defaultEnabled, NewPartitionCollector)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPartitionCollector(logger *slog.Logger) (Collector, error) {
|
|
||||||
return &partitionCollector{
|
|
||||||
logger: logger,
|
|
||||||
entitledCapacity: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, partitionCollectorSubsystem, "entitled_capacity"),
|
|
||||||
"Entitled processor capacity of the partition in CPU units (e.g. 1.0 = one core).",
|
|
||||||
nil, nil,
|
|
||||||
),
|
|
||||||
memoryMax: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, partitionCollectorSubsystem, "memory_max"),
|
|
||||||
"Maximum memory of the partition in bytes.",
|
|
||||||
nil, nil,
|
|
||||||
),
|
|
||||||
memoryOnline: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, partitionCollectorSubsystem, "memory_online"),
|
|
||||||
"Online memory of the partition in bytes.",
|
|
||||||
nil, nil,
|
|
||||||
),
|
|
||||||
cpuOnline: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, partitionCollectorSubsystem, "cpus_online"),
|
|
||||||
"Number of online CPUs in the partition.",
|
|
||||||
nil, nil,
|
|
||||||
),
|
|
||||||
cpuSys: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, partitionCollectorSubsystem, "cpus_sys"),
|
|
||||||
"Number of physical CPUs in the system.",
|
|
||||||
nil, nil,
|
|
||||||
),
|
|
||||||
cpuPool: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, partitionCollectorSubsystem, "cpus_pool"),
|
|
||||||
"Number of physical CPUs in the pool.",
|
|
||||||
nil, nil,
|
|
||||||
),
|
|
||||||
powerSaveMode: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, partitionCollectorSubsystem, "power_save_mode"),
|
|
||||||
"Power save mode of the partition (1 for enabled, 0 for disabled).",
|
|
||||||
nil, nil,
|
|
||||||
),
|
|
||||||
smtThreads: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, partitionCollectorSubsystem, "smt_threads"),
|
|
||||||
"Number of SMT threads per core.",
|
|
||||||
nil, nil,
|
|
||||||
),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *partitionCollector) Update(ch chan<- prometheus.Metric) error {
|
|
||||||
stats, err := perfstat.PartitionStat()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
powerSaveMode := 0.0
|
|
||||||
if stats.Conf.PowerSave {
|
|
||||||
powerSaveMode = 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.entitledCapacity, prometheus.GaugeValue, float64(stats.EntCapacity)/100.0)
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.memoryMax, prometheus.GaugeValue, float64(stats.Mem.Max)*1024*1024)
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.memoryOnline, prometheus.GaugeValue, float64(stats.Mem.Online)*1024*1024)
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.cpuOnline, prometheus.GaugeValue, float64(stats.VCpus.Online))
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.cpuSys, prometheus.GaugeValue, float64(stats.NumProcessors.Online))
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.cpuPool, prometheus.GaugeValue, float64(stats.ActiveCpusInPool))
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.powerSaveMode, prometheus.GaugeValue, powerSaveMode)
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.smtThreads, prometheus.GaugeValue, float64(stats.SmtThreads))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,143 +0,0 @@
|
||||||
// Copyright 2017-2019 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.
|
|
||||||
|
|
||||||
//go:build !nopcidevice
|
|
||||||
// +build !nopcidevice
|
|
||||||
|
|
||||||
package collector
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
"github.com/prometheus/procfs/sysfs"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
pcideviceSubsystem = "pcidevice"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
pcideviceLabelNames = []string{"segment", "bus", "device", "function"}
|
|
||||||
|
|
||||||
pcideviceMaxLinkTSDesc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, pcideviceSubsystem, "max_link_transfers_per_second"),
|
|
||||||
"Value of maximum link's transfers per second (T/s)",
|
|
||||||
pcideviceLabelNames, nil,
|
|
||||||
)
|
|
||||||
pcideviceMaxLinkWidthDesc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, pcideviceSubsystem, "max_link_width"),
|
|
||||||
"Value of maximum link's width (number of lanes)",
|
|
||||||
pcideviceLabelNames, nil,
|
|
||||||
)
|
|
||||||
|
|
||||||
pcideviceCurrentLinkTSDesc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, pcideviceSubsystem, "current_link_transfers_per_second"),
|
|
||||||
"Value of current link's transfers per second (T/s)",
|
|
||||||
pcideviceLabelNames, nil,
|
|
||||||
)
|
|
||||||
pcideviceCurrentLinkWidthDesc = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, pcideviceSubsystem, "current_link_width"),
|
|
||||||
"Value of current link's width (number of lanes)",
|
|
||||||
pcideviceLabelNames, nil,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
type pcideviceCollector struct {
|
|
||||||
fs sysfs.FS
|
|
||||||
infoDesc typedDesc
|
|
||||||
descs []typedFactorDesc
|
|
||||||
logger *slog.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
registerCollector("pcidevice", defaultDisabled, NewPcideviceCollector)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPcideviceCollector returns a new Collector exposing PCI devices stats.
|
|
||||||
func NewPcideviceCollector(logger *slog.Logger) (Collector, error) {
|
|
||||||
fs, err := sysfs.NewFS(*sysPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to open sysfs: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c := pcideviceCollector{
|
|
||||||
fs: fs,
|
|
||||||
logger: logger,
|
|
||||||
infoDesc: typedDesc{
|
|
||||||
desc: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, pcideviceSubsystem, "info"),
|
|
||||||
"Non-numeric data from /sys/bus/pci/devices/<location>, value is always 1.",
|
|
||||||
append(pcideviceLabelNames,
|
|
||||||
[]string{"parent_segment", "parent_bus", "parent_device", "parent_function",
|
|
||||||
"class_id", "vendor_id", "subsystem_vendor_id", "subsystem_device_id", "revision"}...),
|
|
||||||
nil,
|
|
||||||
),
|
|
||||||
valueType: prometheus.GaugeValue,
|
|
||||||
},
|
|
||||||
descs: []typedFactorDesc{
|
|
||||||
{desc: pcideviceMaxLinkTSDesc, valueType: prometheus.GaugeValue},
|
|
||||||
{desc: pcideviceMaxLinkWidthDesc, valueType: prometheus.GaugeValue},
|
|
||||||
{desc: pcideviceCurrentLinkTSDesc, valueType: prometheus.GaugeValue},
|
|
||||||
{desc: pcideviceCurrentLinkWidthDesc, valueType: prometheus.GaugeValue},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return &c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *pcideviceCollector) Update(ch chan<- prometheus.Metric) error {
|
|
||||||
devices, err := c.fs.PciDevices()
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
|
||||||
c.logger.Debug("PCI device not found, skipping")
|
|
||||||
return ErrNoData
|
|
||||||
}
|
|
||||||
return fmt.Errorf("error obtaining PCI device info: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, device := range devices {
|
|
||||||
// The device location is represented in separated format.
|
|
||||||
values := device.Location.Strings()
|
|
||||||
if device.ParentLocation != nil {
|
|
||||||
values = append(values, device.ParentLocation.Strings()...)
|
|
||||||
} else {
|
|
||||||
values = append(values, []string{"*", "*", "*", "*"}...)
|
|
||||||
}
|
|
||||||
values = append(values, fmt.Sprintf("0x%06x", device.Class))
|
|
||||||
values = append(values, fmt.Sprintf("0x%04x", device.Device))
|
|
||||||
values = append(values, fmt.Sprintf("0x%04x", device.SubsystemVendor))
|
|
||||||
values = append(values, fmt.Sprintf("0x%04x", device.SubsystemDevice))
|
|
||||||
values = append(values, fmt.Sprintf("0x%02x", device.Revision))
|
|
||||||
|
|
||||||
ch <- c.infoDesc.mustNewConstMetric(1.0, values...)
|
|
||||||
|
|
||||||
// MaxLinkSpeed and CurrentLinkSpeed are represnted in GT/s
|
|
||||||
maxLinkSpeedTS := float64(int64(*device.MaxLinkSpeed * 1e9))
|
|
||||||
currentLinkSpeedTS := float64(int64(*device.CurrentLinkSpeed * 1e9))
|
|
||||||
|
|
||||||
for i, val := range []float64{
|
|
||||||
maxLinkSpeedTS,
|
|
||||||
float64(*device.MaxLinkWidth),
|
|
||||||
currentLinkSpeedTS,
|
|
||||||
float64(*device.CurrentLinkWidth),
|
|
||||||
} {
|
|
||||||
ch <- c.descs[i].mustNewConstMetric(val, device.Location.Strings()...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -33,7 +33,7 @@ func canTestPerf(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Skip("Procfs not mounted, skipping perf tests")
|
t.Skip("Procfs not mounted, skipping perf tests")
|
||||||
}
|
}
|
||||||
paranoidStr := strings.ReplaceAll(string(paranoidBytes), "\n", "")
|
paranoidStr := strings.Replace(string(paranoidBytes), "\n", "", -1)
|
||||||
paranoid, err := strconv.Atoi(paranoidStr)
|
paranoid, err := strconv.Atoi(paranoidStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Expected perf_event_paranoid to be an int, got: %s", paranoidStr)
|
t.Fatalf("Expected perf_event_paranoid to be an int, got: %s", paranoidStr)
|
||||||
|
|
|
@ -27,15 +27,8 @@ import (
|
||||||
"github.com/prometheus/procfs"
|
"github.com/prometheus/procfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
psiResourceCPU = "cpu"
|
|
||||||
psiResourceIO = "io"
|
|
||||||
psiResourceMemory = "memory"
|
|
||||||
psiResourceIRQ = "irq"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
psiResources = []string{psiResourceCPU, psiResourceIO, psiResourceMemory, psiResourceIRQ}
|
psiResources = []string{"cpu", "io", "memory", "irq"}
|
||||||
)
|
)
|
||||||
|
|
||||||
type pressureStatsCollector struct {
|
type pressureStatsCollector struct {
|
||||||
|
@ -100,18 +93,13 @@ func NewPressureStatsCollector(logger *slog.Logger) (Collector, error) {
|
||||||
|
|
||||||
// Update calls procfs.NewPSIStatsForResource for the different resources and updates the values
|
// Update calls procfs.NewPSIStatsForResource for the different resources and updates the values
|
||||||
func (c *pressureStatsCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *pressureStatsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
foundResources := 0
|
|
||||||
for _, res := range psiResources {
|
for _, res := range psiResources {
|
||||||
c.logger.Debug("collecting statistics for resource", "resource", res)
|
c.logger.Debug("collecting statistics for resource", "resource", res)
|
||||||
vals, err := c.fs.PSIStatsForResource(res)
|
vals, err := c.fs.PSIStatsForResource(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, os.ErrNotExist) && res != psiResourceIRQ {
|
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", "resource", res)
|
c.logger.Debug("pressure information is unavailable, you need a Linux kernel >= 4.20 and/or CONFIG_PSI enabled for your kernel")
|
||||||
continue
|
return ErrNoData
|
||||||
}
|
|
||||||
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) {
|
if errors.Is(err, syscall.ENOTSUP) {
|
||||||
c.logger.Debug("pressure information is disabled, add psi=1 kernel command line to enable it")
|
c.logger.Debug("pressure information is disabled, add psi=1 kernel command line to enable it")
|
||||||
|
@ -121,35 +109,28 @@ func (c *pressureStatsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
}
|
}
|
||||||
// IRQ pressure does not have 'some' data.
|
// IRQ pressure does not have 'some' data.
|
||||||
// See https://github.com/torvalds/linux/blob/v6.9/include/linux/psi_types.h#L65
|
// See https://github.com/torvalds/linux/blob/v6.9/include/linux/psi_types.h#L65
|
||||||
if vals.Some == nil && res != psiResourceIRQ {
|
if vals.Some == nil && res != "irq" {
|
||||||
c.logger.Debug("pressure information returned no 'some' data")
|
c.logger.Debug("pressure information returned no 'some' data")
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
if vals.Full == nil && res != psiResourceCPU {
|
if vals.Full == nil && res != "cpu" {
|
||||||
c.logger.Debug("pressure information returned no 'full' data")
|
c.logger.Debug("pressure information returned no 'full' data")
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
switch res {
|
switch res {
|
||||||
case psiResourceCPU:
|
case "cpu":
|
||||||
ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, float64(vals.Some.Total)/1000.0/1000.0)
|
ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, float64(vals.Some.Total)/1000.0/1000.0)
|
||||||
case psiResourceIO:
|
case "io":
|
||||||
ch <- prometheus.MustNewConstMetric(c.io, prometheus.CounterValue, float64(vals.Some.Total)/1000.0/1000.0)
|
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)
|
ch <- prometheus.MustNewConstMetric(c.ioFull, prometheus.CounterValue, float64(vals.Full.Total)/1000.0/1000.0)
|
||||||
case psiResourceMemory:
|
case "memory":
|
||||||
ch <- prometheus.MustNewConstMetric(c.mem, prometheus.CounterValue, float64(vals.Some.Total)/1000.0/1000.0)
|
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)
|
ch <- prometheus.MustNewConstMetric(c.memFull, prometheus.CounterValue, float64(vals.Full.Total)/1000.0/1000.0)
|
||||||
case psiResourceIRQ:
|
case "irq":
|
||||||
ch <- prometheus.MustNewConstMetric(c.irqFull, prometheus.CounterValue, float64(vals.Full.Total)/1000.0/1000.0)
|
ch <- prometheus.MustNewConstMetric(c.irqFull, prometheus.CounterValue, float64(vals.Full.Total)/1000.0/1000.0)
|
||||||
default:
|
default:
|
||||||
c.logger.Debug("did not account for resource", "resource", res)
|
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
|
return nil
|
||||||
|
|
|
@ -106,7 +106,7 @@ func (c *processCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
|
|
||||||
pidM, err := readUintFromFile(procFilePath("sys/kernel/pid_max"))
|
pidM, err := readUintFromFile(procFilePath("sys/kernel/pid_max"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve limit number of maximum pids allowed: %w", err)
|
return fmt.Errorf("unable to retrieve limit number of maximum pids alloved: %w", err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(c.pidUsed, prometheus.GaugeValue, float64(pids))
|
ch <- prometheus.MustNewConstMetric(c.pidUsed, prometheus.GaugeValue, float64(pids))
|
||||||
ch <- prometheus.MustNewConstMetric(c.pidMax, prometheus.GaugeValue, float64(pidM))
|
ch <- prometheus.MustNewConstMetric(c.pidMax, prometheus.GaugeValue, float64(pidM))
|
||||||
|
|
|
@ -48,7 +48,7 @@ func TestReadProcessStatus(t *testing.T) {
|
||||||
}
|
}
|
||||||
maxPid, err := readUintFromFile(procFilePath("sys/kernel/pid_max"))
|
maxPid, err := readUintFromFile(procFilePath("sys/kernel/pid_max"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to retrieve limit number of maximum pids allowed %v\n", err)
|
t.Fatalf("Unable to retrieve limit number of maximum pids alloved %v\n", err)
|
||||||
}
|
}
|
||||||
if uint64(pids) > maxPid || pids == 0 {
|
if uint64(pids) > maxPid || pids == 0 {
|
||||||
t.Fatalf("Total running pids cannot be greater than %d or equals to 0", maxPid)
|
t.Fatalf("Total running pids cannot be greater than %d or equals to 0", maxPid)
|
||||||
|
|
|
@ -74,7 +74,6 @@ type systemdCollector struct {
|
||||||
socketCurrentConnectionsDesc *prometheus.Desc
|
socketCurrentConnectionsDesc *prometheus.Desc
|
||||||
socketRefusedConnectionsDesc *prometheus.Desc
|
socketRefusedConnectionsDesc *prometheus.Desc
|
||||||
systemdVersionDesc *prometheus.Desc
|
systemdVersionDesc *prometheus.Desc
|
||||||
virtualizationDesc *prometheus.Desc
|
|
||||||
// Use regexps for more flexibility than device_filter.go allows
|
// Use regexps for more flexibility than device_filter.go allows
|
||||||
systemdUnitIncludePattern *regexp.Regexp
|
systemdUnitIncludePattern *regexp.Regexp
|
||||||
systemdUnitExcludePattern *regexp.Regexp
|
systemdUnitExcludePattern *regexp.Regexp
|
||||||
|
@ -133,9 +132,6 @@ func NewSystemdCollector(logger *slog.Logger) (Collector, error) {
|
||||||
systemdVersionDesc := prometheus.NewDesc(
|
systemdVersionDesc := prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(namespace, subsystem, "version"),
|
prometheus.BuildFQName(namespace, subsystem, "version"),
|
||||||
"Detected systemd version", []string{"version"}, nil)
|
"Detected systemd version", []string{"version"}, nil)
|
||||||
virtualizationDesc := prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(namespace, subsystem, "virtualization_info"),
|
|
||||||
"Detected virtualization technology", []string{"virtualization_type"}, nil)
|
|
||||||
|
|
||||||
if *oldSystemdUnitExclude != "" {
|
if *oldSystemdUnitExclude != "" {
|
||||||
if !systemdUnitExcludeSet {
|
if !systemdUnitExcludeSet {
|
||||||
|
@ -171,7 +167,6 @@ func NewSystemdCollector(logger *slog.Logger) (Collector, error) {
|
||||||
socketCurrentConnectionsDesc: socketCurrentConnectionsDesc,
|
socketCurrentConnectionsDesc: socketCurrentConnectionsDesc,
|
||||||
socketRefusedConnectionsDesc: socketRefusedConnectionsDesc,
|
socketRefusedConnectionsDesc: socketRefusedConnectionsDesc,
|
||||||
systemdVersionDesc: systemdVersionDesc,
|
systemdVersionDesc: systemdVersionDesc,
|
||||||
virtualizationDesc: virtualizationDesc,
|
|
||||||
systemdUnitIncludePattern: systemdUnitIncludePattern,
|
systemdUnitIncludePattern: systemdUnitIncludePattern,
|
||||||
systemdUnitExcludePattern: systemdUnitExcludePattern,
|
systemdUnitExcludePattern: systemdUnitExcludePattern,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
@ -199,14 +194,6 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
systemdVersionFull,
|
systemdVersionFull,
|
||||||
)
|
)
|
||||||
|
|
||||||
systemdVirtualization := c.getSystemdVirtualization(conn)
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
c.virtualizationDesc,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
1.0,
|
|
||||||
systemdVirtualization,
|
|
||||||
)
|
|
||||||
|
|
||||||
allUnits, err := c.getAllUnits(conn)
|
allUnits, err := c.getAllUnits(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get units: %w", err)
|
return fmt.Errorf("couldn't get units: %w", err)
|
||||||
|
@ -228,7 +215,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
begin := time.Now()
|
begin = time.Now()
|
||||||
c.collectUnitStatusMetrics(conn, ch, units)
|
c.collectUnitStatusMetrics(conn, ch, units)
|
||||||
c.logger.Debug("collectUnitStatusMetrics took", "duration_seconds", time.Since(begin).Seconds())
|
c.logger.Debug("collectUnitStatusMetrics took", "duration_seconds", time.Since(begin).Seconds())
|
||||||
}()
|
}()
|
||||||
|
@ -237,7 +224,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
begin := time.Now()
|
begin = time.Now()
|
||||||
c.collectUnitStartTimeMetrics(conn, ch, units)
|
c.collectUnitStartTimeMetrics(conn, ch, units)
|
||||||
c.logger.Debug("collectUnitStartTimeMetrics took", "duration_seconds", time.Since(begin).Seconds())
|
c.logger.Debug("collectUnitStartTimeMetrics took", "duration_seconds", time.Since(begin).Seconds())
|
||||||
}()
|
}()
|
||||||
|
@ -247,7 +234,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
begin := time.Now()
|
begin = time.Now()
|
||||||
c.collectUnitTasksMetrics(conn, ch, units)
|
c.collectUnitTasksMetrics(conn, ch, units)
|
||||||
c.logger.Debug("collectUnitTasksMetrics took", "duration_seconds", time.Since(begin).Seconds())
|
c.logger.Debug("collectUnitTasksMetrics took", "duration_seconds", time.Since(begin).Seconds())
|
||||||
}()
|
}()
|
||||||
|
@ -257,7 +244,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
begin := time.Now()
|
begin = time.Now()
|
||||||
c.collectTimers(conn, ch, units)
|
c.collectTimers(conn, ch, units)
|
||||||
c.logger.Debug("collectTimers took", "duration_seconds", time.Since(begin).Seconds())
|
c.logger.Debug("collectTimers took", "duration_seconds", time.Since(begin).Seconds())
|
||||||
}()
|
}()
|
||||||
|
@ -266,13 +253,13 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
begin := time.Now()
|
begin = time.Now()
|
||||||
c.collectSockets(conn, ch, units)
|
c.collectSockets(conn, ch, units)
|
||||||
c.logger.Debug("collectSockets took", "duration_seconds", time.Since(begin).Seconds())
|
c.logger.Debug("collectSockets took", "duration_seconds", time.Since(begin).Seconds())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if systemdVersion >= minSystemdVersionSystemState {
|
if systemdVersion >= minSystemdVersionSystemState {
|
||||||
begin := time.Now()
|
begin = time.Now()
|
||||||
err = c.collectSystemState(conn, ch)
|
err = c.collectSystemState(conn, ch)
|
||||||
c.logger.Debug("collectSystemState took", "duration_seconds", time.Since(begin).Seconds())
|
c.logger.Debug("collectSystemState took", "duration_seconds", time.Since(begin).Seconds())
|
||||||
}
|
}
|
||||||
|
@ -518,19 +505,3 @@ func (c *systemdCollector) getSystemdVersion(conn *dbus.Conn) (float64, string)
|
||||||
}
|
}
|
||||||
return v, version
|
return v, version
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *systemdCollector) getSystemdVirtualization(conn *dbus.Conn) string {
|
|
||||||
virt, err := conn.GetManagerProperty("Virtualization")
|
|
||||||
if err != nil {
|
|
||||||
c.logger.Debug("Could not get Virtualization property", "err", err)
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
|
|
||||||
virtStr := strings.Trim(virt, `"`)
|
|
||||||
if virtStr == "" {
|
|
||||||
// If no virtualization type is returned, assume it's bare metal.
|
|
||||||
return "none"
|
|
||||||
}
|
|
||||||
|
|
||||||
return virtStr
|
|
||||||
}
|
|
||||||
|
|
|
@ -122,12 +122,11 @@ func TestSystemdSummary(t *testing.T) {
|
||||||
summary := summarizeUnits(fixtures[0])
|
summary := summarizeUnits(fixtures[0])
|
||||||
|
|
||||||
for _, state := range unitStatesName {
|
for _, state := range unitStatesName {
|
||||||
switch state {
|
if state == "inactive" {
|
||||||
case "inactive":
|
|
||||||
testSummaryHelper(t, state, summary[state], 3.0)
|
testSummaryHelper(t, state, summary[state], 3.0)
|
||||||
case "active":
|
} else if state == "active" {
|
||||||
testSummaryHelper(t, state, summary[state], 1.0)
|
testSummaryHelper(t, state, summary[state], 1.0)
|
||||||
default:
|
} else {
|
||||||
testSummaryHelper(t, state, summary[state], 0.0)
|
testSummaryHelper(t, state, summary[state], 0.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,6 @@ import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/prometheus/node_exporter/collector/utils"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -178,7 +176,7 @@ func mappingCFStringToString(s C.CFStringRef) string {
|
||||||
buf := make([]byte, maxBufLen)
|
buf := make([]byte, maxBufLen)
|
||||||
var usedBufLen C.CFIndex
|
var usedBufLen C.CFIndex
|
||||||
_ = C.CFStringGetBytes(s, C.CFRange{0, length}, C.kCFStringEncodingUTF8, C.UInt8(0), C.false, (*C.UInt8)(&buf[0]), maxBufLen, &usedBufLen)
|
_ = C.CFStringGetBytes(s, C.CFRange{0, length}, C.kCFStringEncodingUTF8, C.UInt8(0), C.false, (*C.UInt8)(&buf[0]), maxBufLen, &usedBufLen)
|
||||||
return utils.SafeBytesToString(buf[:usedBufLen])
|
return string(buf[:usedBufLen])
|
||||||
}
|
}
|
||||||
|
|
||||||
func mappingCFNumberLongToInt(n C.CFNumberRef) int {
|
func mappingCFNumberLongToInt(n C.CFNumberRef) int {
|
||||||
|
|
|
@ -13,11 +13,6 @@
|
||||||
|
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SafeDereference[T any](s ...*T) []T {
|
func SafeDereference[T any](s ...*T) []T {
|
||||||
var resolved []T
|
var resolved []T
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
|
@ -30,18 +25,3 @@ func SafeDereference[T any](s ...*T) []T {
|
||||||
}
|
}
|
||||||
return resolved
|
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 "<22>".
|
|
||||||
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, "<22>")
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
// 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<6E>"; want != got {
|
|
||||||
t.Errorf("Expected: %s, Got: %s", want, got)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -435,5 +435,5 @@ type zfsSysctl string
|
||||||
|
|
||||||
func (s zfsSysctl) metricName() string {
|
func (s zfsSysctl) metricName() string {
|
||||||
parts := strings.Split(string(s), ".")
|
parts := strings.Split(string(s), ".")
|
||||||
return strings.ReplaceAll(parts[len(parts)-1], "-", "_")
|
return strings.Replace(parts[len(parts)-1], "-", "_", -1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,6 +200,9 @@ local diskSpaceUtilisation =
|
||||||
+ dashboard.withVariables([
|
+ dashboard.withVariables([
|
||||||
datasource,
|
datasource,
|
||||||
$._clusterVariable,
|
$._clusterVariable,
|
||||||
|
variable.query.withDatasourceFromVariable(datasource)
|
||||||
|
+ variable.query.refresh.onTime()
|
||||||
|
+ variable.query.withSort(asc=true),
|
||||||
])
|
])
|
||||||
+ dashboard.withPanels(
|
+ dashboard.withPanels(
|
||||||
grafana.util.grid.makeGrid([
|
grafana.util.grid.makeGrid([
|
||||||
|
@ -328,6 +331,9 @@ local diskSpaceUtilisation =
|
||||||
+ dashboard.withUid(std.md5('node-multicluster-rsrc-use.json'))
|
+ dashboard.withUid(std.md5('node-multicluster-rsrc-use.json'))
|
||||||
+ dashboard.withVariables([
|
+ dashboard.withVariables([
|
||||||
datasource,
|
datasource,
|
||||||
|
variable.query.withDatasourceFromVariable(datasource)
|
||||||
|
+ variable.query.refresh.onTime()
|
||||||
|
+ variable.query.withSort(asc=true),
|
||||||
])
|
])
|
||||||
+ dashboard.withPanels(
|
+ dashboard.withPanels(
|
||||||
grafana.util.grid.makeGrid([
|
grafana.util.grid.makeGrid([
|
||||||
|
|
|
@ -67,7 +67,6 @@ enabled_collectors=$(cat << COLLECTORS
|
||||||
netstat
|
netstat
|
||||||
nfs
|
nfs
|
||||||
nfsd
|
nfsd
|
||||||
pcidevice
|
|
||||||
pressure
|
pressure
|
||||||
processes
|
processes
|
||||||
qdisc
|
qdisc
|
||||||
|
@ -326,7 +325,6 @@ get "127.0.0.1:${port}/metrics" | grep --text -E -v "${skip_re}" > "${generated_
|
||||||
non_deterministic_metrics=$(cat << METRICS
|
non_deterministic_metrics=$(cat << METRICS
|
||||||
node_boot_time_seconds
|
node_boot_time_seconds
|
||||||
node_cpu_frequency_hertz
|
node_cpu_frequency_hertz
|
||||||
node_cpu_frequency_max_hertz
|
|
||||||
node_cpu_seconds_total
|
node_cpu_seconds_total
|
||||||
node_disk_io_time_seconds_total
|
node_disk_io_time_seconds_total
|
||||||
node_disk_read_bytes_total
|
node_disk_read_bytes_total
|
||||||
|
|
39
go.mod
39
go.mod
|
@ -1,6 +1,6 @@
|
||||||
module github.com/prometheus/node_exporter
|
module github.com/prometheus/node_exporter
|
||||||
|
|
||||||
go 1.23.0
|
go 1.22.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alecthomas/kingpin/v2 v2.4.0
|
github.com/alecthomas/kingpin/v2 v2.4.0
|
||||||
|
@ -13,23 +13,23 @@ require (
|
||||||
github.com/hodgesds/perf-utils v0.7.0
|
github.com/hodgesds/perf-utils v0.7.0
|
||||||
github.com/illumos/go-kstat v0.0.0-20210513183136-173c9b0a9973
|
github.com/illumos/go-kstat v0.0.0-20210513183136-173c9b0a9973
|
||||||
github.com/josharian/native v1.1.0
|
github.com/josharian/native v1.1.0
|
||||||
github.com/jsimonetti/rtnetlink/v2 v2.0.5
|
github.com/jsimonetti/rtnetlink/v2 v2.0.2
|
||||||
github.com/lufia/iostat v1.2.1
|
github.com/lufia/iostat v1.2.1
|
||||||
github.com/mattn/go-xmlrpc v0.0.3
|
github.com/mattn/go-xmlrpc v0.0.3
|
||||||
github.com/mdlayher/ethtool v0.4.0
|
github.com/mdlayher/ethtool v0.2.0
|
||||||
github.com/mdlayher/netlink v1.7.2
|
github.com/mdlayher/netlink v1.7.2
|
||||||
github.com/mdlayher/wifi v0.6.0
|
github.com/mdlayher/wifi v0.3.1
|
||||||
github.com/opencontainers/selinux v1.12.0
|
github.com/opencontainers/selinux v1.11.1
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55
|
||||||
github.com/prometheus-community/go-runit v0.1.0
|
github.com/prometheus-community/go-runit v0.1.0
|
||||||
github.com/prometheus/client_golang v1.23.0
|
github.com/prometheus/client_golang v1.20.5
|
||||||
github.com/prometheus/client_model v0.6.2
|
github.com/prometheus/client_model v0.6.1
|
||||||
github.com/prometheus/common v0.65.0
|
github.com/prometheus/common v0.62.0
|
||||||
github.com/prometheus/exporter-toolkit v0.14.0
|
github.com/prometheus/exporter-toolkit v0.14.0
|
||||||
github.com/prometheus/procfs v0.17.0
|
github.com/prometheus/procfs v0.15.2-0.20240603130017-1754b780536b // == v0.15.1 + https://github.com/prometheus/procfs/commit/1754b780536bb81082baa913e04cc4fff4d2baea
|
||||||
github.com/safchain/ethtool v0.6.2
|
github.com/safchain/ethtool v0.5.10
|
||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
|
||||||
golang.org/x/sys v0.34.0
|
golang.org/x/sys v0.30.0
|
||||||
howett.net/plist v1.0.1
|
howett.net/plist v1.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,8 +38,9 @@ require (
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/dennwc/ioctl v1.0.0 // indirect
|
github.com/dennwc/ioctl v1.0.0 // indirect
|
||||||
github.com/google/go-cmp v0.7.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/jpillora/backoff v1.0.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
|
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||||
github.com/mdlayher/genetlink v1.3.2 // indirect
|
github.com/mdlayher/genetlink v1.3.2 // indirect
|
||||||
github.com/mdlayher/socket v0.4.1 // indirect
|
github.com/mdlayher/socket v0.4.1 // indirect
|
||||||
|
@ -50,11 +51,13 @@ require (
|
||||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
golang.org/x/crypto v0.39.0 // indirect
|
golang.org/x/crypto v0.32.0 // indirect
|
||||||
golang.org/x/net v0.40.0 // indirect
|
golang.org/x/net v0.33.0 // indirect
|
||||||
golang.org/x/oauth2 v0.30.0 // indirect
|
golang.org/x/oauth2 v0.24.0 // indirect
|
||||||
golang.org/x/sync v0.15.0 // indirect
|
golang.org/x/sync v0.10.0 // indirect
|
||||||
golang.org/x/text v0.26.0 // indirect
|
golang.org/x/text v0.21.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.6 // indirect
|
google.golang.org/protobuf v1.36.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//replace github.com/prometheus/procfs => github.com/rexagod/procfs v0.0.0-20241124020414-857c5b813f1b
|
||||||
|
|
79
go.sum
79
go.sum
|
@ -8,8 +8,8 @@ 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/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
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/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cilium/ebpf v0.19.0 h1:Ro/rE64RmFBeA9FGjcTc+KmCeY6jXmryu6FfnzPRIao=
|
github.com/cilium/ebpf v0.12.3 h1:8ht6F9MquybnY97at+VDZb3eQQr8ev79RueWeVaEcG4=
|
||||||
github.com/cilium/ebpf v0.19.0/go.mod h1:fLCgMo3l8tZmAdM3B2XqdFzXBpwkcSTroaVqN08OWVY=
|
github.com/cilium/ebpf v0.12.3/go.mod h1:TctK1ivibvI3znr66ljgi4hqOT8EYQjz1KWBfb1UVgM=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
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.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -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.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 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/hashicorp/go-envparse v0.1.0 h1:bE++6bhIsNCPLvgDZkYqo3nA+/PFI51pkrHdmPSDFPY=
|
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/hashicorp/go-envparse v0.1.0/go.mod h1:OHheN1GoygLlAkTlXLXvAdnXdZxy8JUweQ1rAXx1xnc=
|
||||||
github.com/hodgesds/perf-utils v0.7.0 h1:7KlHGMuig4FRH5fNw68PV6xLmgTe7jKs9hgAcEAbioU=
|
github.com/hodgesds/perf-utils v0.7.0 h1:7KlHGMuig4FRH5fNw68PV6xLmgTe7jKs9hgAcEAbioU=
|
||||||
|
@ -37,10 +37,10 @@ github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtL
|
||||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
github.com/jsimonetti/rtnetlink/v2 v2.0.5 h1:l5S9iedrSW4thUfgiU+Hzsnk1cOR0upGD5ttt6mirHw=
|
github.com/jsimonetti/rtnetlink/v2 v2.0.2 h1:ZKlbCujrIpp4/u3V2Ka0oxlf4BCkt6ojkvpy3nZoCBY=
|
||||||
github.com/jsimonetti/rtnetlink/v2 v2.0.5/go.mod h1:9yTlq3Ojr1rbmh/Y5L30/KIojpFhTRph2xKeZ+y+Pic=
|
github.com/jsimonetti/rtnetlink/v2 v2.0.2/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE=
|
||||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
@ -51,8 +51,8 @@ github.com/lufia/iostat v1.2.1 h1:tnCdZBIglgxD47RyD55kfWQcJMGzO+1QBziSQfesf2k=
|
||||||
github.com/lufia/iostat v1.2.1/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg=
|
github.com/lufia/iostat v1.2.1/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg=
|
||||||
github.com/mattn/go-xmlrpc v0.0.3 h1:Y6WEMLEsqs3RviBrAa1/7qmbGB7DVD3brZIbqMbQdGY=
|
github.com/mattn/go-xmlrpc v0.0.3 h1:Y6WEMLEsqs3RviBrAa1/7qmbGB7DVD3brZIbqMbQdGY=
|
||||||
github.com/mattn/go-xmlrpc v0.0.3/go.mod h1:mqc2dz7tP5x5BKlCahN/n+hs7OSZKJkS9JsHNBRlrxA=
|
github.com/mattn/go-xmlrpc v0.0.3/go.mod h1:mqc2dz7tP5x5BKlCahN/n+hs7OSZKJkS9JsHNBRlrxA=
|
||||||
github.com/mdlayher/ethtool v0.4.0 h1:jjMGNSQfqauwFCtSzcqpa57R0AJdxKdQgbQ9mAOtM4Q=
|
github.com/mdlayher/ethtool v0.2.0 h1:akcA4WZVWozzirPASeMq8qgLkxpF3ykftVXwnrMKrhY=
|
||||||
github.com/mdlayher/ethtool v0.4.0/go.mod h1:GrljOneAFOTPGazYlf8qpxvYLdu4mo3pdJqXWLZ2Re8=
|
github.com/mdlayher/ethtool v0.2.0/go.mod h1:W0pIBrNPK1TslIN4Z9wt1EVbay66Kbvek2z2f29VBfw=
|
||||||
github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw=
|
github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw=
|
||||||
github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o=
|
github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o=
|
||||||
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
|
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
|
||||||
|
@ -61,34 +61,34 @@ github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U
|
||||||
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
||||||
github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
|
github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
|
||||||
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
|
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
|
||||||
github.com/mdlayher/wifi v0.6.0 h1:yBVPVgyCWcdyLkztUVM2Czd2XFKRJegHOoBm2gBWKG8=
|
github.com/mdlayher/wifi v0.3.1 h1:bZDuMI1f7z5BtUUO3NgHRdR/R88YtywIe6dsEFI0Txs=
|
||||||
github.com/mdlayher/wifi v0.6.0/go.mod h1:qwcTzRuC2bV+s4PFhGMzPi0sFHAr2jXkUSumSMIU6+4=
|
github.com/mdlayher/wifi v0.3.1/go.mod h1:ODQaObvsglghTuNhezD9grkTB4shVNc28aJfTXmvSi8=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8=
|
github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8=
|
||||||
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U=
|
github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
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 h1:uTWEj/Fn2RoLdfg/etSqwzgYNOYPrARx1BHUN052tGA=
|
||||||
github.com/prometheus-community/go-runit v0.1.0/go.mod h1:AvJ9Jo3gAFu2lbM4+qfjdpq30FfiLDJZKbQ015u08IQ=
|
github.com/prometheus-community/go-runit v0.1.0/go.mod h1:AvJ9Jo3gAFu2lbM4+qfjdpq30FfiLDJZKbQ015u08IQ=
|
||||||
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||||
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
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 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg=
|
||||||
github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA=
|
github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA=
|
||||||
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
|
github.com/prometheus/procfs v0.15.2-0.20240603130017-1754b780536b h1:4EJkx3vycI+n5JY5ht+bnSUGamkmmXkpcNeO/OBT/0A=
|
||||||
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
|
github.com/prometheus/procfs v0.15.2-0.20240603130017-1754b780536b/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
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/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
github.com/safchain/ethtool v0.6.2 h1:O3ZPFAKEUEfbtE6J/feEe2Ft7dIJ2Sy8t4SdMRiIMHY=
|
github.com/safchain/ethtool v0.5.10 h1:Im294gZtuf4pSGJRAOGKaASNi3wMeFaGaWuSaomedpc=
|
||||||
github.com/safchain/ethtool v0.6.2/go.mod h1:VS7cn+bP3Px3rIq55xImBiZGHVLNyBh5dqG6dDQy8+I=
|
github.com/safchain/ethtool v0.5.10/go.mod h1:w9jh2Lx7YBR4UwzLkzCmWl85UY0W2uZdd7/DckVE5+c=
|
||||||
github.com/siebenmann/go-kstat v0.0.0-20210513183136-173c9b0a9973 h1:GfSdC6wKfTGcgCS7BtzF5694Amne1pGCSTY252WhlEY=
|
github.com/siebenmann/go-kstat v0.0.0-20210513183136-173c9b0a9973 h1:GfSdC6wKfTGcgCS7BtzF5694Amne1pGCSTY252WhlEY=
|
||||||
github.com/siebenmann/go-kstat v0.0.0-20210513183136-173c9b0a9973/go.mod h1:G81aIFAMS9ECrwBYR9YxhlPjWgrItd+Kje78O6+uqm8=
|
github.com/siebenmann/go-kstat v0.0.0-20210513183136-173c9b0a9973/go.mod h1:G81aIFAMS9ECrwBYR9YxhlPjWgrItd+Kje78O6+uqm8=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
@ -100,28 +100,27 @@ 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=
|
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
|
||||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
|
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/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
|
||||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
|
||||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.10.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-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.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
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=
|
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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
|
|
@ -112,7 +112,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.logger.Warn("Couldn't create filtered metrics handler:", "err", err)
|
h.logger.Warn("Couldn't create filtered metrics handler:", "err", err)
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
fmt.Fprintf(w, "Couldn't create filtered metrics handler: %s", err)
|
w.Write([]byte(fmt.Sprintf("Couldn't create filtered metrics handler: %s", err)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
filteredHandler.ServeHTTP(w, r)
|
filteredHandler.ServeHTTP(w, r)
|
||||||
|
|
Loading…
Reference in a new issue