mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-24 21:56:36 +00:00
Fix timezone caching issues (#1499)
This commit is contained in:
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
|||||||
module github.com/prometheus-community/windows_exporter
|
module github.com/prometheus-community/windows_exporter
|
||||||
|
|
||||||
go 1.21
|
go 1.22
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Microsoft/hcsshim v0.12.4
|
github.com/Microsoft/hcsshim v0.12.4
|
||||||
|
|||||||
@@ -8,16 +8,19 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/prometheus-community/windows_exporter/pkg/headers/kernel32"
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/go-kit/log/level"
|
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/headers/netapi32"
|
"github.com/prometheus-community/windows_exporter/pkg/headers/netapi32"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/headers/psapi"
|
"github.com/prometheus-community/windows_exporter/pkg/headers/psapi"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/headers/sysinfoapi"
|
"github.com/prometheus-community/windows_exporter/pkg/headers/sysinfoapi"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
|
|
||||||
|
"github.com/alecthomas/kingpin/v2"
|
||||||
|
"github.com/go-kit/log"
|
||||||
|
"github.com/go-kit/log/level"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"golang.org/x/sys/windows/registry"
|
"golang.org/x/sys/windows/registry"
|
||||||
)
|
)
|
||||||
@@ -197,16 +200,36 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
timezoneName, _ := currentTime.Zone()
|
|
||||||
|
timeZoneInfo, err := kernel32.GetDynamicTimeZoneInformation()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// timeZoneKeyName contains the english name of the timezone.
|
||||||
|
timezoneName := syscall.UTF16ToString(timeZoneInfo.TimeZoneKeyName[:])
|
||||||
|
|
||||||
// Get total allocation of paging files across all disks.
|
// 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)
|
memManKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`, registry.QUERY_VALUE)
|
||||||
defer memManKey.Close()
|
defer memManKey.Close()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pagingFiles, _, pagingErr := memManKey.GetStringsValue("ExistingPageFiles")
|
pagingFiles, _, pagingErr := memManKey.GetStringsValue("ExistingPageFiles")
|
||||||
|
|
||||||
|
var fsipf float64
|
||||||
|
for _, pagingFile := range pagingFiles {
|
||||||
|
fileString := strings.ReplaceAll(pagingFile, `\??\`, "")
|
||||||
|
file, err := os.Stat(fileString)
|
||||||
|
// For unknown reasons, Windows doesn't always create a page file. Continue collection rather than aborting.
|
||||||
|
if err != nil {
|
||||||
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("Failed to read page file (reason: %s): %s\n", err, fileString))
|
||||||
|
} else {
|
||||||
|
fsipf += float64(file.Size())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get build number and product name from registry
|
// Get build number and product name from registry
|
||||||
ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
||||||
defer ntKey.Close()
|
defer ntKey.Close()
|
||||||
@@ -232,18 +255,6 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var fsipf float64
|
|
||||||
for _, pagingFile := range pagingFiles {
|
|
||||||
fileString := strings.ReplaceAll(pagingFile, `\??\`, "")
|
|
||||||
file, err := os.Stat(fileString)
|
|
||||||
// For unknown reasons, Windows doesn't always create a page file. Continue collection rather than aborting.
|
|
||||||
if err != nil {
|
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("Failed to read page file (reason: %s): %s\n", err, fileString))
|
|
||||||
} else {
|
|
||||||
fsipf += float64(file.Size())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gpi, err := psapi.GetPerformanceInfo()
|
gpi, err := psapi.GetPerformanceInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
52
pkg/headers/kernel32/kernel32.go
Normal file
52
pkg/headers/kernel32/kernel32.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package kernel32
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
|
||||||
|
procGetDynamicTimeZoneInformationSys = kernel32.NewProc("GetDynamicTimeZoneInformation")
|
||||||
|
)
|
||||||
|
|
||||||
|
// SYSTEMTIME contains a date and time.
|
||||||
|
// 📑 https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
|
||||||
|
type SYSTEMTIME struct {
|
||||||
|
WYear uint16
|
||||||
|
WMonth uint16
|
||||||
|
WDayOfWeek uint16
|
||||||
|
WDay uint16
|
||||||
|
WHour uint16
|
||||||
|
WMinute uint16
|
||||||
|
WSecond uint16
|
||||||
|
WMilliseconds uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// DynamicTimezoneInformation contains the current dynamic daylight time settings.
|
||||||
|
// 📑 https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/ns-timezoneapi-dynamic_time_zone_information
|
||||||
|
type DynamicTimezoneInformation struct {
|
||||||
|
Bias int32
|
||||||
|
standardName [32]uint16
|
||||||
|
StandardDate SYSTEMTIME
|
||||||
|
StandardBias int32
|
||||||
|
DaylightName [32]uint16
|
||||||
|
DaylightDate SYSTEMTIME
|
||||||
|
DaylightBias int32
|
||||||
|
TimeZoneKeyName [128]uint16
|
||||||
|
DynamicDaylightTimeDisabled uint8 // BOOLEAN
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDynamicTimeZoneInformation retrieves the current dynamic daylight time settings.
|
||||||
|
// 📑 https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-getdynamictimezoneinformation
|
||||||
|
func GetDynamicTimeZoneInformation() (DynamicTimezoneInformation, error) {
|
||||||
|
var tzi DynamicTimezoneInformation
|
||||||
|
|
||||||
|
r0, _, err := syscall.SyscallN(procGetDynamicTimeZoneInformationSys.Addr(), uintptr(unsafe.Pointer(&tzi)))
|
||||||
|
if uint32(r0) == 0xffffffff {
|
||||||
|
return tzi, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tzi, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user