pagefile: BREAKING: move paging metrics from os to dedicated collector (click PR for more information) (#1735)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
parent
df8513ab8e
commit
7a9a4e5831
|
@ -41,6 +41,7 @@ Name | Description | Enabled by default
|
|||
[netframework](docs/collector.netframework.md) | .NET Framework metrics |
|
||||
[net](docs/collector.net.md) | Network interface I/O | ✓
|
||||
[os](docs/collector.os.md) | OS metrics (memory, processes, users) | ✓
|
||||
[pagefile](docs/collector.pagefile.md) | pagefile metrics |
|
||||
[perfdata](docs/collector.perfdata.md) | Custom perfdata metrics |
|
||||
[physical_disk](docs/collector.physical_disk.md) | physical disk metrics | ✓
|
||||
[printer](docs/collector.printer.md) | Printer metrics |
|
||||
|
|
|
@ -15,11 +15,9 @@ None
|
|||
## Metrics
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|------------------------------------------------------------------------|
|
||||
|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|------------------------------------------------------------------------|
|
||||
| `windows_os_hostname` | Labelled system hostname information as provided by ComputerSystem.DNSHostName and ComputerSystem.Domain | gauge | `domain`, `fqdn`, `hostname` |
|
||||
| `windows_os_info` | Contains full product name & version in labels. Note that the `major_version` for Windows 11 is "10"; a build number greater than 22000 represents Windows 11. | gauge | `product`, `version`, `major_version`, `minor_version`, `build_number` |
|
||||
| `windows_os_paging_limit_bytes` | Total number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files | gauge | None |
|
||||
| `windows_os_paging_free_bytes` | Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out | gauge | None |
|
||||
|
||||
|
||||
### Example metric
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
# pagefile collector
|
||||
|
||||
The pagefile collector exposes metrics about the pagefile usage
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `pagefile`
|
||||
Classes | [`Win32_OperatingSystem`](https://msdn.microsoft.com/en-us/library/aa394239)
|
||||
Enabled by default? | Yes
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------|-------|--------|
|
||||
| `windows_pagefile_free_bytes` | Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out | gauge | `file` |
|
||||
| `windows_pagefile_limit_bytes` | Number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files | gauge | `file` |
|
||||
|
||||
|
||||
### Example metric
|
||||
|
||||
```
|
||||
# HELP windows_pagefile_free_bytes OperatingSystem.FreeSpaceInPagingFiles
|
||||
# TYPE windows_pagefile_free_bytes gauge
|
||||
windows_pagefile_free_bytes{file="C:\\pagefile.sys"} 6.025797632e+09
|
||||
# HELP windows_pagefile_limit_bytes OperatingSystem.SizeStoredInPagingFiles
|
||||
# TYPE windows_pagefile_limit_bytes gauge
|
||||
windows_pagefile_limit_bytes{file="C:\\pagefile.sys"} 6.442450944e+09
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have useful queries, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
|
@ -36,7 +36,12 @@ type Collector struct {
|
|||
|
||||
hostname *prometheus.Desc
|
||||
osInformation *prometheus.Desc
|
||||
|
||||
// pagingFreeBytes
|
||||
// Deprecated: Use windows_paging_free_bytes instead.
|
||||
pagingFreeBytes *prometheus.Desc
|
||||
// pagingLimitBytes
|
||||
// Deprecated: Use windows_paging_total_bytes instead.
|
||||
pagingLimitBytes *prometheus.Desc
|
||||
|
||||
// users
|
||||
|
@ -151,13 +156,13 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
|||
)
|
||||
c.pagingLimitBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "paging_limit_bytes"),
|
||||
"OperatingSystem.SizeStoredInPagingFiles",
|
||||
"Deprecated: Use windows_pagefile_limit_bytes instead.",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.pagingFreeBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "paging_free_bytes"),
|
||||
"OperatingSystem.FreeSpaceInPagingFiles",
|
||||
"Deprecated: Use windows_pagefile_free_bytes instead.",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package pagefile
|
||||
|
||||
const (
|
||||
usage = "% Usage"
|
||||
)
|
|
@ -0,0 +1,136 @@
|
|||
//go:build windows
|
||||
|
||||
package pagefile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/headers/psapi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "pagefile"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A Collector is a Prometheus Collector for WMI metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
perfDataCollector perfdata.Collector
|
||||
|
||||
pagingFreeBytes *prometheus.Desc
|
||||
pagingLimitBytes *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(_ *kingpin.Application) *Collector {
|
||||
return &Collector{}
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
counters := []string{
|
||||
usage,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector(perfdata.V2, "Paging File", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Paging File collector: %w", err)
|
||||
}
|
||||
|
||||
c.pagingLimitBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "limit_bytes"),
|
||||
"Number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files",
|
||||
[]string{"file"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.pagingFreeBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "free_bytes"),
|
||||
"Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out",
|
||||
[]string{"file"},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, _ *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
return c.collectPaging(ch)
|
||||
}
|
||||
|
||||
func (c *Collector) collectPaging(ch chan<- prometheus.Metric) error {
|
||||
data, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect Paging File metrics: %w", err)
|
||||
}
|
||||
|
||||
gpi, err := psapi.GetPerformanceInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for fileName, pageFile := range data {
|
||||
fileString := strings.ReplaceAll(fileName, `\??\`, "")
|
||||
file, err := os.Stat(fileString)
|
||||
|
||||
var fileSize float64
|
||||
|
||||
// For unknown reasons, Windows doesn't always create a page file. Continue collection rather than aborting.
|
||||
if err == nil {
|
||||
fileSize = float64(file.Size())
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pagingFreeBytes,
|
||||
prometheus.GaugeValue,
|
||||
fileSize-(pageFile[usage].FirstValue*float64(gpi.PageSize)),
|
||||
fileString,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pagingLimitBytes,
|
||||
prometheus.GaugeValue,
|
||||
fileSize,
|
||||
fileString,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package pagefile_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/pagefile"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, pagefile.Name, pagefile.NewWithFlags)
|
||||
}
|
||||
|
||||
func TestCollector(t *testing.T) {
|
||||
testutils.TestCollector(t, pagefile.New, nil)
|
||||
}
|
|
@ -5,6 +5,7 @@ package v2
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
|
@ -17,6 +18,7 @@ type Collector struct {
|
|||
object string
|
||||
counters map[string]Counter
|
||||
handle pdhQueryHandle
|
||||
totalCounterRequested bool
|
||||
}
|
||||
|
||||
type Counter struct {
|
||||
|
@ -42,6 +44,7 @@ func NewCollector(object string, instances []string, counters []string) (*Collec
|
|||
object: object,
|
||||
counters: make(map[string]Counter, len(counters)),
|
||||
handle: handle,
|
||||
totalCounterRequested: slices.Contains(instances, "_Total"),
|
||||
}
|
||||
|
||||
for _, counterName := range counters {
|
||||
|
@ -166,12 +169,10 @@ func (c *Collector) Collect() (map[string]map[string]perftypes.CounterValues, er
|
|||
metricType = prometheus.GaugeValue
|
||||
}
|
||||
|
||||
_, isTotalCounterRequests := c.counters["_Total"]
|
||||
|
||||
for _, item := range items {
|
||||
if item.RawValue.CStatus == PdhCstatusValidData || item.RawValue.CStatus == PdhCstatusNewData {
|
||||
instanceName := windows.UTF16PtrToString(item.SzName)
|
||||
if strings.HasSuffix(instanceName, "_Total") && !isTotalCounterRequests {
|
||||
if strings.HasSuffix(instanceName, "_Total") && !c.totalCounterRequested {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/prometheus-community/windows_exporter/internal/collector/netframework"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/nps"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/os"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/pagefile"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/physical_disk"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/printer"
|
||||
|
@ -107,6 +108,7 @@ func NewWithConfig(config Config) *MetricCollectors {
|
|||
collectors[netframework.Name] = netframework.New(&config.NetFramework)
|
||||
collectors[nps.Name] = nps.New(&config.Nps)
|
||||
collectors[os.Name] = os.New(&config.OS)
|
||||
collectors[pagefile.Name] = pagefile.New(&config.Paging)
|
||||
collectors[perfdata.Name] = perfdata.New(&config.PerfData)
|
||||
collectors[physical_disk.Name] = physical_disk.New(&config.PhysicalDisk)
|
||||
collectors[printer.Name] = printer.New(&config.Printer)
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/prometheus-community/windows_exporter/internal/collector/netframework"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/nps"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/os"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/pagefile"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/physical_disk"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/printer"
|
||||
|
@ -79,6 +80,7 @@ type Config struct {
|
|||
NetFramework netframework.Config `yaml:"net_framework"`
|
||||
Nps nps.Config `yaml:"nps"`
|
||||
OS os.Config `yaml:"os"`
|
||||
Paging pagefile.Config `yaml:"paging"`
|
||||
PerfData perfdata.Config `yaml:"perf_data"`
|
||||
PhysicalDisk physical_disk.Config `yaml:"physical_disk"`
|
||||
Printer printer.Config `yaml:"printer"`
|
||||
|
@ -132,6 +134,7 @@ var ConfigDefaults = Config{
|
|||
NetFramework: netframework.ConfigDefaults,
|
||||
Nps: nps.ConfigDefaults,
|
||||
OS: os.ConfigDefaults,
|
||||
Paging: pagefile.ConfigDefaults,
|
||||
PerfData: perfdata.ConfigDefaults,
|
||||
PhysicalDisk: physical_disk.ConfigDefaults,
|
||||
Printer: printer.ConfigDefaults,
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/prometheus-community/windows_exporter/internal/collector/netframework"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/nps"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/os"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/pagefile"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/physical_disk"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/printer"
|
||||
|
@ -89,6 +90,7 @@ var BuildersWithFlags = map[string]BuilderWithFlags[Collector]{
|
|||
netframework.Name: NewBuilderWithFlags(netframework.NewWithFlags),
|
||||
nps.Name: NewBuilderWithFlags(nps.NewWithFlags),
|
||||
os.Name: NewBuilderWithFlags(os.NewWithFlags),
|
||||
pagefile.Name: NewBuilderWithFlags(pagefile.NewWithFlags),
|
||||
perfdata.Name: NewBuilderWithFlags(perfdata.NewWithFlags),
|
||||
physical_disk.Name: NewBuilderWithFlags(physical_disk.NewWithFlags),
|
||||
printer.Name: NewBuilderWithFlags(printer.NewWithFlags),
|
||||
|
|
|
@ -122,6 +122,7 @@ windows_exporter_collector_success{collector="logon"} 1
|
|||
windows_exporter_collector_success{collector="memory"} 1
|
||||
windows_exporter_collector_success{collector="net"} 1
|
||||
windows_exporter_collector_success{collector="os"} 1
|
||||
windows_exporter_collector_success{collector="pagefile"} 1
|
||||
windows_exporter_collector_success{collector="perfdata"} 1
|
||||
windows_exporter_collector_success{collector="physical_disk"} 1
|
||||
windows_exporter_collector_success{collector="printer"} 1
|
||||
|
@ -144,6 +145,7 @@ windows_exporter_collector_timeout{collector="logon"} 0
|
|||
windows_exporter_collector_timeout{collector="memory"} 0
|
||||
windows_exporter_collector_timeout{collector="net"} 0
|
||||
windows_exporter_collector_timeout{collector="os"} 0
|
||||
windows_exporter_collector_timeout{collector="pagefile"} 0
|
||||
windows_exporter_collector_timeout{collector="perfdata"} 0
|
||||
windows_exporter_collector_timeout{collector="physical_disk"} 0
|
||||
windows_exporter_collector_timeout{collector="printer"} 0
|
||||
|
@ -297,9 +299,9 @@ windows_exporter_collector_timeout{collector="udp"} 0
|
|||
# TYPE windows_os_hostname gauge
|
||||
# HELP windows_os_info Contains full product name & version in labels. Note that the "major_version" for Windows 11 is \\"10\\"; a build number greater than 22000 represents Windows 11.
|
||||
# TYPE windows_os_info gauge
|
||||
# HELP windows_os_paging_free_bytes OperatingSystem.FreeSpaceInPagingFiles
|
||||
# HELP windows_os_paging_free_bytes Deprecated: Use windows_pagefile_free_bytes instead.
|
||||
# TYPE windows_os_paging_free_bytes gauge
|
||||
# HELP windows_os_paging_limit_bytes OperatingSystem.SizeStoredInPagingFiles
|
||||
# HELP windows_os_paging_limit_bytes Deprecated: Use windows_pagefile_limit_bytes instead.
|
||||
# TYPE windows_os_paging_limit_bytes gauge
|
||||
# HELP windows_os_physical_memory_free_bytes Deprecated: Use `windows_memory_physical_free_bytes` instead.
|
||||
# TYPE windows_os_physical_memory_free_bytes gauge
|
||||
|
@ -321,6 +323,10 @@ windows_exporter_collector_timeout{collector="udp"} 0
|
|||
# TYPE windows_os_virtual_memory_free_bytes gauge
|
||||
# HELP windows_os_visible_memory_bytes Deprecated: Use `windows_memory_physical_total_bytes` instead.
|
||||
# TYPE windows_os_visible_memory_bytes gauge
|
||||
# HELP windows_pagefile_free_bytes Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out
|
||||
# TYPE windows_pagefile_free_bytes gauge
|
||||
# HELP windows_pagefile_limit_bytes Number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files
|
||||
# TYPE windows_pagefile_limit_bytes gauge
|
||||
# HELP windows_perfdata_memory_cache_faults_sec Performance data for \\Memory\\Cache Faults/sec
|
||||
# TYPE windows_perfdata_memory_cache_faults_sec counter
|
||||
# HELP windows_perfdata_processor_information__privileged_time Performance data for \\Processor Information\\% Privileged Time
|
||||
|
|
|
@ -18,14 +18,14 @@ mkdir $textfile_dir | Out-Null
|
|||
Copy-Item 'e2e-textfile.prom' -Destination "$($textfile_dir)/e2e-textfile.prom"
|
||||
|
||||
# Omit dynamic collector information that will change after each run
|
||||
$skip_re = "^(go_|windows_exporter_build_info|windows_exporter_collector_duration_seconds|windows_exporter_perflib_snapshot_duration_seconds|windows_exporter_scrape_duration_seconds|process_|windows_textfile_mtime_seconds|windows_cpu|windows_cs|windows_cache|windows_logon|windows_logical_disk|windows_physical_disk|windows_memory|windows_net|windows_os|windows_process|windows_service_process|windows_printer|windows_udp|windows_tcp|windows_system|windows_time|windows_session|windows_perfdata|windows_textfile_mtime_seconds)"
|
||||
$skip_re = "^(go_|windows_exporter_build_info|windows_exporter_collector_duration_seconds|windows_exporter_perflib_snapshot_duration_seconds|windows_exporter_scrape_duration_seconds|process_|windows_textfile_mtime_seconds|windows_cpu|windows_cs|windows_cache|windows_logon|windows_pagefile|windows_logical_disk|windows_physical_disk|windows_memory|windows_net|windows_os|windows_process|windows_service_process|windows_printer|windows_udp|windows_tcp|windows_system|windows_time|windows_session|windows_perfdata|windows_textfile_mtime_seconds)"
|
||||
|
||||
# Start process in background, awaiting HTTP requests.
|
||||
# Use default collectors, port and address: http://localhost:9182/metrics
|
||||
$exporter_proc = Start-Process `
|
||||
-PassThru `
|
||||
-FilePath ..\windows_exporter.exe `
|
||||
-ArgumentList "--log.level=debug","--web.disable-exporter-metrics","--collectors.enabled=[defaults],cpu_info,textfile,process,perfdata,scheduled_task,tcp,udp,time,system,service,logical_disk,printer,os,net,memory,logon,cache","--collector.process.include=explorer.exe","--collector.scheduled_task.include=.*GAEvents","--collector.service.include=Themes","--collector.textfile.directories=$($textfile_dir)",@"
|
||||
-ArgumentList "--log.level=debug","--web.disable-exporter-metrics","--collectors.enabled=[defaults],cpu_info,textfile,process,pagefile,perfdata,scheduled_task,tcp,udp,time,system,service,logical_disk,printer,os,net,memory,logon,cache","--collector.process.include=explorer.exe","--collector.scheduled_task.include=.*GAEvents","--collector.service.include=Themes","--collector.textfile.directories=$($textfile_dir)",@"
|
||||
--collector.perfdata.objects="[{\"object\":\"Processor Information\",\"instance_label\":\"core\",\"instances\":[\"*\"],\"counters\":{\"% Processor Time\":{},\"% Privileged Time\":{}}},{\"object\":\"Memory\",\"counters\":{\"Cache Faults/sec\":{\"type\":\"counter\"}}}]"
|
||||
"@ `
|
||||
-WindowStyle Hidden `
|
||||
|
|
Loading…
Reference in New Issue