mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-03-06 02:26:36 +00:00
mscluster: restore support for Windows Server 2016-2019 (#1882)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
@@ -23,11 +23,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/Microsoft/hcsshim/osversion"
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"golang.org/x/sys/windows"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -157,19 +156,17 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
version := windows.RtlGetVersion()
|
|
||||||
|
|
||||||
subCollectors := map[string]struct {
|
subCollectors := map[string]struct {
|
||||||
build func() error
|
build func() error
|
||||||
collect func(ch chan<- prometheus.Metric) error
|
collect func(ch chan<- prometheus.Metric) error
|
||||||
close func()
|
close func()
|
||||||
minBuildNumber uint32
|
minBuildNumber uint16
|
||||||
}{
|
}{
|
||||||
subCollectorDataStore: {
|
subCollectorDataStore: {
|
||||||
build: c.buildDataStore,
|
build: c.buildDataStore,
|
||||||
collect: c.collectDataStore,
|
collect: c.collectDataStore,
|
||||||
close: c.perfDataCollectorDataStore.Close,
|
close: c.perfDataCollectorDataStore.Close,
|
||||||
minBuildNumber: types.BuildNumberWindowsServer2022,
|
minBuildNumber: osversion.LTSC2022,
|
||||||
},
|
},
|
||||||
subCollectorDynamicMemoryBalancer: {
|
subCollectorDynamicMemoryBalancer: {
|
||||||
build: c.buildDynamicMemoryBalancer,
|
build: c.buildDynamicMemoryBalancer,
|
||||||
@@ -243,6 +240,8 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildNumber := osversion.Build()
|
||||||
|
|
||||||
// Result must order, to prevent test failures.
|
// Result must order, to prevent test failures.
|
||||||
sort.Strings(c.config.CollectorsEnabled)
|
sort.Strings(c.config.CollectorsEnabled)
|
||||||
|
|
||||||
@@ -253,7 +252,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
return fmt.Errorf("unknown collector: %s", name)
|
return fmt.Errorf("unknown collector: %s", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if version.BuildNumber < subCollectors[name].minBuildNumber {
|
if buildNumber < subCollectors[name].minBuildNumber {
|
||||||
errs = append(errs, fmt.Errorf("collector %s requires Windows Server 2022 or newer", name))
|
errs = append(errs, fmt.Errorf("collector %s requires Windows Server 2022 or newer", name))
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package mscluster
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Microsoft/hcsshim/osversion"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
@@ -192,7 +193,14 @@ type msClusterCluster struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) buildCluster() error {
|
func (c *Collector) buildCluster() error {
|
||||||
clusterMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_Cluster")
|
buildNumber := osversion.Build()
|
||||||
|
|
||||||
|
wmiSelect := "AddEvictDelay,AdminAccessPoint,AutoAssignNodeSite,AutoBalancerLevel,AutoBalancerMode,BackupInProgress,BlockCacheSize,ClusSvcHangTimeout,ClusSvcRegroupOpeningTimeout,ClusSvcRegroupPruningTimeout,ClusSvcRegroupStageTimeout,ClusSvcRegroupTickInMilliseconds,ClusterEnforcedAntiAffinity,ClusterFunctionalLevel,ClusterGroupWaitDelay,ClusterLogLevel,ClusterLogSize,ClusterUpgradeVersion,CrossSiteDelay,CrossSiteThreshold,CrossSubnetDelay,CrossSubnetThreshold,CsvBalancer,DatabaseReadWriteMode,DefaultNetworkRole,DisableGroupPreferredOwnerRandomization,DrainOnShutdown,DynamicQuorumEnabled,EnableSharedVolumes,FixQuorum,GracePeriodEnabled,GracePeriodTimeout,GroupDependencyTimeout,HangRecoveryAction,IgnorePersistentStateOnStartup,LogResourceControls,LowerQuorumPriorityNodeId,MessageBufferLength,MinimumNeverPreemptPriority,MinimumPreemptorPriority,NetftIPSecEnabled,PlacementOptions,PlumbAllCrossSubnetRoutes,PreventQuorum,QuarantineDuration,QuarantineThreshold,QuorumArbitrationTimeMax,QuorumArbitrationTimeMin,QuorumLogFileSize,QuorumTypeValue,RequestReplyTimeout,ResiliencyDefaultPeriod,ResiliencyLevel,ResourceDllDeadlockPeriod,RootMemoryReserved,RouteHistoryLength,S2DBusTypes,S2DCacheDesiredState,S2DCacheFlashReservePercent,S2DCachePageSizeKBytes,S2DEnabled,S2DIOLatencyThreshold,S2DOptimizations,SameSubnetDelay,SameSubnetThreshold,SecurityLevel,SharedVolumeVssWriterOperationTimeout,ShutdownTimeoutInMinutes,UseClientAccessNetworksForSharedVolumes,WitnessDatabaseWriteTimeout,WitnessDynamicWeight,WitnessRestartInterval"
|
||||||
|
if buildNumber >= osversion.LTSC2022 {
|
||||||
|
wmiSelect += ",DetectManagedEvents,SecurityLevelForStorage,MaxNumberOfNodes,DetectManagedEventsThreshold,DetectedCloudPlatform"
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterMIQuery, err := mi.NewQuery(fmt.Sprintf("SELECT %s FROM MSCluster_Cluster", wmiSelect))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||||
}
|
}
|
||||||
@@ -852,27 +860,6 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
|||||||
v.Name,
|
v.Name,
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
c.clusterDetectedCloudPlatform,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
float64(v.DetectedCloudPlatform),
|
|
||||||
v.Name,
|
|
||||||
)
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
c.clusterDetectManagedEvents,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
float64(v.DetectManagedEvents),
|
|
||||||
v.Name,
|
|
||||||
)
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
c.clusterDetectManagedEventsThreshold,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
float64(v.DetectManagedEventsThreshold),
|
|
||||||
v.Name,
|
|
||||||
)
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.clusterDisableGroupPreferredOwnerRandomization,
|
c.clusterDisableGroupPreferredOwnerRandomization,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
@@ -957,13 +944,6 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
|||||||
v.Name,
|
v.Name,
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
c.clusterMaxNumberOfNodes,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
float64(v.MaxNumberOfNodes),
|
|
||||||
v.Name,
|
|
||||||
)
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.clusterMessageBufferLength,
|
c.clusterMessageBufferLength,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
@@ -1167,13 +1147,6 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
|||||||
v.Name,
|
v.Name,
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
c.clusterSecurityLevelForStorage,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
float64(v.SecurityLevelForStorage),
|
|
||||||
v.Name,
|
|
||||||
)
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.clusterSharedVolumeVssWriterOperationTimeout,
|
c.clusterSharedVolumeVssWriterOperationTimeout,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
@@ -1215,6 +1188,43 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
|||||||
float64(v.WitnessRestartInterval),
|
float64(v.WitnessRestartInterval),
|
||||||
v.Name,
|
v.Name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if osversion.Build() >= osversion.LTSC2022 {
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.clusterDetectManagedEvents,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(v.DetectManagedEvents),
|
||||||
|
v.Name,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.clusterDetectManagedEventsThreshold,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(v.DetectManagedEventsThreshold),
|
||||||
|
v.Name,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.clusterSecurityLevelForStorage,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(v.SecurityLevelForStorage),
|
||||||
|
v.Name,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.clusterMaxNumberOfNodes,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(v.MaxNumberOfNodes),
|
||||||
|
v.Name,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.clusterDetectedCloudPlatform,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(v.DetectedCloudPlatform),
|
||||||
|
v.Name,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ type msClusterNetwork struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) buildNetwork() error {
|
func (c *Collector) buildNetwork() error {
|
||||||
networkMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_Network")
|
networkMIQuery, err := mi.NewQuery("SELECT Characteristics,Flags,Metric,Role,State FROM MSCluster_Network")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package mscluster
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Microsoft/hcsshim/osversion"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
@@ -66,7 +67,14 @@ type msClusterNode struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) buildNode() error {
|
func (c *Collector) buildNode() error {
|
||||||
nodeMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_Node")
|
buildNumber := osversion.Build()
|
||||||
|
|
||||||
|
wmiSelect := "BuildNumber,Characteristics,DynamicWeight,Flags,MajorVersion,MinorVersion,NeedsPreventQuorum,NodeDrainStatus,NodeHighestVersion,NodeLowestVersion,NodeWeight,State,StatusInformation"
|
||||||
|
if buildNumber >= osversion.LTSC2022 {
|
||||||
|
wmiSelect += ",DetectedCloudPlatform"
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeMIQuery, err := mi.NewQuery(fmt.Sprintf("SELECT %s FROM MSCluster_Node", wmiSelect))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ type msClusterResource struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) buildResource() error {
|
func (c *Collector) buildResource() error {
|
||||||
resourceMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_Resource")
|
resourceMIQuery, err := mi.NewQuery("SELECT Name,Type,OwnerGroup,OwnerNode,Characteristics,DeadlockTimeout,EmbeddedFailureAction,Flags,IsAlivePollInterval,LooksAlivePollInterval,MonitorProcessId,PendingTimeout,ResourceClass,RestartAction,RestartDelay,RestartPeriod,RestartThreshold,RetryPeriodOnFailure,State,Subclass FROM MSCluster_Resource")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ type msClusterResourceGroup struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) buildResourceGroup() error {
|
func (c *Collector) buildResourceGroup() error {
|
||||||
resourceGroupMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_ResourceGroup")
|
resourceGroupMIQuery, err := mi.NewQuery("SELECT AutoFailbackType,Characteristics,ColdStartSetting,DefaultOwner,FailbackWindowEnd,FailbackWindowStart,FailoverPeriod,FailoverThreshold,Flags,GroupType,OwnerNode,Priority,ResiliencyPeriod,State FROM MSCluster_ResourceGroup")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,6 +138,10 @@ func (o *OperationUnmarshalCallbacks) InstanceResult(
|
|||||||
|
|
||||||
element, err := instance.GetElement(miTag)
|
element, err := instance.GetElement(miTag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, MI_RESULT_NO_SUCH_PROPERTY) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
o.errCh <- fmt.Errorf("failed to get element %s: %w", miTag, err)
|
o.errCh <- fmt.Errorf("failed to get element %s: %w", miTag, err)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -16,10 +16,5 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BuildNumberWindowsServer2025 uint32 = 26100
|
|
||||||
BuildNumberWindowsServer2022 uint32 = 20348
|
|
||||||
BuildNumberWindowsServer2019 uint32 = 17763
|
|
||||||
BuildNumberWindowsServer2016 uint32 = 14393
|
|
||||||
|
|
||||||
Namespace = "windows"
|
Namespace = "windows"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user