mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-08 05:56:37 +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"
|
||||
"sync"
|
||||
|
||||
"github.com/Microsoft/hcsshim/osversion"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -157,19 +156,17 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
version := windows.RtlGetVersion()
|
||||
|
||||
subCollectors := map[string]struct {
|
||||
build func() error
|
||||
collect func(ch chan<- prometheus.Metric) error
|
||||
close func()
|
||||
minBuildNumber uint32
|
||||
minBuildNumber uint16
|
||||
}{
|
||||
subCollectorDataStore: {
|
||||
build: c.buildDataStore,
|
||||
collect: c.collectDataStore,
|
||||
close: c.perfDataCollectorDataStore.Close,
|
||||
minBuildNumber: types.BuildNumberWindowsServer2022,
|
||||
minBuildNumber: osversion.LTSC2022,
|
||||
},
|
||||
subCollectorDynamicMemoryBalancer: {
|
||||
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.
|
||||
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)
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
continue
|
||||
|
||||
@@ -18,6 +18,7 @@ package mscluster
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/osversion"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@@ -192,7 +193,14 @@ type msClusterCluster struct {
|
||||
}
|
||||
|
||||
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 {
|
||||
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,
|
||||
)
|
||||
|
||||
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(
|
||||
c.clusterDisableGroupPreferredOwnerRandomization,
|
||||
prometheus.GaugeValue,
|
||||
@@ -957,13 +944,6 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterMaxNumberOfNodes,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.MaxNumberOfNodes),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterMessageBufferLength,
|
||||
prometheus.GaugeValue,
|
||||
@@ -1167,13 +1147,6 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterSecurityLevelForStorage,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.SecurityLevelForStorage),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterSharedVolumeVssWriterOperationTimeout,
|
||||
prometheus.GaugeValue,
|
||||
@@ -1215,6 +1188,43 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
||||
float64(v.WitnessRestartInterval),
|
||||
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
|
||||
|
||||
@@ -48,7 +48,7 @@ type msClusterNetwork struct {
|
||||
}
|
||||
|
||||
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 {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package mscluster
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/osversion"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@@ -66,7 +67,14 @@ type msClusterNode struct {
|
||||
}
|
||||
|
||||
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 {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ type msClusterResource struct {
|
||||
}
|
||||
|
||||
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 {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ type msClusterResourceGroup struct {
|
||||
}
|
||||
|
||||
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 {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
@@ -138,6 +138,10 @@ func (o *OperationUnmarshalCallbacks) InstanceResult(
|
||||
|
||||
element, err := instance.GetElement(miTag)
|
||||
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)
|
||||
|
||||
return 0
|
||||
|
||||
@@ -16,10 +16,5 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
BuildNumberWindowsServer2025 uint32 = 26100
|
||||
BuildNumberWindowsServer2022 uint32 = 20348
|
||||
BuildNumberWindowsServer2019 uint32 = 17763
|
||||
BuildNumberWindowsServer2016 uint32 = 14393
|
||||
|
||||
Namespace = "windows"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user