mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-07 21:46:37 +00:00
license collector (#1524)
This commit is contained in:
@@ -24,6 +24,7 @@ Name | Description | Enabled by default
|
|||||||
[fsrmquota](docs/collector.fsrmquota.md) | Microsoft File Server Resource Manager (FSRM) Quotas collector |
|
[fsrmquota](docs/collector.fsrmquota.md) | Microsoft File Server Resource Manager (FSRM) Quotas collector |
|
||||||
[hyperv](docs/collector.hyperv.md) | Hyper-V hosts |
|
[hyperv](docs/collector.hyperv.md) | Hyper-V hosts |
|
||||||
[iis](docs/collector.iis.md) | IIS sites and applications |
|
[iis](docs/collector.iis.md) | IIS sites and applications |
|
||||||
|
[license](docs/collector.license.md) | Windows license status |
|
||||||
[logical_disk](docs/collector.logical_disk.md) | Logical disks, disk I/O | ✓
|
[logical_disk](docs/collector.logical_disk.md) | Logical disks, disk I/O | ✓
|
||||||
[logon](docs/collector.logon.md) | User logon sessions |
|
[logon](docs/collector.logon.md) | User logon sessions |
|
||||||
[memory](docs/collector.memory.md) | Memory usage metrics |
|
[memory](docs/collector.memory.md) | Memory usage metrics |
|
||||||
|
|||||||
53
docs/collector.license.md
Normal file
53
docs/collector.license.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# license collector
|
||||||
|
|
||||||
|
The license collector exposes metrics about the Windows license status.
|
||||||
|
|
||||||
|
|||
|
||||||
|
-|-
|
||||||
|
Metric name prefix | `license`
|
||||||
|
Data source | Win32
|
||||||
|
Enabled by default? | No
|
||||||
|
|
||||||
|
## Flags
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
## Metrics
|
||||||
|
|
||||||
|
| Name | Description | Type | Labels |
|
||||||
|
|--------------------------|----------------|-------|---------|
|
||||||
|
| `windows_license_status` | license status | gauge | `state` |
|
||||||
|
|
||||||
|
### Example metric
|
||||||
|
|
||||||
|
```
|
||||||
|
# HELP windows_license_status Status of windows license
|
||||||
|
# TYPE windows_license_status gauge
|
||||||
|
windows_license_status{state="genuine"} 1
|
||||||
|
windows_license_status{state="invalid_license"} 0
|
||||||
|
windows_license_status{state="last"} 0
|
||||||
|
windows_license_status{state="offline"} 0
|
||||||
|
windows_license_status{state="tampered"} 0
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Useful queries
|
||||||
|
|
||||||
|
Show if the license is genuine
|
||||||
|
|
||||||
|
```
|
||||||
|
windows_license_status{state="genuine"}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Alerting examples
|
||||||
|
**prometheus.rules**
|
||||||
|
```yaml
|
||||||
|
- alert: "WindowsLicense"
|
||||||
|
expr: 'windows_license_status{state="genuine"} == 0'
|
||||||
|
for: "10m"
|
||||||
|
labels:
|
||||||
|
severity: "high"
|
||||||
|
annotations:
|
||||||
|
summary: "Windows system license is not genuine"
|
||||||
|
description: "The Windows system license is not genuine. Please check the license status."
|
||||||
|
```
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/go-kit/log"
|
"github.com/go-kit/log"
|
||||||
|
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/ad"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/ad"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/adcs"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/adcs"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/adfs"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/adfs"
|
||||||
@@ -23,6 +24,7 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/license"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
"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/logon"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
||||||
@@ -103,6 +105,7 @@ func NewWithConfig(logger log.Logger, config Config) Collectors {
|
|||||||
collectors[exchange.Name] = exchange.New(logger, &config.Fsrmquota)
|
collectors[exchange.Name] = exchange.New(logger, &config.Fsrmquota)
|
||||||
collectors[hyperv.Name] = hyperv.New(logger, &config.Hyperv)
|
collectors[hyperv.Name] = hyperv.New(logger, &config.Hyperv)
|
||||||
collectors[iis.Name] = iis.New(logger, &config.Iis)
|
collectors[iis.Name] = iis.New(logger, &config.Iis)
|
||||||
|
collectors[license.Name] = license.New(logger, &config.License)
|
||||||
collectors[logical_disk.Name] = logical_disk.New(logger, &config.LogicalDisk)
|
collectors[logical_disk.Name] = logical_disk.New(logger, &config.LogicalDisk)
|
||||||
collectors[logon.Name] = logon.New(logger, &config.Logon)
|
collectors[logon.Name] = logon.New(logger, &config.Logon)
|
||||||
collectors[memory.Name] = memory.New(logger, &config.Memory)
|
collectors[memory.Name] = memory.New(logger, &config.Memory)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/license"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
"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/logon"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
||||||
@@ -74,6 +75,7 @@ type Config struct {
|
|||||||
Fsrmquota exchange.Config `yaml:"fsrmquota"`
|
Fsrmquota exchange.Config `yaml:"fsrmquota"`
|
||||||
Hyperv hyperv.Config `yaml:"hyperv"`
|
Hyperv hyperv.Config `yaml:"hyperv"`
|
||||||
Iis iis.Config `yaml:"iis"`
|
Iis iis.Config `yaml:"iis"`
|
||||||
|
License license.Config `yaml:"license"`
|
||||||
LogicalDisk logical_disk.Config `yaml:"logical_disk"`
|
LogicalDisk logical_disk.Config `yaml:"logical_disk"`
|
||||||
Logon logon.Config `yaml:"logon"`
|
Logon logon.Config `yaml:"logon"`
|
||||||
Memory memory.Config `yaml:"memory"`
|
Memory memory.Config `yaml:"memory"`
|
||||||
@@ -133,6 +135,7 @@ var ConfigDefaults = Config{
|
|||||||
Fsrmquota: exchange.ConfigDefaults,
|
Fsrmquota: exchange.ConfigDefaults,
|
||||||
Hyperv: hyperv.ConfigDefaults,
|
Hyperv: hyperv.ConfigDefaults,
|
||||||
Iis: iis.ConfigDefaults,
|
Iis: iis.ConfigDefaults,
|
||||||
|
License: license.ConfigDefaults,
|
||||||
LogicalDisk: logical_disk.ConfigDefaults,
|
LogicalDisk: logical_disk.ConfigDefaults,
|
||||||
Logon: logon.ConfigDefaults,
|
Logon: logon.ConfigDefaults,
|
||||||
Memory: memory.ConfigDefaults,
|
Memory: memory.ConfigDefaults,
|
||||||
|
|||||||
95
pkg/collector/license/license.go
Normal file
95
pkg/collector/license/license.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package license
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kingpin/v2"
|
||||||
|
"github.com/go-kit/log"
|
||||||
|
"github.com/go-kit/log/level"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/headers/slc"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Name = "license"
|
||||||
|
|
||||||
|
var labelMap = map[slc.SL_GENUINE_STATE]string{
|
||||||
|
slc.SL_GEN_STATE_IS_GENUINE: "genuine",
|
||||||
|
slc.SL_GEN_STATE_INVALID_LICENSE: "invalid_license",
|
||||||
|
slc.SL_GEN_STATE_TAMPERED: "tampered",
|
||||||
|
slc.SL_GEN_STATE_OFFLINE: "offline",
|
||||||
|
slc.SL_GEN_STATE_LAST: "last",
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct{}
|
||||||
|
|
||||||
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
|
// A collector is a Prometheus collector for WMI Win32_PerfRawData_DNS_DNS metrics
|
||||||
|
type collector struct {
|
||||||
|
logger log.Logger
|
||||||
|
|
||||||
|
LicenseStatus *prometheus.Desc
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(logger log.Logger, _ *Config) types.Collector {
|
||||||
|
c := &collector{}
|
||||||
|
c.SetLogger(logger)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWithFlags(_ *kingpin.Application) types.Collector {
|
||||||
|
return &collector{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) GetName() string {
|
||||||
|
return Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) SetLogger(logger log.Logger) {
|
||||||
|
c.logger = log.With(logger, "collector", Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) GetPerfCounter() ([]string, error) {
|
||||||
|
return []string{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) Build() error {
|
||||||
|
c.LicenseStatus = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "status"),
|
||||||
|
"Status of windows license",
|
||||||
|
[]string{"state"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect sends the metric values for each metric
|
||||||
|
// to the provided prometheus Metric channel.
|
||||||
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
|
if err := c.collect(ch); err != nil {
|
||||||
|
_ = level.Error(c.logger).Log("msg", "failed collecting license metrics", "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
|
status, err := slc.SLIsWindowsGenuineLocal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range labelMap {
|
||||||
|
val := 0.0
|
||||||
|
if status == k {
|
||||||
|
val = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(c.LicenseStatus, prometheus.GaugeValue, val, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
12
pkg/collector/license/license_test.go
Normal file
12
pkg/collector/license/license_test.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package license_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/license"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkCollector(b *testing.B) {
|
||||||
|
testutils.FuncBenchmarkCollector(b, license.Name, license.NewWithFlags)
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/fsrmquota"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/fsrmquota"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/license"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
"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/logon"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
||||||
@@ -78,6 +79,7 @@ var Map = map[string]types.CollectorBuilderWithFlags{
|
|||||||
fsrmquota.Name: fsrmquota.NewWithFlags,
|
fsrmquota.Name: fsrmquota.NewWithFlags,
|
||||||
hyperv.Name: hyperv.NewWithFlags,
|
hyperv.Name: hyperv.NewWithFlags,
|
||||||
iis.Name: iis.NewWithFlags,
|
iis.Name: iis.NewWithFlags,
|
||||||
|
license.Name: license.NewWithFlags,
|
||||||
logical_disk.Name: logical_disk.NewWithFlags,
|
logical_disk.Name: logical_disk.NewWithFlags,
|
||||||
logon.Name: logon.NewWithFlags,
|
logon.Name: logon.NewWithFlags,
|
||||||
memory.Name: memory.NewWithFlags,
|
memory.Name: memory.NewWithFlags,
|
||||||
|
|||||||
40
pkg/headers/slc/slc.go
Normal file
40
pkg/headers/slc/slc.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package slc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slc = windows.NewLazySystemDLL("slc.dll")
|
||||||
|
procSLIsWindowsGenuineLocal = slc.NewProc("SLIsWindowsGenuineLocal")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Define SL_GENUINE_STATE enumeration
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/slpublic/ne-slpublic-sl_genuine_state
|
||||||
|
type SL_GENUINE_STATE uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
SL_GEN_STATE_IS_GENUINE SL_GENUINE_STATE = iota
|
||||||
|
SL_GEN_STATE_INVALID_LICENSE
|
||||||
|
SL_GEN_STATE_TAMPERED
|
||||||
|
SL_GEN_STATE_OFFLINE
|
||||||
|
SL_GEN_STATE_LAST
|
||||||
|
)
|
||||||
|
|
||||||
|
// SLIsWindowsGenuineLocal function wrapper
|
||||||
|
func SLIsWindowsGenuineLocal() (SL_GENUINE_STATE, error) {
|
||||||
|
var genuineState SL_GENUINE_STATE
|
||||||
|
|
||||||
|
_, _, err := procSLIsWindowsGenuineLocal.Call(
|
||||||
|
uintptr(unsafe.Pointer(&genuineState)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if !errors.Is(err, windows.NTE_OP_OK) {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return genuineState, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user