Skip to content

Commit

Permalink
Refactor remaining sysinfoapi calls into header package
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Ridley <[email protected]>
  • Loading branch information
benridley committed Jan 20, 2021
1 parent e427acc commit fe4fcf5
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 117 deletions.
12 changes: 7 additions & 5 deletions collector/cs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package collector

import (
"github.com/prometheus-community/windows_exporter/sysinfoapi"
"github.com/prometheus-community/windows_exporter/headers/sysinfoapi"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
Expand Down Expand Up @@ -60,23 +60,25 @@ func (c *CSCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) e
}

func (c *CSCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
cs := sysinfoapi.GetNumLogicalProcessors()
// Get systeminfo for number of processors
systemInfo := sysinfoapi.GetSystemInfo()

pm, err := sysinfoapi.GetPhysicalMemory()
// Get memory status for physical memory
mem, err := sysinfoapi.GlobalMemoryStatusEx()
if err != nil {
return nil, err
}

ch <- prometheus.MustNewConstMetric(
c.LogicalProcessors,
prometheus.GaugeValue,
float64(cs),
float64(systemInfo.DwNumberOfProcessors),
)

ch <- prometheus.MustNewConstMetric(
c.PhysicalMemoryBytes,
prometheus.GaugeValue,
float64(pm),
float64(mem.UllTotalPhys),
)

hostname, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSHostname)
Expand Down
65 changes: 65 additions & 0 deletions headers/sysinfoapi/sysinfoapi.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sysinfoapi

import (
"unicode/utf16"
"unsafe"

"golang.org/x/sys/windows"
Expand All @@ -20,10 +21,49 @@ type MemoryStatusEx struct {
UllAvailExtendedVirtual uint64
}

// wProcessorArchitecture is a wrapper for the union found in LP_SYSTEM_INFO
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
type wProcessorArchitecture struct {
WReserved uint16
WProcessorArchitecture uint16
}

// LpSystemInfo is a wrapper for LPSYSTEM_INFO
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
type LpSystemInfo struct {
Arch wProcessorArchitecture
DwPageSize uint32
LpMinimumApplicationAddress *byte
LpMaximumApplicationAddress *byte
DwActiveProcessorMask *uint32
DwNumberOfProcessors uint32
DwProcessorType uint32
DwAllocationGranularity uint32
WProcessorLevel uint16
WProcessorRevision uint16
}

// WinComputerNameFormat is a wrapper for COMPUTER_NAME_FORMAT
type WinComputerNameFormat int

// Definitions for WinComputerNameFormat constants
const (
ComputerNameNetBIOS WinComputerNameFormat = iota
ComputerNameDNSHostname
ComputerNameDNSDomain
ComputerNameDNSFullyQualified
ComputerNamePhysicalNetBIOS
ComputerNamePhysicalDNSHostname
ComputerNamePhysicalDNSDomain
ComputerNamePhysicalDNSFullyQualified
ComputerNameMax
)

var (
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
procGetSystemInfo = kernel32.NewProc("GetSystemInfo")
procGlobalMemoryStatusEx = kernel32.NewProc("GlobalMemoryStatusEx")
procGetComputerNameExW = kernel32.NewProc("GetComputerNameExW")
)

// GlobalMemoryStatusEx retrieves information about the system's current usage of both physical and virtual memory.
Expand All @@ -41,3 +81,28 @@ func GlobalMemoryStatusEx() (MemoryStatusEx, error) {

return mse, nil
}

// GetSystemInfo wraps the GetSystemInfo function from sysinfoapi
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsysteminfo
func GetSystemInfo() LpSystemInfo {
var info LpSystemInfo
pInfo := uintptr(unsafe.Pointer(&info))
procGetSystemInfo.Call(pInfo)
return info
}

// GetComputerName wraps the GetComputerNameW function in a more Go-like way
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcomputernamew
func GetComputerName(f WinComputerNameFormat) (string, error) {
// 1kb buffer to accept computer name. This should be more than enough as the maximum size
// returned is the max length of a DNS name, which this author believes is 253 characters.
size := 1024
var buffer [4096]uint16
r1, _, err := procGetComputerNameExW.Call(uintptr(f), uintptr(unsafe.Pointer(&buffer)), uintptr(unsafe.Pointer(&size)))
if r1 == 0 {
return "", err
}
bytes := buffer[0:size]
out := utf16.Decode(bytes)
return string(out), nil
}
112 changes: 0 additions & 112 deletions sysinfoapi/sysinfoapi.go

This file was deleted.

0 comments on commit fe4fcf5

Please sign in to comment.