Fix timezone caching issues (#1499)

This commit is contained in:
Jan-Otto Kröpke 2024-06-14 08:58:58 +02:00 committed by GitHub
parent f0d0545d34
commit 1b438cdb82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 81 additions and 18 deletions

2
go.mod
View File

@ -1,6 +1,6 @@
module github.com/prometheus-community/windows_exporter
go 1.21
go 1.22
require (
github.com/Microsoft/hcsshim v0.12.4

View File

@ -8,16 +8,19 @@ import (
"os"
"strconv"
"strings"
"syscall"
"time"
"github.com/alecthomas/kingpin/v2"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus-community/windows_exporter/pkg/headers/kernel32"
"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/sysinfoapi"
"github.com/prometheus-community/windows_exporter/pkg/perflib"
"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"
"golang.org/x/sys/windows/registry"
)
@ -197,16 +200,36 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
}
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.
memManKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`, registry.QUERY_VALUE)
defer memManKey.Close()
if err != nil {
return err
}
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
ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
defer ntKey.Close()
@ -232,18 +255,6 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
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()
if err != nil {
return err

View 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
}