diff --git a/collector/os.go b/collector/os.go index 6af19159..aa914f39 100644 --- a/collector/os.go +++ b/collector/os.go @@ -4,15 +4,16 @@ package collector import ( "fmt" + "os" "strings" "time" - "github.com/prometheus-community/windows_exporter/headers/custom" "github.com/prometheus-community/windows_exporter/headers/netapi32" "github.com/prometheus-community/windows_exporter/headers/psapi" "github.com/prometheus-community/windows_exporter/headers/sysinfoapi" - "github.com/prometheus-community/windows_exporter/log" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/log" + "golang.org/x/sys/windows/registry" ) func init() { @@ -157,60 +158,63 @@ type Win32_OperatingSystem struct { } func (c *OSCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) { - /*var dst []Win32_OperatingSystem - q := queryAll(&dst) - if err := wmi.Query(q, &dst); err != nil { - return nil, err - } - - if len(dst) == 0 { - return nil, errors.New("WMI query returned empty result set") - }*/ - - product, buildNum := custom.GetProductDetails() - nwgi, _, err := netapi32.NetWkstaGetInfo() if err != nil { return nil, err } - ch <- prometheus.MustNewConstMetric( - c.OSInformation, - prometheus.GaugeValue, - 1.0, - fmt.Sprintf("Microsoft %s", product), // Caption - fmt.Sprintf("%d.%d.%s", nwgi.Wki102_ver_major, nwgi.Wki102_ver_minor, buildNum), // Version - ) - gmse, err := sysinfoapi.GlobalMemoryStatusEx() if err != nil { return nil, err } - ch <- prometheus.MustNewConstMetric( - c.PhysicalMemoryFreeBytes, - prometheus.GaugeValue, - float64(gmse.UllAvailPhys), - ) - currentTime := time.Now() - - ch <- prometheus.MustNewConstMetric( - c.Time, - prometheus.GaugeValue, - float64(currentTime.Unix()), - ) - timezoneName, _ := currentTime.Zone() - ch <- prometheus.MustNewConstMetric( - c.Timezone, - prometheus.GaugeValue, - 1.0, - timezoneName, - ) + // Get total allocation of paging files across all disks. + memManKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`, registry.QUERY_VALUE) + if err != nil { + return nil, err + } + pagingFiles, _, err := memManKey.GetStringsValue("ExistingPageFiles") + if err != nil { + return nil, err + } - fsipf, err := custom.GetSizeStoredInPagingFiles() + if err := memManKey.Close(); err != nil { + return nil, err + } + + // Get build number and product name from registry + ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) + if err != nil { + return nil, err + } + pn, _, err := ntKey.GetStringValue("ProductName") + if err != nil { + return nil, err + } + + bn, _, err := ntKey.GetStringValue("CurrentBuildNumber") + if err != nil { + return nil, err + } + + if err := ntKey.Close(); err != nil { + return nil, err + } + + var fsipf float64 = 0 + for _, pagingFile := range pagingFiles { + fileString := strings.ReplaceAll(pagingFile, `\??\`, "") + file, err := os.Stat(fileString) + if err != nil { + return nil, err + } + fsipf += float64(file.Size()) + } + + gpi, err := psapi.GetPerformanceInfo() if err != nil { return nil, err } @@ -220,21 +224,49 @@ func (c *OSCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) ( return nil, err } - var pfbPercent float64 + // Get current page file usage. + var pfbRaw float64 = 0 for _, pageFile := range pfc { if strings.Contains(strings.ToLower(pageFile.Name), "_total") { - pfbPercent = pageFile.Usage - } else { continue } + pfbRaw += pageFile.Usage } - fpbNum := float64(fsipf) - (float64(fsipf) / float64(100) * pfbPercent) + // Subtract from total page file allocation on disk. + pfb := fsipf - (pfbRaw * float64(gpi.PageSize)) + + ch <- prometheus.MustNewConstMetric( + c.OSInformation, + prometheus.GaugeValue, + 1.0, + fmt.Sprintf("Microsoft %s", pn), // Caption + fmt.Sprintf("%d.%d.%s", nwgi.Wki102_ver_major, nwgi.Wki102_ver_minor, bn), // Version + ) + + ch <- prometheus.MustNewConstMetric( + c.PhysicalMemoryFreeBytes, + prometheus.GaugeValue, + float64(gmse.UllAvailPhys), + ) + + ch <- prometheus.MustNewConstMetric( + c.Time, + prometheus.GaugeValue, + float64(currentTime.Unix()), + ) + + ch <- prometheus.MustNewConstMetric( + c.Timezone, + prometheus.GaugeValue, + 1.0, + timezoneName, + ) ch <- prometheus.MustNewConstMetric( c.PagingFreeBytes, prometheus.GaugeValue, - float64(fpbNum), + pfb, ) ch <- prometheus.MustNewConstMetric( @@ -258,11 +290,6 @@ func (c *OSCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) ( float64(gmse.UllTotalVirtual), ) - gpi, err := psapi.GetLPPerformanceInfo() - if err != nil { - return nil, err - } - ch <- prometheus.MustNewConstMetric( c.Processes, prometheus.GaugeValue, diff --git a/headers/custom/custom.go b/headers/custom/custom.go deleted file mode 100644 index 752b33ec..00000000 --- a/headers/custom/custom.go +++ /dev/null @@ -1,54 +0,0 @@ -package custom - -import ( - "log" - "os" - "strings" - - "golang.org/x/sys/windows/registry" -) - -// GetSizeStoredInPagingFiles returns the total size of paging files across all discs. -func GetSizeStoredInPagingFiles() (int64, error) { - k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`, registry.QUERY_VALUE) - if err != nil { - return 0, err - } - pagingFiles, _, err := k.GetStringsValue("ExistingPageFiles") - if err != nil { - return 0, err - } - - var size int64 = 0 - for _, pagingFile := range pagingFiles { - fileString := strings.ReplaceAll(pagingFile, `\??\`, "") - file, err := os.Stat(fileString) - if err != nil { - return 0, err - } - size += file.Size() - } - return size, nil -} - -// GetProductDetails returns the ProductName and CurrentBuildNumber values from the registry. -func GetProductDetails() (string, string) { - k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) - if err != nil { - log.Fatal(err) - } - pn, _, err := k.GetStringValue("ProductName") - if err != nil { - log.Fatal(err) - } - - bn, _, err := k.GetStringValue("CurrentBuildNumber") - if err != nil { - log.Fatal(err) - } - - if err := k.Close(); err != nil { - log.Fatal(err) - } - return pn, bn -}