From 418b5b3ca99cbe7ec01cebb298051ab81eb14421 Mon Sep 17 00:00:00 2001 From: nwies Date: Sun, 7 Jun 2020 17:40:55 +0200 Subject: [PATCH] Add Collector for Microsoft FileSystem Resource Manager Quotas (#437) Add Collector for Microsoft FileSystem Resource Manager Signed-off-by: nwies --- README.md | 1 + collector/collector.go | 6 ++ collector/fsrmquota.go | 174 ++++++++++++++++++++++++++++++++++++ docs/collector.fsrmquota.md | 52 +++++++++++ 4 files changed, 233 insertions(+) create mode 100644 collector/fsrmquota.go create mode 100644 docs/collector.fsrmquota.md diff --git a/README.md b/README.md index 67d75675..2763559c 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Name | Description | Enabled by default [container](docs/collector.container.md) | Container metrics | [dns](docs/collector.dns.md) | DNS Server | [exchange](docs/collector.exchange.md) | Exchange metrics | +[fsrmquota](docs/collector.fsrmquota.md) | Microsoft File Server Resource Manager (FSRM) Quotas collector | [hyperv](docs/collector.hyperv.md) | Hyper-V hosts | [iis](docs/collector.iis.md) | IIS sites and applications | [logical_disk](docs/collector.logical_disk.md) | Logical disks, disk I/O | ✓ diff --git a/collector/collector.go b/collector/collector.go index 41708e3a..f6c1e3a0 100644 --- a/collector/collector.go +++ b/collector/collector.go @@ -109,3 +109,9 @@ func PrepareScrapeContext(collectors []string) (*ScrapeContext, error) { return &ScrapeContext{objs}, nil } +func boolToFloat(b bool) float64 { + if b { + return 1.0 + } + return 0.0 +} diff --git a/collector/fsrmquota.go b/collector/fsrmquota.go new file mode 100644 index 00000000..00b8b8d4 --- /dev/null +++ b/collector/fsrmquota.go @@ -0,0 +1,174 @@ +package collector + +import ( + "github.com/StackExchange/wmi" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/log" +) + +func init() { + registerCollector("fsrmquota",newFSRMQuotaCollector) +} + +// NewSRMQuotaCollector ... +func newFSRMQuotaCollector() (Collector, error) { + const subsystem = "fsrmquota" + return &FSRMQuotaCollector{ + QuotasCount: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "count"), + "Number of Quotas", + nil, + nil, + ), + PeakUsage: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "peak_usage_bytes"), + "The highest amount of disk space usage charged to this quota. (PeakUsage)", + []string{"path", "template"}, + nil, + ), + Size: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "size_bytes"), + "The size of the quota. (Size)", + []string{"path", "template"}, + nil, + ), + Usage: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "usage_bytes"), + "The current amount of disk space usage charged to this quota. (Usage)", + []string{"path", "template"}, + nil, + ), + Description: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "description"), + "Description of the quota (Description)", + []string{"path", "template", "description"}, + nil, + ), + Disabled: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "disabled"), + "If 1, the quota is disabled. The default value is 0. (Disabled)", + []string{"path", "template"}, + nil, + ), + SoftLimit: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "softlimit"), + "If 1, the quota is a soft limit. If 0, the quota is a hard limit. The default value is 0. Optional (SoftLimit)", + []string{"path", "template"}, + nil, + ), + Template: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "template"), + "Quota template name. (Template)", + []string{"path", "template"}, + nil, + ), + MatchesTemplate: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "matchestemplate"), + "If 1, the property values of this quota match those values of the template from which it was derived. (MatchesTemplate)", + []string{"path", "template"}, + nil, + ), + }, nil +} + +// Collect sends the metric values for each metric +// to the provided prometheus Metric channel. +func (c *FSRMQuotaCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error { + if desc, err := c.collect(ch); err != nil { + log.Error("failed collecting fsrmquota metrics:", desc, err) + return err + } + return nil +} + +// MSFT_FSRMQuota docs: +// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/fsrm/msft-fsrmquota +type MSFT_FSRMQuota struct { + Name string + + Path string + PeakUsage uint64 + Size uint64 + Usage uint64 + Description string + Template string + //Threshold string + Disabled bool + MatchesTemplate bool + SoftLimit bool +} + +func (c *FSRMQuotaCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) { + var dst []MSFT_FSRMQuota + q := queryAll(&dst) + + var count int + + if err := wmi.QueryNamespace(q, &dst, "root/microsoft/windows/fsrm"); err != nil { + return nil, err + } + + for _, quota := range dst { + + count++ + path := quota.Path + template := quota.Template + Description := quota.Description + + ch <- prometheus.MustNewConstMetric( + c.PeakUsage, + prometheus.GaugeValue, + float64(quota.PeakUsage), + path, + template, + ) + ch <- prometheus.MustNewConstMetric( + c.Size, + prometheus.GaugeValue, + float64(quota.Size), + path, + template, + ) + ch <- prometheus.MustNewConstMetric( + c.Usage, + prometheus.GaugeValue, + float64(quota.Usage), + path, + template, + ) + ch <- prometheus.MustNewConstMetric( + c.Description, + prometheus.GaugeValue, + 1.0, + path, template, Description, + ) + ch <- prometheus.MustNewConstMetric( + c.Disabled, + prometheus.GaugeValue, + boolToFloat(quota.Disabled), + path, + template, + ) + ch <- prometheus.MustNewConstMetric( + c.MatchesTemplate, + prometheus.GaugeValue, + boolToFloat(quota.MatchesTemplate), + path, + template, + ) + ch <- prometheus.MustNewConstMetric( + c.SoftLimit, + prometheus.GaugeValue, + boolToFloat(quota.SoftLimit), + path, + template, + ) + } + + ch <- prometheus.MustNewConstMetric( + c.QuotasCount, + prometheus.GaugeValue, + float64(count), + ) + return nil, nil +} diff --git a/docs/collector.fsrmquota.md b/docs/collector.fsrmquota.md new file mode 100644 index 00000000..5d6c60e0 --- /dev/null +++ b/docs/collector.fsrmquota.md @@ -0,0 +1,52 @@ +# Microsoft File Server Resource Manager (FSRM) Quotas collector + +The fsrmquota collector exposes metrics about File Server Ressource Manager Quotas. Note that this collector has only been tested against Windows server 2012R2. +Other FSRM versions may work but are not tested. + +||| +-|- +Metric name prefix | `fsrmquota` +Data source | wmi +Counters | `FSRMQUOTA` +Enabled by default? | No + +## Flags + +None + +## Metrics + +Name | Description | Type | Labels +-----|-------------|------|------- + +`windows_fsrmquota_count` | Number of Quotas | counter |None +`windows_fsrmquota_description` | A string up to 1KB in size. Optional. The default value is an empty string. (Description) | counter |`path`, `template`,`description` +`windows_fsrmquota_disabled` | If 1, the quota is disabled. The default value is 0. (Disabled) | counter |`path`, `template` +`windows_fsrmquota_matchestemplate` | If 1, the property values of this quota match those values of the template from which it was derived. (MatchesTemplate) | counter |`path`, `template` +`windows_fsrmquota_peak_usage_bytes ` | The highest amount of disk space usage charged to this quota. (PeakUsage) | counter |`path`, `template` +`windows_fsrmquota_size_bytes` | The size of the quota. If the Template property is not provided then the Size property must be provided (Size) | counter |`path`, `template` +`windows_fsrmquota_softlimit` | If 1, the quota is a soft limit. If 0, the quota is a hard limit. The default value is 0. Optional (SoftLimit) | counter |`path`, `template` +`windows_fsrmquota_template` | A valid quota template name. Up to 1KB in size. Optional (Template) | counter |`path`, `template` +`windows_fsrmquota_usage_bytes` | The current amount of disk space usage charged to this quota. (Usage) | counter |`path`, `template` + + +### Example metric +Show rate of Quotas usage: +``` +rate(windows_fsrmquota_usage_bytes)[1d] +``` + +## Useful queries + +## Alerting examples +**prometheus.rules** +```yaml + - alert: "HighQuotasUsage" + expr: "windows_fsrmquota_usage_bytes{instance="SERVER1.COM:9182"} / windows_fsrmquota_size{instance="SERVER1.COM:9182"} >0.85" + for: "10m" + labels: + severity: "high" + annotations: + summary: "High Quotas Usage" + description: "High use of File Ressource.\n Quotas: {{ $labels.path }}\n Current use : {{ $value }}" +```