mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-08 05:56:37 +00:00
mscluster: merge multiple collector into one (Click here for more information) (#1585)
This commit is contained in:
@@ -29,11 +29,7 @@ import (
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logon"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_cluster"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_network"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_node"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_resource"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_resourcegroup"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/msmq"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mssql"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/net"
|
||||
@@ -111,11 +107,7 @@ func NewWithConfig(config Config) Collectors {
|
||||
collectors[logical_disk.Name] = logical_disk.New(&config.LogicalDisk)
|
||||
collectors[logon.Name] = logon.New(&config.Logon)
|
||||
collectors[memory.Name] = memory.New(&config.Memory)
|
||||
collectors[mscluster_cluster.Name] = mscluster_cluster.New(&config.MsclusterCluster)
|
||||
collectors[mscluster_network.Name] = mscluster_network.New(&config.MsclusterNetwork)
|
||||
collectors[mscluster_node.Name] = mscluster_node.New(&config.MsclusterNode)
|
||||
collectors[mscluster_resource.Name] = mscluster_resource.New(&config.MsclusterResource)
|
||||
collectors[mscluster_resourcegroup.Name] = mscluster_resourcegroup.New(&config.MsclusterResourceGroup)
|
||||
collectors[mscluster.Name] = mscluster.New(&config.Mscluster)
|
||||
collectors[msmq.Name] = msmq.New(&config.Msmq)
|
||||
collectors[mssql.Name] = mssql.New(&config.Mssql)
|
||||
collectors[net.Name] = net.New(&config.Net)
|
||||
|
||||
@@ -21,11 +21,7 @@ import (
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logon"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_cluster"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_network"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_node"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_resource"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_resourcegroup"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/msmq"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mssql"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/net"
|
||||
@@ -80,11 +76,7 @@ type Config struct {
|
||||
LogicalDisk logical_disk.Config `yaml:"logical_disk"`
|
||||
Logon logon.Config `yaml:"logon"`
|
||||
Memory memory.Config `yaml:"memory"`
|
||||
MsclusterCluster mscluster_cluster.Config `yaml:"mscluster_cluster"`
|
||||
MsclusterNetwork mscluster_network.Config `yaml:"mscluster_network"`
|
||||
MsclusterNode mscluster_node.Config `yaml:"mscluster_node"`
|
||||
MsclusterResource mscluster_resource.Config `yaml:"mscluster_resource"`
|
||||
MsclusterResourceGroup mscluster_resourcegroup.Config `yaml:"mscluster_resourcegroup"` //nolint:tagliatelle
|
||||
Mscluster mscluster.Config `yaml:"mscluster"`
|
||||
Msmq msmq.Config `yaml:"msmq"`
|
||||
Mssql mssql.Config `yaml:"mssql"`
|
||||
Net net.Config `yaml:"net"`
|
||||
@@ -142,11 +134,7 @@ var ConfigDefaults = Config{
|
||||
LogicalDisk: logical_disk.ConfigDefaults,
|
||||
Logon: logon.ConfigDefaults,
|
||||
Memory: memory.ConfigDefaults,
|
||||
MsclusterCluster: mscluster_cluster.ConfigDefaults,
|
||||
MsclusterNetwork: mscluster_network.ConfigDefaults,
|
||||
MsclusterNode: mscluster_node.ConfigDefaults,
|
||||
MsclusterResource: mscluster_resource.ConfigDefaults,
|
||||
MsclusterResourceGroup: mscluster_resourcegroup.ConfigDefaults,
|
||||
Mscluster: mscluster.ConfigDefaults,
|
||||
Msmq: msmq.ConfigDefaults,
|
||||
Mssql: mssql.ConfigDefaults,
|
||||
Net: net.ConfigDefaults,
|
||||
|
||||
@@ -5,7 +5,6 @@ package exchange
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
@@ -78,8 +77,6 @@ type Collector struct {
|
||||
unreachableQueueLength *prometheus.Desc
|
||||
userCount *prometheus.Desc
|
||||
yieldedTasks *prometheus.Desc
|
||||
|
||||
enabledCollectors []string
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
@@ -229,18 +226,6 @@ func (c *Collector) Build(_ log.Logger) error {
|
||||
c.syncCommandsPerSec = desc("activesync_sync_cmds_total", "Number of sync commands processed per second. Clients use this command to synchronize items within a folder")
|
||||
c.activeUserCountMapiHttpEmsMDB = desc("mapihttp_emsmdb_active_user_count", "Number of unique outlook users that have shown some kind of activity in the last 2 minutes")
|
||||
|
||||
c.enabledCollectors = make([]string, 0, len(ConfigDefaults.CollectorsEnabled))
|
||||
|
||||
for _, collectorName := range c.config.CollectorsEnabled {
|
||||
if !slices.Contains(ConfigDefaults.CollectorsEnabled, collectorName) {
|
||||
return fmt.Errorf("unknown exchange collector: %s", collectorName)
|
||||
}
|
||||
|
||||
c.enabledCollectors = append(c.enabledCollectors, collectorName)
|
||||
}
|
||||
|
||||
c.enabledCollectors = slices.Clip(c.enabledCollectors)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -260,7 +245,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, logger log.Logger, ch chan
|
||||
"MapiHttpEmsmdb": c.collectMapiHttpEmsmdb,
|
||||
}
|
||||
|
||||
for _, collectorName := range c.enabledCollectors {
|
||||
for _, collectorName := range c.config.CollectorsEnabled {
|
||||
if err := collectorFuncs[collectorName](ctx, logger, ch); err != nil {
|
||||
_ = level.Error(logger).Log("msg", "Error in "+collectorName, "err", err)
|
||||
return err
|
||||
|
||||
@@ -21,11 +21,7 @@ import (
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logon"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_cluster"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_network"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_node"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_resource"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_resourcegroup"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/msmq"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mssql"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/net"
|
||||
@@ -81,11 +77,7 @@ var BuildersWithFlags = map[string]BuilderWithFlags[Collector]{
|
||||
logical_disk.Name: NewBuilderWithFlags(logical_disk.NewWithFlags),
|
||||
logon.Name: NewBuilderWithFlags(logon.NewWithFlags),
|
||||
memory.Name: NewBuilderWithFlags(memory.NewWithFlags),
|
||||
mscluster_cluster.Name: NewBuilderWithFlags(mscluster_cluster.NewWithFlags),
|
||||
mscluster_network.Name: NewBuilderWithFlags(mscluster_network.NewWithFlags),
|
||||
mscluster_node.Name: NewBuilderWithFlags(mscluster_node.NewWithFlags),
|
||||
mscluster_resource.Name: NewBuilderWithFlags(mscluster_resource.NewWithFlags),
|
||||
mscluster_resourcegroup.Name: NewBuilderWithFlags(mscluster_resourcegroup.NewWithFlags),
|
||||
mscluster.Name: NewBuilderWithFlags(mscluster.NewWithFlags),
|
||||
msmq.Name: NewBuilderWithFlags(msmq.NewWithFlags),
|
||||
mssql.Name: NewBuilderWithFlags(mssql.NewWithFlags),
|
||||
net.Name: NewBuilderWithFlags(net.NewWithFlags),
|
||||
|
||||
299
pkg/collector/mscluster/mscluster.go
Normal file
299
pkg/collector/mscluster/mscluster.go
Normal file
@@ -0,0 +1,299 @@
|
||||
package mscluster
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "mscluster"
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
}
|
||||
|
||||
var ConfigDefaults = Config{
|
||||
CollectorsEnabled: []string{
|
||||
"cluster",
|
||||
"network",
|
||||
"node",
|
||||
"resource",
|
||||
"resourcegroup",
|
||||
},
|
||||
}
|
||||
|
||||
// A Collector is a Prometheus Collector for WMI MSCluster_Cluster metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
// cluster
|
||||
clusterAddEvictDelay *prometheus.Desc
|
||||
clusterAdminAccessPoint *prometheus.Desc
|
||||
clusterAutoAssignNodeSite *prometheus.Desc
|
||||
clusterAutoBalancerLevel *prometheus.Desc
|
||||
clusterAutoBalancerMode *prometheus.Desc
|
||||
clusterBackupInProgress *prometheus.Desc
|
||||
clusterBlockCacheSize *prometheus.Desc
|
||||
clusterClusSvcHangTimeout *prometheus.Desc
|
||||
clusterClusSvcRegroupOpeningTimeout *prometheus.Desc
|
||||
clusterClusSvcRegroupPruningTimeout *prometheus.Desc
|
||||
clusterClusSvcRegroupStageTimeout *prometheus.Desc
|
||||
clusterClusSvcRegroupTickInMilliseconds *prometheus.Desc
|
||||
clusterClusterEnforcedAntiAffinity *prometheus.Desc
|
||||
clusterClusterFunctionalLevel *prometheus.Desc
|
||||
clusterClusterGroupWaitDelay *prometheus.Desc
|
||||
clusterClusterLogLevel *prometheus.Desc
|
||||
clusterClusterLogSize *prometheus.Desc
|
||||
clusterClusterUpgradeVersion *prometheus.Desc
|
||||
clusterCrossSiteDelay *prometheus.Desc
|
||||
clusterCrossSiteThreshold *prometheus.Desc
|
||||
clusterCrossSubnetDelay *prometheus.Desc
|
||||
clusterCrossSubnetThreshold *prometheus.Desc
|
||||
clusterCsvBalancer *prometheus.Desc
|
||||
clusterDatabaseReadWriteMode *prometheus.Desc
|
||||
clusterDefaultNetworkRole *prometheus.Desc
|
||||
clusterDetectedCloudPlatform *prometheus.Desc
|
||||
clusterDetectManagedEvents *prometheus.Desc
|
||||
clusterDetectManagedEventsThreshold *prometheus.Desc
|
||||
clusterDisableGroupPreferredOwnerRandomization *prometheus.Desc
|
||||
clusterDrainOnShutdown *prometheus.Desc
|
||||
clusterDynamicQuorumEnabled *prometheus.Desc
|
||||
clusterEnableSharedVolumes *prometheus.Desc
|
||||
clusterFixQuorum *prometheus.Desc
|
||||
clusterGracePeriodEnabled *prometheus.Desc
|
||||
clusterGracePeriodTimeout *prometheus.Desc
|
||||
clusterGroupDependencyTimeout *prometheus.Desc
|
||||
clusterHangRecoveryAction *prometheus.Desc
|
||||
clusterIgnorePersistentStateOnStartup *prometheus.Desc
|
||||
clusterLogResourceControls *prometheus.Desc
|
||||
clusterLowerQuorumPriorityNodeId *prometheus.Desc
|
||||
clusterMaxNumberOfNodes *prometheus.Desc
|
||||
clusterMessageBufferLength *prometheus.Desc
|
||||
clusterMinimumNeverPreemptPriority *prometheus.Desc
|
||||
clusterMinimumPreemptorPriority *prometheus.Desc
|
||||
clusterNetftIPSecEnabled *prometheus.Desc
|
||||
clusterPlacementOptions *prometheus.Desc
|
||||
clusterPlumbAllCrossSubnetRoutes *prometheus.Desc
|
||||
clusterPreventQuorum *prometheus.Desc
|
||||
clusterQuarantineDuration *prometheus.Desc
|
||||
clusterQuarantineThreshold *prometheus.Desc
|
||||
clusterQuorumArbitrationTimeMax *prometheus.Desc
|
||||
clusterQuorumArbitrationTimeMin *prometheus.Desc
|
||||
clusterQuorumLogFileSize *prometheus.Desc
|
||||
clusterQuorumTypeValue *prometheus.Desc
|
||||
clusterRequestReplyTimeout *prometheus.Desc
|
||||
clusterResiliencyDefaultPeriod *prometheus.Desc
|
||||
clusterResiliencyLevel *prometheus.Desc
|
||||
clusterResourceDllDeadlockPeriod *prometheus.Desc
|
||||
clusterRootMemoryReserved *prometheus.Desc
|
||||
clusterRouteHistoryLength *prometheus.Desc
|
||||
clusterS2DBusTypes *prometheus.Desc
|
||||
clusterS2DCacheDesiredState *prometheus.Desc
|
||||
clusterS2DCacheFlashReservePercent *prometheus.Desc
|
||||
clusterS2DCachePageSizeKBytes *prometheus.Desc
|
||||
clusterS2DEnabled *prometheus.Desc
|
||||
clusterS2DIOLatencyThreshold *prometheus.Desc
|
||||
clusterS2DOptimizations *prometheus.Desc
|
||||
clusterSameSubnetDelay *prometheus.Desc
|
||||
clusterSameSubnetThreshold *prometheus.Desc
|
||||
clusterSecurityLevel *prometheus.Desc
|
||||
clusterSecurityLevelForStorage *prometheus.Desc
|
||||
clusterSharedVolumeVssWriterOperationTimeout *prometheus.Desc
|
||||
clusterShutdownTimeoutInMinutes *prometheus.Desc
|
||||
clusterUseClientAccessNetworksForSharedVolumes *prometheus.Desc
|
||||
clusterWitnessDatabaseWriteTimeout *prometheus.Desc
|
||||
clusterWitnessDynamicWeight *prometheus.Desc
|
||||
clusterWitnessRestartInterval *prometheus.Desc
|
||||
|
||||
// network
|
||||
networkCharacteristics *prometheus.Desc
|
||||
networkFlags *prometheus.Desc
|
||||
networkMetric *prometheus.Desc
|
||||
networkRole *prometheus.Desc
|
||||
networkState *prometheus.Desc
|
||||
|
||||
// node
|
||||
nodeBuildNumber *prometheus.Desc
|
||||
nodeCharacteristics *prometheus.Desc
|
||||
nodeDetectedCloudPlatform *prometheus.Desc
|
||||
nodeDynamicWeight *prometheus.Desc
|
||||
nodeFlags *prometheus.Desc
|
||||
nodeMajorVersion *prometheus.Desc
|
||||
nodeMinorVersion *prometheus.Desc
|
||||
nodeNeedsPreventQuorum *prometheus.Desc
|
||||
nodeNodeDrainStatus *prometheus.Desc
|
||||
nodeNodeHighestVersion *prometheus.Desc
|
||||
nodeNodeLowestVersion *prometheus.Desc
|
||||
nodeNodeWeight *prometheus.Desc
|
||||
nodeState *prometheus.Desc
|
||||
nodeStatusInformation *prometheus.Desc
|
||||
|
||||
resourceCharacteristics *prometheus.Desc
|
||||
resourceDeadlockTimeout *prometheus.Desc
|
||||
resourceEmbeddedFailureAction *prometheus.Desc
|
||||
resourceFlags *prometheus.Desc
|
||||
resourceIsAlivePollInterval *prometheus.Desc
|
||||
resourceLooksAlivePollInterval *prometheus.Desc
|
||||
resourceMonitorProcessId *prometheus.Desc
|
||||
resourceOwnerNode *prometheus.Desc
|
||||
resourcePendingTimeout *prometheus.Desc
|
||||
resourceResourceClass *prometheus.Desc
|
||||
resourceRestartAction *prometheus.Desc
|
||||
resourceRestartDelay *prometheus.Desc
|
||||
resourceRestartPeriod *prometheus.Desc
|
||||
resourceRestartThreshold *prometheus.Desc
|
||||
resourceRetryPeriodOnFailure *prometheus.Desc
|
||||
resourceState *prometheus.Desc
|
||||
resourceSubClass *prometheus.Desc
|
||||
|
||||
// ResourceGroup
|
||||
resourceGroupAutoFailbackType *prometheus.Desc
|
||||
resourceGroupCharacteristics *prometheus.Desc
|
||||
resourceGroupColdStartSetting *prometheus.Desc
|
||||
resourceGroupDefaultOwner *prometheus.Desc
|
||||
resourceGroupFailbackWindowEnd *prometheus.Desc
|
||||
resourceGroupFailbackWindowStart *prometheus.Desc
|
||||
resourceGroupFailOverPeriod *prometheus.Desc
|
||||
resourceGroupFailOverThreshold *prometheus.Desc
|
||||
resourceGroupFlags *prometheus.Desc
|
||||
resourceGroupGroupType *prometheus.Desc
|
||||
resourceGroupOwnerNode *prometheus.Desc
|
||||
resourceGroupPriority *prometheus.Desc
|
||||
resourceGroupResiliencyPeriod *prometheus.Desc
|
||||
resourceGroupState *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
if config.CollectorsEnabled == nil {
|
||||
config.CollectorsEnabled = ConfigDefaults.CollectorsEnabled
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(app *kingpin.Application) *Collector {
|
||||
c := &Collector{
|
||||
config: ConfigDefaults,
|
||||
}
|
||||
c.config.CollectorsEnabled = make([]string, 0)
|
||||
|
||||
var collectorsEnabled string
|
||||
|
||||
app.Flag(
|
||||
"collectors.mscluster.enabled",
|
||||
"Comma-separated list of collectors to use.",
|
||||
).Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
|
||||
|
||||
app.Action(func(*kingpin.ParseContext) error {
|
||||
c.config.CollectorsEnabled = strings.Split(collectorsEnabled, ",")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ log.Logger) ([]string, error) {
|
||||
return []string{"Memory"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ log.Logger) error {
|
||||
if len(c.config.CollectorsEnabled) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "cluster") {
|
||||
c.buildCluster()
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "network") {
|
||||
c.buildNetwork()
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "node") {
|
||||
c.buildNode()
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "resource") {
|
||||
c.buildResource()
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "resourcegroup") {
|
||||
c.buildResourceGroup()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger log.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = log.With(logger, "collector", Name)
|
||||
if len(c.config.CollectorsEnabled) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
errs []error
|
||||
nodeNames []string
|
||||
)
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "cluster") {
|
||||
if err = c.collectCluster(logger, ch); err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to collect cluster metrics: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "network") {
|
||||
if err = c.collectNetwork(logger, ch); err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to collect network metrics: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "node") {
|
||||
if nodeNames, err = c.collectNode(logger, ch); err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to collect node metrics: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "resource") {
|
||||
if err = c.collectResource(logger, ch, nodeNames); err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to collect resource metrics: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "resourcegroup") {
|
||||
if err = c.collectResourceGroup(logger, ch, nodeNames); err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to collect resource group metrics: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,95 +1,17 @@
|
||||
package mscluster_network
|
||||
package mscluster
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "mscluster_network"
|
||||
const nameNetwork = Name + "_network"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A Collector is a Prometheus Collector for WMI MSCluster_Network metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
characteristics *prometheus.Desc
|
||||
flags *prometheus.Desc
|
||||
metric *prometheus.Desc
|
||||
role *prometheus.Desc
|
||||
state *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(_ *kingpin.Application) *Collector {
|
||||
return &Collector{}
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ log.Logger) ([]string, error) {
|
||||
return []string{"Memory"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ log.Logger) error {
|
||||
c.characteristics = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "characteristics"),
|
||||
"Provides the characteristics of the network.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.flags = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "flags"),
|
||||
"Provides access to the flags set for the node. ",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.metric = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "metric"),
|
||||
"The metric of a cluster network (networks with lower values are used first). If this value is set, then the AutoMetric property is set to false.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.role = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "role"),
|
||||
"Provides access to the network's Role property. The Role property describes the role of the network in the cluster. 0: None; 1: Cluster; 2: Client; 3: Both ",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.state = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "state"),
|
||||
"Provides the current state of the network. 1-1: Unknown; 0: Unavailable; 1: Down; 2: Partitioned; 3: Up",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MSCluster_Network docs:
|
||||
// msClusterNetwork represents the MSCluster_Network WMI class
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-network
|
||||
type MSCluster_Network struct {
|
||||
type msClusterNetwork struct {
|
||||
Name string
|
||||
|
||||
Characteristics uint
|
||||
@@ -99,47 +21,80 @@ type MSCluster_Network struct {
|
||||
State uint
|
||||
}
|
||||
|
||||
func (c *Collector) buildNetwork() {
|
||||
c.networkCharacteristics = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNetwork, "characteristics"),
|
||||
"Provides the characteristics of the network.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.networkFlags = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNetwork, "flags"),
|
||||
"Provides access to the flags set for the node. ",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.networkMetric = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNetwork, "metric"),
|
||||
"The metric of a cluster network (networks with lower values are used first). If this value is set, then the AutoMetric property is set to false.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.networkRole = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNetwork, "role"),
|
||||
"Provides access to the network's Role property. The Role property describes the role of the network in the cluster. 0: None; 1: Cluster; 2: Client; 3: Both ",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.networkState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNetwork, "state"),
|
||||
"Provides the current state of the network. 1-1: Unknown; 0: Unavailable; 1: Down; 2: Partitioned; 3: Up",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger log.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = log.With(logger, "collector", Name)
|
||||
var dst []MSCluster_Network
|
||||
q := wmi.QueryAll(&dst, logger)
|
||||
func (c *Collector) collectNetwork(logger log.Logger, ch chan<- prometheus.Metric) error {
|
||||
var dst []msClusterNetwork
|
||||
|
||||
q := wmi.QueryAllForClass(&dst, "MSCluster_Network", logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range dst {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.characteristics,
|
||||
c.networkCharacteristics,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Characteristics),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.flags,
|
||||
c.networkFlags,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Flags),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.metric,
|
||||
c.networkMetric,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Metric),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.role,
|
||||
c.networkRole,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Role),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.state,
|
||||
c.networkState,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.State),
|
||||
v.Name,
|
||||
@@ -1,161 +1,17 @@
|
||||
package mscluster_node
|
||||
package mscluster
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "mscluster_node"
|
||||
const nameNode = Name + "_node"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// Variable used by mscluster_resource and mscluster_resourcegroup.
|
||||
var NodeName []string
|
||||
|
||||
// A Collector is a Prometheus Collector for WMI MSCluster_Node metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
buildNumber *prometheus.Desc
|
||||
characteristics *prometheus.Desc
|
||||
detectedCloudPlatform *prometheus.Desc
|
||||
dynamicWeight *prometheus.Desc
|
||||
flags *prometheus.Desc
|
||||
majorVersion *prometheus.Desc
|
||||
minorVersion *prometheus.Desc
|
||||
needsPreventQuorum *prometheus.Desc
|
||||
nodeDrainStatus *prometheus.Desc
|
||||
nodeHighestVersion *prometheus.Desc
|
||||
nodeLowestVersion *prometheus.Desc
|
||||
nodeWeight *prometheus.Desc
|
||||
state *prometheus.Desc
|
||||
statusInformation *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(_ *kingpin.Application) *Collector {
|
||||
return &Collector{}
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ log.Logger) ([]string, error) {
|
||||
return []string{"Memory"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ log.Logger) error {
|
||||
c.buildNumber = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "build_number"),
|
||||
"Provides access to the node's BuildNumber property.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.characteristics = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "characteristics"),
|
||||
"Provides access to the characteristics set for the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.detectedCloudPlatform = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "detected_cloud_platform"),
|
||||
"(DetectedCloudPlatform)",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.dynamicWeight = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dynamic_weight"),
|
||||
"The dynamic vote weight of the node adjusted by dynamic quorum feature.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.flags = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "flags"),
|
||||
"Provides access to the flags set for the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.majorVersion = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "major_version"),
|
||||
"Provides access to the node's MajorVersion property, which specifies the major portion of the Windows version installed.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.minorVersion = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "minor_version"),
|
||||
"Provides access to the node's MinorVersion property, which specifies the minor portion of the Windows version installed.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.needsPreventQuorum = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "needs_prevent_quorum"),
|
||||
"Whether the cluster service on that node should be started with prevent quorum flag.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeDrainStatus = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "node_drain_status"),
|
||||
"The current node drain status of a node. 0: Not Initiated; 1: In Progress; 2: Completed; 3: Failed",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeHighestVersion = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "node_highest_version"),
|
||||
"Provides access to the node's NodeHighestVersion property, which specifies the highest possible version of the cluster service with which the node can join or communicate.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeLowestVersion = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "node_lowest_version"),
|
||||
"Provides access to the node's NodeLowestVersion property, which specifies the lowest possible version of the cluster service with which the node can join or communicate.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeWeight = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "node_weight"),
|
||||
"The vote weight of the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.state = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "state"),
|
||||
"Returns the current state of a node. -1: Unknown; 0: Up; 1: Down; 2: Paused; 3: Joining",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.statusInformation = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "status_information"),
|
||||
"The isolation or quarantine status of the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MSCluster_Node docs:
|
||||
// msClusterNode represents the MSCluster_Node WMI class
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-node
|
||||
type MSCluster_Node struct {
|
||||
type msClusterNode struct {
|
||||
Name string
|
||||
|
||||
BuildNumber uint
|
||||
@@ -174,119 +30,206 @@ type MSCluster_Node struct {
|
||||
StatusInformation uint
|
||||
}
|
||||
|
||||
func (c *Collector) buildNode() {
|
||||
c.nodeBuildNumber = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "build_number"),
|
||||
"Provides access to the node's BuildNumber property.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeCharacteristics = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "characteristics"),
|
||||
"Provides access to the characteristics set for the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeDetectedCloudPlatform = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "detected_cloud_platform"),
|
||||
"(DetectedCloudPlatform)",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeDynamicWeight = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "dynamic_weight"),
|
||||
"The dynamic vote weight of the node adjusted by dynamic quorum feature.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeFlags = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "flags"),
|
||||
"Provides access to the flags set for the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeMajorVersion = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "major_version"),
|
||||
"Provides access to the node's MajorVersion property, which specifies the major portion of the Windows version installed.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeMinorVersion = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "minor_version"),
|
||||
"Provides access to the node's MinorVersion property, which specifies the minor portion of the Windows version installed.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeNeedsPreventQuorum = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "needs_prevent_quorum"),
|
||||
"Whether the cluster service on that node should be started with prevent quorum flag.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeNodeDrainStatus = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "node_drain_status"),
|
||||
"The current node drain status of a node. 0: Not Initiated; 1: In Progress; 2: Completed; 3: Failed",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeNodeHighestVersion = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "node_highest_version"),
|
||||
"Provides access to the node's NodeHighestVersion property, which specifies the highest possible version of the cluster service with which the node can join or communicate.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeNodeLowestVersion = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "node_lowest_version"),
|
||||
"Provides access to the node's NodeLowestVersion property, which specifies the lowest possible version of the cluster service with which the node can join or communicate.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeNodeWeight = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "node_weight"),
|
||||
"The vote weight of the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "state"),
|
||||
"Returns the current state of a node. -1: Unknown; 0: Up; 1: Down; 2: Paused; 3: Joining",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.nodeStatusInformation = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameNode, "status_information"),
|
||||
"The isolation or quarantine status of the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger log.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = log.With(logger, "collector", Name)
|
||||
var dst []MSCluster_Node
|
||||
q := wmi.QueryAll(&dst, logger)
|
||||
func (c *Collector) collectNode(logger log.Logger, ch chan<- prometheus.Metric) ([]string, error) {
|
||||
var dst []msClusterNode
|
||||
|
||||
q := wmi.QueryAllForClass(&dst, "MSCluster_Node", logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
NodeName = []string{}
|
||||
nodeNames := make([]string, 0, len(dst))
|
||||
|
||||
for _, v := range dst {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.buildNumber,
|
||||
c.nodeBuildNumber,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.BuildNumber),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.characteristics,
|
||||
c.nodeCharacteristics,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Characteristics),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.detectedCloudPlatform,
|
||||
c.nodeDetectedCloudPlatform,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DetectedCloudPlatform),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicWeight,
|
||||
c.nodeDynamicWeight,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DynamicWeight),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.flags,
|
||||
c.nodeFlags,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Flags),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.majorVersion,
|
||||
c.nodeMajorVersion,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.MajorVersion),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.minorVersion,
|
||||
c.nodeMinorVersion,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.MinorVersion),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.needsPreventQuorum,
|
||||
c.nodeNeedsPreventQuorum,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NeedsPreventQuorum),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.nodeDrainStatus,
|
||||
c.nodeNodeDrainStatus,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NodeDrainStatus),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.nodeHighestVersion,
|
||||
c.nodeNodeHighestVersion,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NodeHighestVersion),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.nodeLowestVersion,
|
||||
c.nodeNodeLowestVersion,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NodeLowestVersion),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.nodeWeight,
|
||||
c.nodeNodeWeight,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NodeWeight),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.state,
|
||||
c.nodeState,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.State),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.statusInformation,
|
||||
c.nodeStatusInformation,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.StatusInformation),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
NodeName = append(NodeName, v.Name)
|
||||
nodeNames = append(nodeNames, v.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
return nodeNames, nil
|
||||
}
|
||||
@@ -1,186 +1,17 @@
|
||||
package mscluster_resource
|
||||
package mscluster
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_node"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "mscluster_resource"
|
||||
const nameResource = Name + "_resource"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A Collector is a Prometheus Collector for WMI MSCluster_Resource metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
characteristics *prometheus.Desc
|
||||
deadlockTimeout *prometheus.Desc
|
||||
embeddedFailureAction *prometheus.Desc
|
||||
flags *prometheus.Desc
|
||||
isAlivePollInterval *prometheus.Desc
|
||||
looksAlivePollInterval *prometheus.Desc
|
||||
monitorProcessId *prometheus.Desc
|
||||
ownerNode *prometheus.Desc
|
||||
pendingTimeout *prometheus.Desc
|
||||
resourceClass *prometheus.Desc
|
||||
restartAction *prometheus.Desc
|
||||
restartDelay *prometheus.Desc
|
||||
restartPeriod *prometheus.Desc
|
||||
restartThreshold *prometheus.Desc
|
||||
retryPeriodOnFailure *prometheus.Desc
|
||||
state *prometheus.Desc
|
||||
subclass *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(_ *kingpin.Application) *Collector {
|
||||
return &Collector{}
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ log.Logger) ([]string, error) {
|
||||
return []string{"Memory"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ log.Logger) error {
|
||||
c.characteristics = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "characteristics"),
|
||||
"Provides the characteristics of the object.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.deadlockTimeout = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "deadlock_timeout"),
|
||||
"Indicates the length of time to wait, in milliseconds, before declaring a deadlock in any call into a resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.embeddedFailureAction = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "embedded_failure_action"),
|
||||
"The time, in milliseconds, that a resource should remain in a failed state before the Cluster service attempts to restart it.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.flags = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "flags"),
|
||||
"Provides access to the flags set for the object.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.isAlivePollInterval = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "is_alive_poll_interval"),
|
||||
"Provides access to the resource's IsAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it is operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the IsAlivePollInterval property for the resource type associated with the resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.looksAlivePollInterval = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "looks_alive_poll_interval"),
|
||||
"Provides access to the resource's LooksAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it appears operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the LooksAlivePollInterval property for the resource type associated with the resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.monitorProcessId = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "monitor_process_id"),
|
||||
"Provides the process ID of the resource host service that is currently hosting the resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.ownerNode = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "owner_node"),
|
||||
"The node hosting the resource. 0: Not hosted; 1: Hosted",
|
||||
[]string{"type", "owner_group", "node_name", "name"},
|
||||
nil,
|
||||
)
|
||||
c.ownerNode = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "owner_node"),
|
||||
"The node hosting the resource. 0: Not hosted; 1: Hosted",
|
||||
[]string{"type", "owner_group", "node_name", "name"},
|
||||
nil,
|
||||
)
|
||||
c.pendingTimeout = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "pending_timeout"),
|
||||
"Provides access to the resource's PendingTimeout property. If a resource cannot be brought online or taken offline in the number of milliseconds specified by the PendingTimeout property, the resource is forcibly terminated.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceClass = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "resource_class"),
|
||||
"Gets or sets the resource class of a resource. 0: Unknown; 1: Storage; 2: Network; 32768: Unknown ",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.restartAction = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "restart_action"),
|
||||
"Provides access to the resource's RestartAction property, which is the action to be taken by the Cluster Service if the resource fails.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.restartDelay = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "restart_delay"),
|
||||
"Indicates the time delay before a failed resource is restarted.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.restartPeriod = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "restart_period"),
|
||||
"Provides access to the resource's RestartPeriod property, which is interval of time, in milliseconds, during which a specified number of restart attempts can be made on a nonresponsive resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.restartThreshold = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "restart_threshold"),
|
||||
"Provides access to the resource's RestartThreshold property which is the maximum number of restart attempts that can be made on a resource within an interval defined by the RestartPeriod property before the Cluster Service initiates the action specified by the RestartAction property.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.retryPeriodOnFailure = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "retry_period_on_failure"),
|
||||
"Provides access to the resource's RetryPeriodOnFailure property, which is the interval of time (in milliseconds) that a resource should remain in a failed state before the Cluster service attempts to restart it.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.state = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "state"),
|
||||
"The current state of the resource. -1: Unknown; 0: Inherited; 1: Initializing; 2: Online; 3: Offline; 4: Failed; 128: Pending; 129: Online Pending; 130: Offline Pending ",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.subclass = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "subclass"),
|
||||
"Provides the list of references to nodes that can be the owner of this resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MSCluster_Resource docs:
|
||||
// msClusterResource represents the MSCluster_Resource WMI class
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resource
|
||||
type MSCluster_Resource struct {
|
||||
type msClusterResource struct {
|
||||
Name string
|
||||
Type string
|
||||
OwnerGroup string
|
||||
@@ -204,139 +35,248 @@ type MSCluster_Resource struct {
|
||||
Subclass uint
|
||||
}
|
||||
|
||||
func (c *Collector) buildResource() {
|
||||
c.resourceCharacteristics = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "characteristics"),
|
||||
"Provides the characteristics of the object.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceDeadlockTimeout = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "deadlock_timeout"),
|
||||
"Indicates the length of time to wait, in milliseconds, before declaring a deadlock in any call into a resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceEmbeddedFailureAction = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "embedded_failure_action"),
|
||||
"The time, in milliseconds, that a resource should remain in a failed state before the Cluster service attempts to restart it.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceFlags = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "flags"),
|
||||
"Provides access to the flags set for the object.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceIsAlivePollInterval = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "is_alive_poll_interval"),
|
||||
"Provides access to the resource's IsAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it is operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the IsAlivePollInterval property for the resource type associated with the resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceLooksAlivePollInterval = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "looks_alive_poll_interval"),
|
||||
"Provides access to the resource's LooksAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it appears operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the LooksAlivePollInterval property for the resource type associated with the resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceMonitorProcessId = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "monitor_process_id"),
|
||||
"Provides the process ID of the resource host service that is currently hosting the resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceOwnerNode = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "owner_node"),
|
||||
"The node hosting the resource. 0: Not hosted; 1: Hosted",
|
||||
[]string{"type", "owner_group", "node_name", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceOwnerNode = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "owner_node"),
|
||||
"The node hosting the resource. 0: Not hosted; 1: Hosted",
|
||||
[]string{"type", "owner_group", "node_name", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourcePendingTimeout = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "pending_timeout"),
|
||||
"Provides access to the resource's PendingTimeout property. If a resource cannot be brought online or taken offline in the number of milliseconds specified by the PendingTimeout property, the resource is forcibly terminated.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceResourceClass = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "resource_class"),
|
||||
"Gets or sets the resource class of a resource. 0: Unknown; 1: Storage; 2: Network; 32768: Unknown ",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceRestartAction = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "restart_action"),
|
||||
"Provides access to the resource's RestartAction property, which is the action to be taken by the Cluster Service if the resource fails.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceRestartDelay = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "restart_delay"),
|
||||
"Indicates the time delay before a failed resource is restarted.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceRestartPeriod = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "restart_period"),
|
||||
"Provides access to the resource's RestartPeriod property, which is interval of time, in milliseconds, during which a specified number of restart attempts can be made on a nonresponsive resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceRestartThreshold = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "restart_threshold"),
|
||||
"Provides access to the resource's RestartThreshold property which is the maximum number of restart attempts that can be made on a resource within an interval defined by the RestartPeriod property before the Cluster Service initiates the action specified by the RestartAction property.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceRetryPeriodOnFailure = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "retry_period_on_failure"),
|
||||
"Provides access to the resource's RetryPeriodOnFailure property, which is the interval of time (in milliseconds) that a resource should remain in a failed state before the Cluster service attempts to restart it.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "state"),
|
||||
"The current state of the resource. -1: Unknown; 0: Inherited; 1: Initializing; 2: Online; 3: Offline; 4: Failed; 128: Pending; 129: Online Pending; 130: Offline Pending ",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceSubClass = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResource, "subclass"),
|
||||
"Provides the list of references to nodes that can be the owner of this resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger log.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = log.With(logger, "collector", Name)
|
||||
var dst []MSCluster_Resource
|
||||
q := wmi.QueryAll(&dst, logger)
|
||||
func (c *Collector) collectResource(logger log.Logger, ch chan<- prometheus.Metric, nodeNames []string) error {
|
||||
var dst []msClusterResource
|
||||
|
||||
q := wmi.QueryAllForClass(&dst, "MSCluster_Resource", logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range dst {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.characteristics,
|
||||
c.resourceCharacteristics,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Characteristics),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.deadlockTimeout,
|
||||
c.resourceDeadlockTimeout,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DeadlockTimeout),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.embeddedFailureAction,
|
||||
c.resourceEmbeddedFailureAction,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.EmbeddedFailureAction),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.flags,
|
||||
c.resourceFlags,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Flags),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.isAlivePollInterval,
|
||||
c.resourceIsAlivePollInterval,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.IsAlivePollInterval),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.looksAlivePollInterval,
|
||||
c.resourceLooksAlivePollInterval,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.LooksAlivePollInterval),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.monitorProcessId,
|
||||
c.resourceMonitorProcessId,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.MonitorProcessId),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
if mscluster_node.NodeName != nil {
|
||||
for _, node_name := range mscluster_node.NodeName {
|
||||
isCurrentState := 0.0
|
||||
if v.OwnerNode == node_name {
|
||||
isCurrentState = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ownerNode,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
v.Type, v.OwnerGroup, node_name, v.Name,
|
||||
)
|
||||
for _, nodeName := range nodeNames {
|
||||
isCurrentState := 0.0
|
||||
if v.OwnerNode == nodeName {
|
||||
isCurrentState = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.resourceOwnerNode,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
v.Type, v.OwnerGroup, nodeName, v.Name,
|
||||
)
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pendingTimeout,
|
||||
c.resourcePendingTimeout,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.PendingTimeout),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.resourceClass,
|
||||
c.resourceResourceClass,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.ResourceClass),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.restartAction,
|
||||
c.resourceRestartAction,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RestartAction),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.restartDelay,
|
||||
c.resourceRestartDelay,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RestartDelay),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.restartPeriod,
|
||||
c.resourceRestartPeriod,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RestartPeriod),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.restartThreshold,
|
||||
c.resourceRestartThreshold,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RestartThreshold),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.retryPeriodOnFailure,
|
||||
c.resourceRetryPeriodOnFailure,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RetryPeriodOnFailure),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.state,
|
||||
c.resourceState,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.State),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.subclass,
|
||||
c.resourceSubClass,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Subclass),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
@@ -1,165 +1,17 @@
|
||||
package mscluster_resourcegroup
|
||||
package mscluster
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_node"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "mscluster_resourcegroup"
|
||||
const nameResourceGroup = Name + "_resourcegroup"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A Collector is a Prometheus Collector for WMI MSCluster_ResourceGroup metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
autoFailbackType *prometheus.Desc
|
||||
characteristics *prometheus.Desc
|
||||
coldStartSetting *prometheus.Desc
|
||||
defaultOwner *prometheus.Desc
|
||||
failbackWindowEnd *prometheus.Desc
|
||||
failbackWindowStart *prometheus.Desc
|
||||
failOverPeriod *prometheus.Desc
|
||||
failOverThreshold *prometheus.Desc
|
||||
flags *prometheus.Desc
|
||||
groupType *prometheus.Desc
|
||||
ownerNode *prometheus.Desc
|
||||
priority *prometheus.Desc
|
||||
resiliencyPeriod *prometheus.Desc
|
||||
state *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(_ *kingpin.Application) *Collector {
|
||||
return &Collector{}
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ log.Logger) ([]string, error) {
|
||||
return []string{"Memory"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ log.Logger) error {
|
||||
c.autoFailbackType = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "auto_failback_type"),
|
||||
"Provides access to the group's AutoFailbackType property.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.characteristics = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "characteristics"),
|
||||
"Provides the characteristics of the group.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.coldStartSetting = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cold_start_setting"),
|
||||
"Indicates whether a group can start after a cluster cold start.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.defaultOwner = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "default_owner"),
|
||||
"Number of the last node the resource group was activated on or explicitly moved to.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.failbackWindowEnd = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failback_window_end"),
|
||||
"The FailbackWindowEnd property provides the latest time that the group can be moved back to the node identified as its preferred node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.failbackWindowStart = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failback_window_start"),
|
||||
"The FailbackWindowStart property provides the earliest time (that is, local time as kept by the cluster) that the group can be moved back to the node identified as its preferred node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.failOverPeriod = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_period"),
|
||||
"The FailoverPeriod property specifies a number of hours during which a maximum number of failover attempts, specified by the FailoverThreshold property, can occur.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.failOverThreshold = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_threshold"),
|
||||
"The FailoverThreshold property specifies the maximum number of failover attempts.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.flags = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "flags"),
|
||||
"Provides access to the flags set for the group. ",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.groupType = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "group_type"),
|
||||
"The Type of the resource group.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.ownerNode = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "owner_node"),
|
||||
"The node hosting the resource group. 0: Not hosted; 1: Hosted",
|
||||
[]string{"node_name", "name"},
|
||||
nil,
|
||||
)
|
||||
c.ownerNode = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "owner_node"),
|
||||
"The node hosting the resource group. 0: Not hosted; 1: Hosted",
|
||||
[]string{"node_name", "name"},
|
||||
nil,
|
||||
)
|
||||
c.priority = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "priority"),
|
||||
"Priority value of the resource group",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resiliencyPeriod = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "resiliency_period"),
|
||||
"The resiliency period for this group, in seconds.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.state = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "state"),
|
||||
"The current state of the resource group. -1: Unknown; 0: Online; 1: Offline; 2: Failed; 3: Partial Online; 4: Pending",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MSCluster_ResourceGroup docs:
|
||||
// msClusterResourceGroup represents the MSCluster_ResourceGroup WMI class
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resourcegroup
|
||||
type MSCluster_ResourceGroup struct {
|
||||
type msClusterResourceGroup struct {
|
||||
Name string
|
||||
|
||||
AutoFailbackType uint
|
||||
@@ -178,118 +30,209 @@ type MSCluster_ResourceGroup struct {
|
||||
State uint
|
||||
}
|
||||
|
||||
func (c *Collector) buildResourceGroup() {
|
||||
c.resourceGroupAutoFailbackType = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "auto_failback_type"),
|
||||
"Provides access to the group's AutoFailbackType property.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupCharacteristics = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "characteristics"),
|
||||
"Provides the characteristics of the group.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupColdStartSetting = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "cold_start_setting"),
|
||||
"Indicates whether a group can start after a cluster cold start.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupDefaultOwner = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "default_owner"),
|
||||
"Number of the last node the resource group was activated on or explicitly moved to.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupFailbackWindowEnd = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "failback_window_end"),
|
||||
"The FailbackWindowEnd property provides the latest time that the group can be moved back to the node identified as its preferred node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupFailbackWindowStart = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "failback_window_start"),
|
||||
"The FailbackWindowStart property provides the earliest time (that is, local time as kept by the cluster) that the group can be moved back to the node identified as its preferred node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupFailOverPeriod = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "failover_period"),
|
||||
"The FailoverPeriod property specifies a number of hours during which a maximum number of failover attempts, specified by the FailoverThreshold property, can occur.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupFailOverThreshold = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "failover_threshold"),
|
||||
"The FailoverThreshold property specifies the maximum number of failover attempts.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupFlags = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "flags"),
|
||||
"Provides access to the flags set for the group. ",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupGroupType = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "group_type"),
|
||||
"The Type of the resource group.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupOwnerNode = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "owner_node"),
|
||||
"The node hosting the resource group. 0: Not hosted; 1: Hosted",
|
||||
[]string{"node_name", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupOwnerNode = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "owner_node"),
|
||||
"The node hosting the resource group. 0: Not hosted; 1: Hosted",
|
||||
[]string{"node_name", "name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupPriority = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "priority"),
|
||||
"Priority value of the resource group",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupResiliencyPeriod = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "resiliency_period"),
|
||||
"The resiliency period for this group, in seconds.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.resourceGroupState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "state"),
|
||||
"The current state of the resource group. -1: Unknown; 0: Online; 1: Offline; 2: Failed; 3: Partial Online; 4: Pending",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger log.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = log.With(logger, "collector", Name)
|
||||
var dst []MSCluster_ResourceGroup
|
||||
q := wmi.QueryAll(&dst, logger)
|
||||
func (c *Collector) collectResourceGroup(logger log.Logger, ch chan<- prometheus.Metric, nodeNames []string) error {
|
||||
var dst []msClusterResourceGroup
|
||||
|
||||
q := wmi.QueryAllForClass(&dst, "MSCluster_ResourceGroup", logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range dst {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.autoFailbackType,
|
||||
c.resourceGroupAutoFailbackType,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.AutoFailbackType),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.characteristics,
|
||||
c.resourceGroupCharacteristics,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Characteristics),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.coldStartSetting,
|
||||
c.resourceGroupColdStartSetting,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.ColdStartSetting),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.defaultOwner,
|
||||
c.resourceGroupDefaultOwner,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DefaultOwner),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failbackWindowEnd,
|
||||
c.resourceGroupFailbackWindowEnd,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.FailbackWindowEnd),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failbackWindowStart,
|
||||
c.resourceGroupFailbackWindowStart,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.FailbackWindowStart),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failOverPeriod,
|
||||
c.resourceGroupFailOverPeriod,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.FailoverPeriod),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failOverThreshold,
|
||||
c.resourceGroupFailOverThreshold,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.FailoverThreshold),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.flags,
|
||||
c.resourceGroupFlags,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Flags),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.groupType,
|
||||
c.resourceGroupGroupType,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.GroupType),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
if mscluster_node.NodeName != nil {
|
||||
for _, node_name := range mscluster_node.NodeName {
|
||||
isCurrentState := 0.0
|
||||
if v.OwnerNode == node_name {
|
||||
isCurrentState = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ownerNode,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
node_name, v.Name,
|
||||
)
|
||||
for _, nodeName := range nodeNames {
|
||||
isCurrentState := 0.0
|
||||
if v.OwnerNode == nodeName {
|
||||
isCurrentState = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.resourceGroupOwnerNode,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
nodeName, v.Name,
|
||||
)
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.priority,
|
||||
c.resourceGroupPriority,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Priority),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.resiliencyPeriod,
|
||||
c.resourceGroupResiliencyPeriod,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.ResiliencyPeriod),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.state,
|
||||
c.resourceGroupState,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.State),
|
||||
v.Name,
|
||||
@@ -186,6 +186,7 @@ func (coll *Prometheus) execute(logger log.Logger, name string, c Collector, ctx
|
||||
_ = level.Error(coll.logger).Log("msg", fmt.Sprintf("collector %s failed after %fs", name, duration), "err", err)
|
||||
return failed
|
||||
}
|
||||
|
||||
_ = level.Debug(coll.logger).Log("msg", fmt.Sprintf("collector %s succeeded after %fs.", name, duration))
|
||||
return success
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user