mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-07 21:46:37 +00:00
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -95,7 +95,7 @@ jobs:
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: v1.51.2
|
||||
version: v1.55.2
|
||||
args: "--timeout=5m"
|
||||
|
||||
# golangci-lint action doesn't always provide helpful output, so re-run without the action for
|
||||
|
||||
@@ -7,13 +7,13 @@ linters:
|
||||
- govet
|
||||
- gofmt
|
||||
- ineffassign
|
||||
- structcheck
|
||||
- unconvert
|
||||
- varcheck
|
||||
|
||||
issues:
|
||||
exclude:
|
||||
- don't use underscores in Go names
|
||||
- don't use an underscore in package name
|
||||
- exported type .+ should have comment or be unexported
|
||||
exclude-rules:
|
||||
- # Golint has many capitalisation complaints on WMI class names
|
||||
|
||||
4
Makefile
4
Makefile
@@ -13,14 +13,14 @@ BASE_IMAGE=mcr.microsoft.com/windows/nanoserver
|
||||
|
||||
.PHONY: build
|
||||
build: windows_exporter.exe
|
||||
windows_exporter.exe: **/*.go
|
||||
windows_exporter.exe: pkg/**/*.go
|
||||
promu build -v
|
||||
|
||||
test:
|
||||
go test -v ./...
|
||||
|
||||
bench:
|
||||
go test -v -bench='benchmark(cpu|logicaldisk|physicaldisk|logon|memory|net|process|service|system|tcp|time)collector' ./...
|
||||
go test -v -bench='benchmarkcollector' ./pkg/collector/{cpu,logical_disk,physical_disk,logon,memory,net,process,service,system,tcp,time}
|
||||
|
||||
lint:
|
||||
golangci-lint -c .golangci.yaml run
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkADCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "ad", newADCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkADCSCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "adcs", adcsCollectorMethod)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkADFSCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "adfs", newADFSCollector)
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/perflib"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
// ...
|
||||
const (
|
||||
// TODO: Make package-local
|
||||
Namespace = "windows"
|
||||
|
||||
// Conversion factors
|
||||
ticksToSecondsScaleFactor = 1 / 1e7
|
||||
windowsEpoch = 116444736000000000
|
||||
)
|
||||
|
||||
// getWindowsVersion reads the version number of the OS from the Registry
|
||||
// See https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version
|
||||
func getWindowsVersion(logger log.Logger) float64 {
|
||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
_ = level.Warn(logger).Log("msg", "Couldn't open registry", "err", err)
|
||||
return 0
|
||||
}
|
||||
defer func() {
|
||||
err = k.Close()
|
||||
if err != nil {
|
||||
_ = level.Warn(logger).Log("msg", "Failed to close registry key", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
currentv, _, err := k.GetStringValue("CurrentVersion")
|
||||
if err != nil {
|
||||
_ = level.Warn(logger).Log("msg", "Couldn't open registry to determine current Windows version", "err", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
currentv_flt, err := strconv.ParseFloat(currentv, 64)
|
||||
|
||||
_ = level.Debug(logger).Log("msg", fmt.Sprintf("Detected Windows version %f\n", currentv_flt))
|
||||
|
||||
return currentv_flt
|
||||
}
|
||||
|
||||
type collectorBuilder func(log.Logger) (Collector, error)
|
||||
type flagsBuilder func(*kingpin.Application)
|
||||
type perfCounterNamesBuilder func(log.Logger) []string
|
||||
|
||||
var (
|
||||
builders = make(map[string]collectorBuilder)
|
||||
perfCounterDependencies = make(map[string]string)
|
||||
)
|
||||
|
||||
func registerCollector(name string, builder collectorBuilder, perfCounterNames ...string) {
|
||||
builders[name] = builder
|
||||
addPerfCounterDependencies(name, perfCounterNames)
|
||||
}
|
||||
|
||||
func addPerfCounterDependencies(name string, perfCounterNames []string) {
|
||||
perfIndicies := make([]string, 0, len(perfCounterNames))
|
||||
for _, cn := range perfCounterNames {
|
||||
perfIndicies = append(perfIndicies, MapCounterToIndex(cn))
|
||||
}
|
||||
perfCounterDependencies[name] = strings.Join(perfIndicies, " ")
|
||||
}
|
||||
|
||||
func Available() []string {
|
||||
cs := make([]string, 0, len(builders))
|
||||
for c := range builders {
|
||||
cs = append(cs, c)
|
||||
}
|
||||
return cs
|
||||
}
|
||||
func Build(collector string, logger log.Logger) (Collector, error) {
|
||||
builder, exists := builders[collector]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("Unknown collector %q", collector)
|
||||
}
|
||||
return builder(logger)
|
||||
}
|
||||
func getPerfQuery(collectors []string) string {
|
||||
parts := make([]string, 0, len(collectors))
|
||||
for _, c := range collectors {
|
||||
if p := perfCounterDependencies[c]; p != "" {
|
||||
parts = append(parts, p)
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, " ")
|
||||
}
|
||||
|
||||
// Collector is the interface a collector has to implement.
|
||||
type Collector interface {
|
||||
// Get new metrics and expose them via prometheus registry.
|
||||
Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (err error)
|
||||
}
|
||||
|
||||
type ScrapeContext struct {
|
||||
perfObjects map[string]*perflib.PerfObject
|
||||
}
|
||||
|
||||
// PrepareScrapeContext creates a ScrapeContext to be used during a single scrape
|
||||
func PrepareScrapeContext(collectors []string) (*ScrapeContext, error) {
|
||||
q := getPerfQuery(collectors) // TODO: Memoize
|
||||
objs, err := getPerflibSnapshot(q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ScrapeContext{objs}, nil
|
||||
}
|
||||
func boolToFloat(b bool) float64 {
|
||||
if b {
|
||||
return 1.0
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func find(slice []string, val string) bool {
|
||||
for _, item := range slice {
|
||||
if item == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Used by more complex collectors where user input specifies enabled child collectors.
|
||||
// Splits provided child collectors and deduplicate.
|
||||
func expandEnabledChildCollectors(enabled string) []string {
|
||||
separated := strings.Split(enabled, ",")
|
||||
unique := map[string]bool{}
|
||||
for _, s := range separated {
|
||||
if s != "" {
|
||||
unique[s] = true
|
||||
}
|
||||
}
|
||||
result := make([]string, 0, len(unique))
|
||||
for s := range unique {
|
||||
result = append(result, s)
|
||||
}
|
||||
// Ensure result is ordered, to prevent test failure
|
||||
sort.Strings(result)
|
||||
return result
|
||||
}
|
||||
|
||||
func milliSecToSec(t float64) float64 {
|
||||
return t / 1000
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func TestExpandChildCollectors(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input string
|
||||
expectedOutput []string
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
input: "testing1,testing2,testing3",
|
||||
expectedOutput: []string{"testing1", "testing2", "testing3"},
|
||||
},
|
||||
{
|
||||
name: "duplicate",
|
||||
input: "testing1,testing2,testing2,testing3",
|
||||
expectedOutput: []string{"testing1", "testing2", "testing3"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
output := expandEnabledChildCollectors(c.input)
|
||||
if !reflect.DeepEqual(output, c.expectedOutput) {
|
||||
t.Errorf("Output mismatch, expected %+v, got %+v", c.expectedOutput, output)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkCollector(b *testing.B, name string, collectFunc func(logger log.Logger) (Collector, error)) {
|
||||
// Create perflib scrape context. Some perflib collectors required a correct context,
|
||||
// or will fail during benchmark.
|
||||
scrapeContext, err := PrepareScrapeContext([]string{name})
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
c, err := collectFunc(log.NewNopLogger())
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
metrics := make(chan prometheus.Metric)
|
||||
go func() {
|
||||
for {
|
||||
<-metrics
|
||||
}
|
||||
}()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
c.Collect(scrapeContext, metrics) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
@@ -1,372 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// A ContainerMetricsCollector is a Prometheus collector for containers metrics
|
||||
type ContainerMetricsCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
// Presence
|
||||
ContainerAvailable *prometheus.Desc
|
||||
|
||||
// Number of containers
|
||||
ContainersCount *prometheus.Desc
|
||||
// memory
|
||||
UsageCommitBytes *prometheus.Desc
|
||||
UsageCommitPeakBytes *prometheus.Desc
|
||||
UsagePrivateWorkingSetBytes *prometheus.Desc
|
||||
|
||||
// CPU
|
||||
RuntimeTotal *prometheus.Desc
|
||||
RuntimeUser *prometheus.Desc
|
||||
RuntimeKernel *prometheus.Desc
|
||||
|
||||
// Network
|
||||
BytesReceived *prometheus.Desc
|
||||
BytesSent *prometheus.Desc
|
||||
PacketsReceived *prometheus.Desc
|
||||
PacketsSent *prometheus.Desc
|
||||
DroppedPacketsIncoming *prometheus.Desc
|
||||
DroppedPacketsOutgoing *prometheus.Desc
|
||||
|
||||
// Storage
|
||||
ReadCountNormalized *prometheus.Desc
|
||||
ReadSizeBytes *prometheus.Desc
|
||||
WriteCountNormalized *prometheus.Desc
|
||||
WriteSizeBytes *prometheus.Desc
|
||||
}
|
||||
|
||||
// newContainerMetricsCollector constructs a new ContainerMetricsCollector
|
||||
func newContainerMetricsCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "container"
|
||||
return &ContainerMetricsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
ContainerAvailable: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "available"),
|
||||
"Available",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
ContainersCount: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "count"),
|
||||
"Number of containers",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
UsageCommitBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "memory_usage_commit_bytes"),
|
||||
"Memory Usage Commit Bytes",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
UsageCommitPeakBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "memory_usage_commit_peak_bytes"),
|
||||
"Memory Usage Commit Peak Bytes",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
UsagePrivateWorkingSetBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "memory_usage_private_working_set_bytes"),
|
||||
"Memory Usage Private Working Set Bytes",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
RuntimeTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cpu_usage_seconds_total"),
|
||||
"Total Run time in Seconds",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
RuntimeUser: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cpu_usage_seconds_usermode"),
|
||||
"Run Time in User mode in Seconds",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
RuntimeKernel: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cpu_usage_seconds_kernelmode"),
|
||||
"Run time in Kernel mode in Seconds",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
BytesReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "network_receive_bytes_total"),
|
||||
"Bytes Received on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
),
|
||||
BytesSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "network_transmit_bytes_total"),
|
||||
"Bytes Sent on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
),
|
||||
PacketsReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "network_receive_packets_total"),
|
||||
"Packets Received on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
),
|
||||
PacketsSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "network_transmit_packets_total"),
|
||||
"Packets Sent on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
),
|
||||
DroppedPacketsIncoming: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "network_receive_packets_dropped_total"),
|
||||
"Dropped Incoming Packets on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
),
|
||||
DroppedPacketsOutgoing: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "network_transmit_packets_dropped_total"),
|
||||
"Dropped Outgoing Packets on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
),
|
||||
ReadCountNormalized: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "storage_read_count_normalized_total"),
|
||||
"Read Count Normalized",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
ReadSizeBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "storage_read_size_bytes_total"),
|
||||
"Read Size Bytes",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
WriteCountNormalized: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "storage_write_count_normalized_total"),
|
||||
"Write Count Normalized",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
WriteSizeBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "storage_write_size_bytes_total"),
|
||||
"Write Size Bytes",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *ContainerMetricsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting ContainerMetricsCollector metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// containerClose closes the container resource
|
||||
func (c *ContainerMetricsCollector) containerClose(container hcsshim.Container) {
|
||||
err := container.Close()
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ContainerMetricsCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
|
||||
// Types Container is passed to get the containers compute systems only
|
||||
containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "Err in Getting containers", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
count := len(containers)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ContainersCount,
|
||||
prometheus.GaugeValue,
|
||||
float64(count),
|
||||
)
|
||||
if count == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
containerPrefixes := make(map[string]string)
|
||||
|
||||
for _, containerDetails := range containers {
|
||||
container, err := hcsshim.OpenContainer(containerDetails.ID)
|
||||
if container != nil {
|
||||
defer c.containerClose(container)
|
||||
}
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "err in opening container", "containerId", containerDetails.ID, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
cstats, err := container.Statistics()
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "err in fetching container Statistics", "containerId", containerDetails.ID, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
containerIdWithPrefix := getContainerIdWithPrefix(containerDetails)
|
||||
containerPrefixes[containerDetails.ID] = containerIdWithPrefix
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ContainerAvailable,
|
||||
prometheus.CounterValue,
|
||||
1,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.UsageCommitBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(cstats.Memory.UsageCommitBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.UsageCommitPeakBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(cstats.Memory.UsageCommitPeakBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.UsagePrivateWorkingSetBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(cstats.Memory.UsagePrivateWorkingSetBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RuntimeTotal,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Processor.TotalRuntime100ns)*ticksToSecondsScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RuntimeUser,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Processor.RuntimeUser100ns)*ticksToSecondsScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RuntimeKernel,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Processor.RuntimeKernel100ns)*ticksToSecondsScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadCountNormalized,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.ReadCountNormalized),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadSizeBytes,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.ReadSizeBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteCountNormalized,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.WriteCountNormalized),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteSizeBytes,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.WriteSizeBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
}
|
||||
|
||||
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for containers")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if len(hnsEndpoints) == 0 {
|
||||
_ = level.Info(c.logger).Log("msg", fmt.Sprintf("No network stats for containers to collect"))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, endpoint := range hnsEndpoints {
|
||||
endpointStats, err := hcsshim.GetHNSEndpointStats(endpoint.Id)
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Failed to collect network stats for interface %s", endpoint.Id), "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, containerId := range endpoint.SharedContainers {
|
||||
containerIdWithPrefix, ok := containerPrefixes[containerId]
|
||||
endpointId := strings.ToUpper(endpoint.Id)
|
||||
|
||||
if !ok {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Failed to collect network stats for container %s", containerId))
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.BytesReceived),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesSent,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.BytesSent),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.PacketsReceived),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.PacketsSent),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DroppedPacketsIncoming,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.DroppedPacketsIncoming),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DroppedPacketsOutgoing,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.DroppedPacketsOutgoing),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getContainerIdWithPrefix(containerDetails hcsshim.ContainerProperties) string {
|
||||
switch containerDetails.Owner {
|
||||
case "containerd-shim-runhcs-v1.exe":
|
||||
return "containerd://" + containerDetails.ID
|
||||
default:
|
||||
// default to docker or if owner is not set
|
||||
return "docker://" + containerDetails.ID
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkContainerCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "container", newContainerMetricsCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkCPUCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "cpu", newCPUCollector)
|
||||
}
|
||||
108
collector/cs.go
108
collector/cs.go
@@ -1,108 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/headers/sysinfoapi"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// A CSCollector is a Prometheus collector for WMI metrics
|
||||
type CSCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
PhysicalMemoryBytes *prometheus.Desc
|
||||
LogicalProcessors *prometheus.Desc
|
||||
Hostname *prometheus.Desc
|
||||
}
|
||||
|
||||
// newCSCollector ...
|
||||
func newCSCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "cs"
|
||||
|
||||
return &CSCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
LogicalProcessors: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "logical_processors"),
|
||||
"ComputerSystem.NumberOfLogicalProcessors",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PhysicalMemoryBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "physical_memory_bytes"),
|
||||
"ComputerSystem.TotalPhysicalMemory",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
Hostname: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "hostname"),
|
||||
"Labeled system hostname information as provided by ComputerSystem.DNSHostName and ComputerSystem.Domain",
|
||||
[]string{
|
||||
"hostname",
|
||||
"domain",
|
||||
"fqdn"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *CSCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting cs metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CSCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
// Get systeminfo for number of processors
|
||||
systemInfo := sysinfoapi.GetSystemInfo()
|
||||
|
||||
// Get memory status for physical memory
|
||||
mem, err := sysinfoapi.GlobalMemoryStatusEx()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.LogicalProcessors,
|
||||
prometheus.GaugeValue,
|
||||
float64(systemInfo.NumberOfProcessors),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PhysicalMemoryBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(mem.TotalPhys),
|
||||
)
|
||||
|
||||
hostname, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSHostname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domain, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSDomain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fqdn, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSFullyQualified)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Hostname,
|
||||
prometheus.GaugeValue,
|
||||
1.0,
|
||||
hostname,
|
||||
domain,
|
||||
fqdn,
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkCsCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "cs", newCSCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkDFSRCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "dfsr", newDFSRCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkDHCPCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "dhcp", newDhcpCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkDiskDriveCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "disk_drive", newDiskDriveInfoCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkDNSCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "dns", newDNSCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkExchangeCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "exchange", newExchangeCollector)
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
type FSRMQuotaCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
QuotasCount *prometheus.Desc
|
||||
Path *prometheus.Desc
|
||||
PeakUsage *prometheus.Desc
|
||||
Size *prometheus.Desc
|
||||
Usage *prometheus.Desc
|
||||
|
||||
Description *prometheus.Desc
|
||||
Disabled *prometheus.Desc
|
||||
MatchesTemplate *prometheus.Desc
|
||||
SoftLimit *prometheus.Desc
|
||||
Template *prometheus.Desc
|
||||
}
|
||||
|
||||
func newFSRMQuotaCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "fsrmquota"
|
||||
return &FSRMQuotaCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
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 {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting fsrmquota metrics", "desc", desc, "err", 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, c.logger)
|
||||
|
||||
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
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkFsrmQuotaCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "fsrmquota", newFSRMQuotaCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkHypervCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "hyperv", newHyperVCollector)
|
||||
}
|
||||
@@ -1,423 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
)
|
||||
|
||||
// collectorInit represents the required initialisation config for a collector.
|
||||
type collectorInit struct {
|
||||
// Name of collector to be initialised
|
||||
name string
|
||||
// Builder function for the collector
|
||||
flags flagsBuilder
|
||||
// Builder function for the collector
|
||||
builder collectorBuilder
|
||||
// Perflib counter names for the collector.
|
||||
// These will be included in the Perflib scrape scope by the exporter.
|
||||
perfCounterFunc perfCounterNamesBuilder
|
||||
}
|
||||
|
||||
func getDFSRCollectorDeps(_ log.Logger) []string {
|
||||
// Perflib sources are dynamic, depending on the enabled child collectors
|
||||
var perflibDependencies []string
|
||||
for _, source := range expandEnabledChildCollectors(*dfsrEnabledCollectors) {
|
||||
perflibDependencies = append(perflibDependencies, dfsrGetPerfObjectName(source))
|
||||
}
|
||||
|
||||
return perflibDependencies
|
||||
}
|
||||
|
||||
var collectors = []collectorInit{
|
||||
{
|
||||
name: "ad",
|
||||
flags: nil,
|
||||
builder: newADCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "adcs",
|
||||
flags: nil,
|
||||
builder: adcsCollectorMethod,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Certification Authority"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "adfs",
|
||||
flags: nil,
|
||||
builder: newADFSCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"AD FS"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cache",
|
||||
flags: nil,
|
||||
builder: newCacheCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Cache"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "container",
|
||||
flags: nil,
|
||||
builder: newContainerMetricsCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "cpu",
|
||||
flags: nil,
|
||||
builder: newCPUCollector,
|
||||
perfCounterFunc: func(logger log.Logger) []string {
|
||||
if getWindowsVersion(logger) > 6.05 {
|
||||
return []string{"Processor Information"}
|
||||
}
|
||||
return []string{"Processor"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cpu_info",
|
||||
flags: nil,
|
||||
builder: newCpuInfoCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "cs",
|
||||
flags: nil,
|
||||
builder: newCSCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "dfsr",
|
||||
flags: newDFSRCollectorFlags,
|
||||
builder: newDFSRCollector,
|
||||
perfCounterFunc: getDFSRCollectorDeps,
|
||||
},
|
||||
{
|
||||
name: "dhcp",
|
||||
flags: nil,
|
||||
builder: newDhcpCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "diskdrive",
|
||||
flags: nil,
|
||||
builder: newDiskDriveInfoCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "dns",
|
||||
flags: nil,
|
||||
builder: newDNSCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "exchange",
|
||||
flags: newExchangeCollectorFlags,
|
||||
builder: newExchangeCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{
|
||||
"MSExchange ADAccess Processes",
|
||||
"MSExchangeTransport Queues",
|
||||
"MSExchange HttpProxy",
|
||||
"MSExchange ActiveSync",
|
||||
"MSExchange Availability Service",
|
||||
"MSExchange OWA",
|
||||
"MSExchangeAutodiscover",
|
||||
"MSExchange WorkloadManagement Workloads",
|
||||
"MSExchange RpcClientAccess",
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "fsrmquota",
|
||||
flags: nil,
|
||||
builder: newFSRMQuotaCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "hyperv",
|
||||
flags: nil,
|
||||
builder: newHyperVCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "iis",
|
||||
flags: newIISCollectorFlags,
|
||||
builder: newIISCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{
|
||||
"Web Service",
|
||||
"APP_POOL_WAS",
|
||||
"Web Service Cache",
|
||||
"W3SVC_W3WP",
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "logical_disk",
|
||||
flags: newLogicalDiskCollectorFlags,
|
||||
builder: newLogicalDiskCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"LogicalDisk"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "logon",
|
||||
flags: nil,
|
||||
builder: newLogonCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "memory",
|
||||
flags: nil,
|
||||
builder: newMemoryCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Memory"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "mscluster_cluster",
|
||||
flags: nil,
|
||||
builder: newMSCluster_ClusterCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mscluster_network",
|
||||
flags: nil,
|
||||
builder: newMSCluster_NetworkCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mscluster_node",
|
||||
flags: nil,
|
||||
builder: newMSCluster_NodeCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mscluster_resource",
|
||||
flags: nil,
|
||||
builder: newMSCluster_ResourceCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mscluster_resourcegroup",
|
||||
flags: nil,
|
||||
builder: newMSCluster_ResourceGroupCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "msmq",
|
||||
flags: newMSMQCollectorFlags,
|
||||
builder: newMSMQCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mssql",
|
||||
flags: newMSSQLCollectorFlags,
|
||||
builder: newMSSQLCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "net",
|
||||
flags: newNetworkCollectorFlags,
|
||||
builder: newNetworkCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Network Interface"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "netframework_clrexceptions",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRExceptionsCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrinterop",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRInteropCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrjit",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRJitCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrloading",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRLoadingCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrlocksandthreads",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRLocksAndThreadsCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrmemory",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRMemoryCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrremoting",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRRemotingCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrsecurity",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRSecurityCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "nps",
|
||||
builder: newNPSCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "os",
|
||||
flags: nil,
|
||||
builder: newOSCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Paging File"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "physical_disk",
|
||||
flags: newPhysicalDiskCollectorFlags,
|
||||
builder: NewPhysicalDiskCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"PhysicalDisk"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "process",
|
||||
flags: newProcessCollectorFlags,
|
||||
builder: newProcessCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Process"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remote_fx",
|
||||
flags: nil,
|
||||
builder: newRemoteFx,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"RemoteFX Network"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scheduled_task",
|
||||
flags: newScheduledTaskFlags,
|
||||
builder: newScheduledTask,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "service",
|
||||
flags: newServiceCollectorFlags,
|
||||
builder: newserviceCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "smtp",
|
||||
flags: newSMTPCollectorFlags,
|
||||
builder: newSMTPCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"SMTP Server"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "system",
|
||||
flags: nil,
|
||||
builder: newSystemCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"System"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "teradici_pcoip",
|
||||
flags: nil,
|
||||
builder: newTeradiciPcoipCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "tcp",
|
||||
flags: nil,
|
||||
builder: newTCPCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"TCPv4"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "terminal_services",
|
||||
flags: nil,
|
||||
builder: newTerminalServicesCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{
|
||||
"Terminal Services",
|
||||
"Terminal Services Session",
|
||||
"Remote Desktop Connection Broker Counterset",
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "textfile",
|
||||
flags: newTextFileCollectorFlags,
|
||||
builder: newTextFileCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "thermalzone",
|
||||
flags: nil,
|
||||
builder: newThermalZoneCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "time",
|
||||
flags: nil,
|
||||
builder: newTimeCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Windows Time Service"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "vmware",
|
||||
flags: nil,
|
||||
builder: newVmwareCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "vmware_blast",
|
||||
flags: nil,
|
||||
builder: newVmwareBlastCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
}
|
||||
|
||||
// RegisterCollectorsFlags To be called by the exporter for collector initialisation before running app.Parse
|
||||
func RegisterCollectorsFlags(app *kingpin.Application) {
|
||||
for _, v := range collectors {
|
||||
if v.flags != nil {
|
||||
v.flags(app)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterCollectors To be called by the exporter for collector initialisation
|
||||
func RegisterCollectors(logger log.Logger) {
|
||||
for _, v := range collectors {
|
||||
var perfCounterNames []string
|
||||
|
||||
if v.perfCounterFunc != nil {
|
||||
perfCounterNames = v.perfCounterFunc(logger)
|
||||
}
|
||||
|
||||
registerCollector(v.name, v.builder, perfCounterNames...)
|
||||
}
|
||||
}
|
||||
@@ -1,391 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagLogicalDiskVolumeOldExclude = "collector.logical_disk.volume-blacklist"
|
||||
FlagLogicalDiskVolumeOldInclude = "collector.logical_disk.volume-whitelist"
|
||||
|
||||
FlagLogicalDiskVolumeExclude = "collector.logical_disk.volume-exclude"
|
||||
FlagLogicalDiskVolumeInclude = "collector.logical_disk.volume-include"
|
||||
)
|
||||
|
||||
var (
|
||||
volumeOldInclude *string
|
||||
volumeOldExclude *string
|
||||
|
||||
volumeInclude *string
|
||||
volumeExclude *string
|
||||
|
||||
volumeIncludeSet bool
|
||||
volumeExcludeSet bool
|
||||
)
|
||||
|
||||
// A LogicalDiskCollector is a Prometheus collector for perflib logicalDisk metrics
|
||||
type LogicalDiskCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
RequestsQueued *prometheus.Desc
|
||||
AvgReadQueue *prometheus.Desc
|
||||
AvgWriteQueue *prometheus.Desc
|
||||
ReadBytesTotal *prometheus.Desc
|
||||
ReadsTotal *prometheus.Desc
|
||||
WriteBytesTotal *prometheus.Desc
|
||||
WritesTotal *prometheus.Desc
|
||||
ReadTime *prometheus.Desc
|
||||
WriteTime *prometheus.Desc
|
||||
TotalSpace *prometheus.Desc
|
||||
FreeSpace *prometheus.Desc
|
||||
IdleTime *prometheus.Desc
|
||||
SplitIOs *prometheus.Desc
|
||||
ReadLatency *prometheus.Desc
|
||||
WriteLatency *prometheus.Desc
|
||||
ReadWriteLatency *prometheus.Desc
|
||||
|
||||
volumeIncludePattern *regexp.Regexp
|
||||
volumeExcludePattern *regexp.Regexp
|
||||
}
|
||||
|
||||
// newLogicalDiskCollectorFlags ...
|
||||
func newLogicalDiskCollectorFlags(app *kingpin.Application) {
|
||||
volumeInclude = app.Flag(
|
||||
FlagLogicalDiskVolumeInclude,
|
||||
"Regexp of volumes to include. Volume name must both match include and not match exclude to be included.",
|
||||
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
|
||||
volumeIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
volumeExclude = app.Flag(
|
||||
FlagLogicalDiskVolumeExclude,
|
||||
"Regexp of volumes to exclude. Volume name must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
volumeExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
volumeOldInclude = app.Flag(
|
||||
FlagLogicalDiskVolumeOldInclude,
|
||||
"DEPRECATED: Use --collector.logical_disk.volume-include",
|
||||
).Hidden().String()
|
||||
volumeOldExclude = app.Flag(
|
||||
FlagLogicalDiskVolumeOldExclude,
|
||||
"DEPRECATED: Use --collector.logical_disk.volume-exclude",
|
||||
).Hidden().String()
|
||||
}
|
||||
|
||||
// newLogicalDiskCollector ...
|
||||
func newLogicalDiskCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "logical_disk"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *volumeOldExclude != "" {
|
||||
if !volumeExcludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.logical_disk.volume-blacklist is DEPRECATED and will be removed in a future release, use --collector.logical_disk.volume-exclude")
|
||||
*volumeExclude = *volumeOldExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.logical_disk.volume-blacklist and --collector.logical_disk.volume-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
if *volumeOldInclude != "" {
|
||||
if !volumeIncludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.logical_disk.volume-whitelist is DEPRECATED and will be removed in a future release, use --collector.logical_disk.volume-include")
|
||||
*volumeInclude = *volumeOldInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.logical_disk.volume-whitelist and --collector.logical_disk.volume-include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
return &LogicalDiskCollector{
|
||||
logger: logger,
|
||||
|
||||
RequestsQueued: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "requests_queued"),
|
||||
"The number of requests queued to the disk (LogicalDisk.CurrentDiskQueueLength)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
AvgReadQueue: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "avg_read_requests_queued"),
|
||||
"Average number of read requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskReadQueueLength)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
AvgWriteQueue: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "avg_write_requests_queued"),
|
||||
"Average number of write requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskWriteQueueLength)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadBytesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_bytes_total"),
|
||||
"The number of bytes transferred from the disk during read operations (LogicalDisk.DiskReadBytesPerSec)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "reads_total"),
|
||||
"The number of read operations on the disk (LogicalDisk.DiskReadsPerSec)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WriteBytesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_bytes_total"),
|
||||
"The number of bytes transferred to the disk during write operations (LogicalDisk.DiskWriteBytesPerSec)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WritesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "writes_total"),
|
||||
"The number of write operations on the disk (LogicalDisk.DiskWritesPerSec)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_seconds_total"),
|
||||
"Seconds that the disk was busy servicing read requests (LogicalDisk.PercentDiskReadTime)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WriteTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_seconds_total"),
|
||||
"Seconds that the disk was busy servicing write requests (LogicalDisk.PercentDiskWriteTime)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FreeSpace: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "free_bytes"),
|
||||
"Free space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
TotalSpace: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "size_bytes"),
|
||||
"Total space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace_Base)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
IdleTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "idle_seconds_total"),
|
||||
"Seconds that the disk was idle (LogicalDisk.PercentIdleTime)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
SplitIOs: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "split_ios_total"),
|
||||
"The number of I/Os to the disk were split into multiple I/Os (LogicalDisk.SplitIOPerSec)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_latency_seconds_total"),
|
||||
"Shows the average time, in seconds, of a read operation from the disk (LogicalDisk.AvgDiskSecPerRead)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WriteLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_latency_seconds_total"),
|
||||
"Shows the average time, in seconds, of a write operation to the disk (LogicalDisk.AvgDiskSecPerWrite)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadWriteLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_write_latency_seconds_total"),
|
||||
"Shows the time, in seconds, of the average disk transfer (LogicalDisk.AvgDiskSecPerTransfer)",
|
||||
[]string{"volume"},
|
||||
nil,
|
||||
),
|
||||
|
||||
volumeIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeInclude)),
|
||||
volumeExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeExclude)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *LogicalDiskCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting logical_disk metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Win32_PerfRawData_PerfDisk_LogicalDisk docs:
|
||||
// - https://msdn.microsoft.com/en-us/windows/hardware/aa394307(v=vs.71) - Win32_PerfRawData_PerfDisk_LogicalDisk class
|
||||
// - https://msdn.microsoft.com/en-us/library/ms803973.aspx - LogicalDisk object reference
|
||||
type logicalDisk struct {
|
||||
Name string
|
||||
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
|
||||
AvgDiskReadQueueLength float64 `perflib:"Avg. Disk Read Queue Length"`
|
||||
AvgDiskWriteQueueLength float64 `perflib:"Avg. Disk Write Queue Length"`
|
||||
DiskReadBytesPerSec float64 `perflib:"Disk Read Bytes/sec"`
|
||||
DiskReadsPerSec float64 `perflib:"Disk Reads/sec"`
|
||||
DiskWriteBytesPerSec float64 `perflib:"Disk Write Bytes/sec"`
|
||||
DiskWritesPerSec float64 `perflib:"Disk Writes/sec"`
|
||||
PercentDiskReadTime float64 `perflib:"% Disk Read Time"`
|
||||
PercentDiskWriteTime float64 `perflib:"% Disk Write Time"`
|
||||
PercentFreeSpace float64 `perflib:"% Free Space_Base"`
|
||||
PercentFreeSpace_Base float64 `perflib:"Free Megabytes"`
|
||||
PercentIdleTime float64 `perflib:"% Idle Time"`
|
||||
SplitIOPerSec float64 `perflib:"Split IO/Sec"`
|
||||
AvgDiskSecPerRead float64 `perflib:"Avg. Disk sec/Read"`
|
||||
AvgDiskSecPerWrite float64 `perflib:"Avg. Disk sec/Write"`
|
||||
AvgDiskSecPerTransfer float64 `perflib:"Avg. Disk sec/Transfer"`
|
||||
}
|
||||
|
||||
func (c *LogicalDiskCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []logicalDisk
|
||||
if err := unmarshalObject(ctx.perfObjects["LogicalDisk"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, volume := range dst {
|
||||
if volume.Name == "_Total" ||
|
||||
c.volumeExcludePattern.MatchString(volume.Name) ||
|
||||
!c.volumeIncludePattern.MatchString(volume.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RequestsQueued,
|
||||
prometheus.GaugeValue,
|
||||
volume.CurrentDiskQueueLength,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AvgReadQueue,
|
||||
prometheus.GaugeValue,
|
||||
volume.AvgDiskReadQueueLength*ticksToSecondsScaleFactor,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AvgWriteQueue,
|
||||
prometheus.GaugeValue,
|
||||
volume.AvgDiskWriteQueueLength*ticksToSecondsScaleFactor,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadBytesTotal,
|
||||
prometheus.CounterValue,
|
||||
volume.DiskReadBytesPerSec,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
volume.DiskReadsPerSec,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteBytesTotal,
|
||||
prometheus.CounterValue,
|
||||
volume.DiskWriteBytesPerSec,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WritesTotal,
|
||||
prometheus.CounterValue,
|
||||
volume.DiskWritesPerSec,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadTime,
|
||||
prometheus.CounterValue,
|
||||
volume.PercentDiskReadTime,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteTime,
|
||||
prometheus.CounterValue,
|
||||
volume.PercentDiskWriteTime,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FreeSpace,
|
||||
prometheus.GaugeValue,
|
||||
volume.PercentFreeSpace_Base*1024*1024,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalSpace,
|
||||
prometheus.GaugeValue,
|
||||
volume.PercentFreeSpace*1024*1024,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.IdleTime,
|
||||
prometheus.CounterValue,
|
||||
volume.PercentIdleTime,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SplitIOs,
|
||||
prometheus.CounterValue,
|
||||
volume.SplitIOPerSec,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadLatency,
|
||||
prometheus.CounterValue,
|
||||
volume.AvgDiskSecPerRead*ticksToSecondsScaleFactor,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteLatency,
|
||||
prometheus.CounterValue,
|
||||
volume.AvgDiskSecPerWrite*ticksToSecondsScaleFactor,
|
||||
volume.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadWriteLatency,
|
||||
prometheus.CounterValue,
|
||||
volume.AvgDiskSecPerTransfer*ticksToSecondsScaleFactor,
|
||||
volume.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkLogicalDiskCollector(b *testing.B) {
|
||||
// Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all disks.
|
||||
localVolumeInclude := ".+"
|
||||
volumeInclude = &localVolumeInclude
|
||||
|
||||
benchmarkCollector(b, "logical_disk", newLogicalDiskCollector)
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkLogonCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newLogonCollector)
|
||||
}
|
||||
@@ -1,513 +0,0 @@
|
||||
// returns data points from Win32_PerfRawData_PerfOS_Memory
|
||||
// <add link to documentation here> - Win32_PerfRawData_PerfOS_Memory class
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// A MemoryCollector is a Prometheus collector for perflib Memory metrics
|
||||
type MemoryCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AvailableBytes *prometheus.Desc
|
||||
CacheBytes *prometheus.Desc
|
||||
CacheBytesPeak *prometheus.Desc
|
||||
CacheFaultsTotal *prometheus.Desc
|
||||
CommitLimit *prometheus.Desc
|
||||
CommittedBytes *prometheus.Desc
|
||||
DemandZeroFaultsTotal *prometheus.Desc
|
||||
FreeAndZeroPageListBytes *prometheus.Desc
|
||||
FreeSystemPageTableEntries *prometheus.Desc
|
||||
ModifiedPageListBytes *prometheus.Desc
|
||||
PageFaultsTotal *prometheus.Desc
|
||||
SwapPageReadsTotal *prometheus.Desc
|
||||
SwapPagesReadTotal *prometheus.Desc
|
||||
SwapPagesWrittenTotal *prometheus.Desc
|
||||
SwapPageOperationsTotal *prometheus.Desc
|
||||
SwapPageWritesTotal *prometheus.Desc
|
||||
PoolNonpagedAllocsTotal *prometheus.Desc
|
||||
PoolNonpagedBytes *prometheus.Desc
|
||||
PoolPagedAllocsTotal *prometheus.Desc
|
||||
PoolPagedBytes *prometheus.Desc
|
||||
PoolPagedResidentBytes *prometheus.Desc
|
||||
StandbyCacheCoreBytes *prometheus.Desc
|
||||
StandbyCacheNormalPriorityBytes *prometheus.Desc
|
||||
StandbyCacheReserveBytes *prometheus.Desc
|
||||
SystemCacheResidentBytes *prometheus.Desc
|
||||
SystemCodeResidentBytes *prometheus.Desc
|
||||
SystemCodeTotalBytes *prometheus.Desc
|
||||
SystemDriverResidentBytes *prometheus.Desc
|
||||
SystemDriverTotalBytes *prometheus.Desc
|
||||
TransitionFaultsTotal *prometheus.Desc
|
||||
TransitionPagesRepurposedTotal *prometheus.Desc
|
||||
WriteCopiesTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
// newMemoryCollector ...
|
||||
func newMemoryCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "memory"
|
||||
|
||||
return &MemoryCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
AvailableBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "available_bytes"),
|
||||
"The amount of physical memory immediately available for allocation to a process or for system use. It is equal to the sum of memory assigned to"+
|
||||
" the standby (cached), free and zero page lists (AvailableBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
CacheBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cache_bytes"),
|
||||
"(CacheBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
CacheBytesPeak: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cache_bytes_peak"),
|
||||
"(CacheBytesPeak)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
CacheFaultsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cache_faults_total"),
|
||||
"Number of faults which occur when a page sought in the file system cache is not found there and must be retrieved from elsewhere in memory (soft fault) "+
|
||||
"or from disk (hard fault) (Cache Faults/sec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
CommitLimit: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "commit_limit"),
|
||||
"(CommitLimit)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
CommittedBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "committed_bytes"),
|
||||
"(CommittedBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DemandZeroFaultsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "demand_zero_faults_total"),
|
||||
"The number of zeroed pages required to satisfy faults. Zeroed pages, pages emptied of previously stored data and filled with zeros, are a security"+
|
||||
" feature of Windows that prevent processes from seeing data stored by earlier processes that used the memory space (Demand Zero Faults/sec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FreeAndZeroPageListBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "free_and_zero_page_list_bytes"),
|
||||
"The amount of physical memory, in bytes, that is assigned to the free and zero page lists. This memory does not contain cached data. It is immediately"+
|
||||
" available for allocation to a process or for system use (FreeAndZeroPageListBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FreeSystemPageTableEntries: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "free_system_page_table_entries"),
|
||||
"(FreeSystemPageTableEntries)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ModifiedPageListBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "modified_page_list_bytes"),
|
||||
"The amount of physical memory, in bytes, that is assigned to the modified page list. This memory contains cached data and code that is not actively in "+
|
||||
"use by processes, the system and the system cache (ModifiedPageListBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PageFaultsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "page_faults_total"),
|
||||
"Overall rate at which faulted pages are handled by the processor (Page Faults/sec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SwapPageReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "swap_page_reads_total"),
|
||||
"Number of disk page reads (a single read operation reading several pages is still only counted once) (PageReadsPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SwapPagesReadTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "swap_pages_read_total"),
|
||||
"Number of pages read across all page reads (ie counting all pages read even if they are read in a single operation) (PagesInputPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SwapPagesWrittenTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "swap_pages_written_total"),
|
||||
"Number of pages written across all page writes (ie counting all pages written even if they are written in a single operation) (PagesOutputPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SwapPageOperationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "swap_page_operations_total"),
|
||||
"Total number of swap page read and writes (PagesPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SwapPageWritesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "swap_page_writes_total"),
|
||||
"Number of disk page writes (a single write operation writing several pages is still only counted once) (PageWritesPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PoolNonpagedAllocsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pool_nonpaged_allocs_total"),
|
||||
"The number of calls to allocate space in the nonpaged pool. The nonpaged pool is an area of system memory area for objects that cannot be written"+
|
||||
" to disk, and must remain in physical memory as long as they are allocated (PoolNonpagedAllocs)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PoolNonpagedBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pool_nonpaged_bytes"),
|
||||
"Number of bytes in the non-paged pool, an area of the system virtual memory that is used for objects that cannot be written to disk, but must "+
|
||||
"remain in physical memory as long as they are allocated (PoolNonpagedBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PoolPagedAllocsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pool_paged_allocs_total"),
|
||||
"Number of calls to allocate space in the paged pool, regardless of the amount of space allocated in each call (PoolPagedAllocs)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PoolPagedBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pool_paged_bytes"),
|
||||
"(PoolPagedBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PoolPagedResidentBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pool_paged_resident_bytes"),
|
||||
"The size, in bytes, of the portion of the paged pool that is currently resident and active in physical memory. The paged pool is an area of the "+
|
||||
"system virtual memory that is used for objects that can be written to disk when they are not being used (PoolPagedResidentBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
StandbyCacheCoreBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "standby_cache_core_bytes"),
|
||||
"The amount of physical memory, in bytes, that is assigned to the core standby cache page lists. This memory contains cached data and code that is "+
|
||||
"not actively in use by processes, the system and the system cache (StandbyCacheCoreBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
StandbyCacheNormalPriorityBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "standby_cache_normal_priority_bytes"),
|
||||
"The amount of physical memory, in bytes, that is assigned to the normal priority standby cache page lists. This memory contains cached data and "+
|
||||
"code that is not actively in use by processes, the system and the system cache (StandbyCacheNormalPriorityBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
StandbyCacheReserveBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "standby_cache_reserve_bytes"),
|
||||
"The amount of physical memory, in bytes, that is assigned to the reserve standby cache page lists. This memory contains cached data and code "+
|
||||
"that is not actively in use by processes, the system and the system cache (StandbyCacheReserveBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SystemCacheResidentBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "system_cache_resident_bytes"),
|
||||
"The size, in bytes, of the portion of the system file cache which is currently resident and active in physical memory (SystemCacheResidentBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SystemCodeResidentBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "system_code_resident_bytes"),
|
||||
"The size, in bytes, of the pageable operating system code that is currently resident and active in physical memory (SystemCodeResidentBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SystemCodeTotalBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "system_code_total_bytes"),
|
||||
"The size, in bytes, of the pageable operating system code currently mapped into the system virtual address space (SystemCodeTotalBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SystemDriverResidentBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "system_driver_resident_bytes"),
|
||||
"The size, in bytes, of the pageable physical memory being used by device drivers. It is the working set (physical memory area) of the drivers (SystemDriverResidentBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SystemDriverTotalBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "system_driver_total_bytes"),
|
||||
"The size, in bytes, of the pageable virtual memory currently being used by device drivers. Pageable memory can be written to disk when it is not being used (SystemDriverTotalBytes)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TransitionFaultsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "transition_faults_total"),
|
||||
"Number of faults rate at which page faults are resolved by recovering pages that were being used by another process sharing the page, or were on the "+
|
||||
"modified page list or the standby list, or were being written to disk at the time of the page fault (TransitionFaultsPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TransitionPagesRepurposedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "transition_pages_repurposed_total"),
|
||||
"Transition Pages RePurposed is the rate at which the number of transition cache pages were reused for a different purpose (TransitionPagesRePurposedPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
WriteCopiesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_copies_total"),
|
||||
"The number of page faults caused by attempting to write that were satisfied by copying the page from elsewhere in physical memory (WriteCopiesPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MemoryCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting memory metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type memory struct {
|
||||
AvailableBytes float64 `perflib:"Available Bytes"`
|
||||
AvailableKBytes float64 `perflib:"Available KBytes"`
|
||||
AvailableMBytes float64 `perflib:"Available MBytes"`
|
||||
CacheBytes float64 `perflib:"Cache Bytes"`
|
||||
CacheBytesPeak float64 `perflib:"Cache Bytes Peak"`
|
||||
CacheFaultsPersec float64 `perflib:"Cache Faults/sec"`
|
||||
CommitLimit float64 `perflib:"Commit Limit"`
|
||||
CommittedBytes float64 `perflib:"Committed Bytes"`
|
||||
DemandZeroFaultsPersec float64 `perflib:"Demand Zero Faults/sec"`
|
||||
FreeAndZeroPageListBytes float64 `perflib:"Free & Zero Page List Bytes"`
|
||||
FreeSystemPageTableEntries float64 `perflib:"Free System Page Table Entries"`
|
||||
ModifiedPageListBytes float64 `perflib:"Modified Page List Bytes"`
|
||||
PageFaultsPersec float64 `perflib:"Page Faults/sec"`
|
||||
PageReadsPersec float64 `perflib:"Page Reads/sec"`
|
||||
PagesInputPersec float64 `perflib:"Pages Input/sec"`
|
||||
PagesOutputPersec float64 `perflib:"Pages Output/sec"`
|
||||
PagesPersec float64 `perflib:"Pages/sec"`
|
||||
PageWritesPersec float64 `perflib:"Page Writes/sec"`
|
||||
PoolNonpagedAllocs float64 `perflib:"Pool Nonpaged Allocs"`
|
||||
PoolNonpagedBytes float64 `perflib:"Pool Nonpaged Bytes"`
|
||||
PoolPagedAllocs float64 `perflib:"Pool Paged Allocs"`
|
||||
PoolPagedBytes float64 `perflib:"Pool Paged Bytes"`
|
||||
PoolPagedResidentBytes float64 `perflib:"Pool Paged Resident Bytes"`
|
||||
StandbyCacheCoreBytes float64 `perflib:"Standby Cache Core Bytes"`
|
||||
StandbyCacheNormalPriorityBytes float64 `perflib:"Standby Cache Normal Priority Bytes"`
|
||||
StandbyCacheReserveBytes float64 `perflib:"Standby Cache Reserve Bytes"`
|
||||
SystemCacheResidentBytes float64 `perflib:"System Cache Resident Bytes"`
|
||||
SystemCodeResidentBytes float64 `perflib:"System Code Resident Bytes"`
|
||||
SystemCodeTotalBytes float64 `perflib:"System Code Total Bytes"`
|
||||
SystemDriverResidentBytes float64 `perflib:"System Driver Resident Bytes"`
|
||||
SystemDriverTotalBytes float64 `perflib:"System Driver Total Bytes"`
|
||||
TransitionFaultsPersec float64 `perflib:"Transition Faults/sec"`
|
||||
TransitionPagesRePurposedPersec float64 `perflib:"Transition Pages RePurposed/sec"`
|
||||
WriteCopiesPersec float64 `perflib:"Write Copies/sec"`
|
||||
}
|
||||
|
||||
func (c *MemoryCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []memory
|
||||
if err := unmarshalObject(ctx.perfObjects["Memory"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AvailableBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].AvailableBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CacheBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].CacheBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CacheBytesPeak,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].CacheBytesPeak,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CacheFaultsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].CacheFaultsPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CommitLimit,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].CommitLimit,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CommittedBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].CommittedBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DemandZeroFaultsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DemandZeroFaultsPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FreeAndZeroPageListBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].FreeAndZeroPageListBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FreeSystemPageTableEntries,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].FreeSystemPageTableEntries,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ModifiedPageListBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].ModifiedPageListBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PageFaultsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PageFaultsPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SwapPageReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PageReadsPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SwapPagesReadTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PagesInputPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SwapPagesWrittenTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PagesOutputPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SwapPageOperationsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PagesPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SwapPageWritesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PageWritesPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PoolNonpagedAllocsTotal,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].PoolNonpagedAllocs,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PoolNonpagedBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].PoolNonpagedBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PoolPagedAllocsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PoolPagedAllocs,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PoolPagedBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].PoolPagedBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PoolPagedResidentBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].PoolPagedResidentBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.StandbyCacheCoreBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].StandbyCacheCoreBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.StandbyCacheNormalPriorityBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].StandbyCacheNormalPriorityBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.StandbyCacheReserveBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].StandbyCacheReserveBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SystemCacheResidentBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].SystemCacheResidentBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SystemCodeResidentBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].SystemCodeResidentBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SystemCodeTotalBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].SystemCodeTotalBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SystemDriverResidentBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].SystemDriverResidentBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SystemDriverTotalBytes,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].SystemDriverTotalBytes,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TransitionFaultsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].TransitionFaultsPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TransitionPagesRepurposedTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].TransitionPagesRePurposedPersec,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteCopiesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].WriteCopiesPersec,
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkMemoryCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "memory", newMemoryCollector)
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A MSCluster_NetworkCollector is a Prometheus collector for WMI MSCluster_Network metrics
|
||||
type MSCluster_NetworkCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
Characteristics *prometheus.Desc
|
||||
Flags *prometheus.Desc
|
||||
Metric *prometheus.Desc
|
||||
Role *prometheus.Desc
|
||||
State *prometheus.Desc
|
||||
}
|
||||
|
||||
func newMSCluster_NetworkCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mscluster_network"
|
||||
return &MSCluster_NetworkCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
Characteristics: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
|
||||
"Provides the characteristics of the network.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
Flags: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "flags"),
|
||||
"Provides access to the flags set for the node. ",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
Metric: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
Role: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
State: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "state"),
|
||||
"Provides the current state of the network. 1-1: Unknown; 0: Unavailable; 1: Down; 2: Partitioned; 3: Up",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MSCluster_Network docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-network
|
||||
type MSCluster_Network struct {
|
||||
Name string
|
||||
|
||||
Characteristics uint
|
||||
Flags uint
|
||||
Metric uint
|
||||
Role uint
|
||||
State uint
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MSCluster_NetworkCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []MSCluster_Network
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range dst {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Characteristics,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Characteristics),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Flags,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Flags),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Metric,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Metric),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Role,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Role),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.State,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.State),
|
||||
v.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A MSCluster_NodeCollector is a Prometheus collector for WMI MSCluster_Node metrics
|
||||
type MSCluster_NodeCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
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 newMSCluster_NodeCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mscluster_node"
|
||||
return &MSCluster_NodeCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
BuildNumber: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "build_number"),
|
||||
"Provides access to the node's BuildNumber property.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
Characteristics: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
|
||||
"Provides access to the characteristics set for the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
DetectedCloudPlatform: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "detected_cloud_platform"),
|
||||
"(DetectedCloudPlatform)",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
DynamicWeight: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "dynamic_weight"),
|
||||
"The dynamic vote weight of the node adjusted by dynamic quorum feature.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
Flags: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "flags"),
|
||||
"Provides access to the flags set for the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
MajorVersion: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "major_version"),
|
||||
"Provides access to the node's MajorVersion property, which specifies the major portion of the Windows version installed.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
MinorVersion: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "minor_version"),
|
||||
"Provides access to the node's MinorVersion property, which specifies the minor portion of the Windows version installed.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
NeedsPreventQuorum: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "needs_prevent_quorum"),
|
||||
"Whether the cluster service on that node should be started with prevent quorum flag.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
NodeDrainStatus: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "node_drain_status"),
|
||||
"The current node drain status of a node. 0: Not Initiated; 1: In Progress; 2: Completed; 3: Failed",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
NodeHighestVersion: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
NodeLowestVersion: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
NodeWeight: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "node_weight"),
|
||||
"The vote weight of the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
State: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "state"),
|
||||
"Returns the current state of a node. -1: Unknown; 0: Up; 1: Down; 2: Paused; 3: Joining",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
StatusInformation: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "status_information"),
|
||||
"The isolation or quarantine status of the node.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MSCluster_Node docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-node
|
||||
type MSCluster_Node struct {
|
||||
Name string
|
||||
|
||||
BuildNumber uint
|
||||
Characteristics uint
|
||||
DetectedCloudPlatform uint
|
||||
DynamicWeight uint
|
||||
Flags uint
|
||||
MajorVersion uint
|
||||
MinorVersion uint
|
||||
NeedsPreventQuorum uint
|
||||
NodeDrainStatus uint
|
||||
NodeHighestVersion uint
|
||||
NodeLowestVersion uint
|
||||
NodeWeight uint
|
||||
State uint
|
||||
StatusInformation uint
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MSCluster_NodeCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []MSCluster_Node
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range dst {
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BuildNumber,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.BuildNumber),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Characteristics,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Characteristics),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DetectedCloudPlatform,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DetectedCloudPlatform),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DynamicWeight,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DynamicWeight),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Flags,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Flags),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.MajorVersion,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.MajorVersion),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.MinorVersion,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.MinorVersion),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NeedsPreventQuorum,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NeedsPreventQuorum),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NodeDrainStatus,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NodeDrainStatus),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NodeHighestVersion,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NodeHighestVersion),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NodeLowestVersion,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NodeLowestVersion),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NodeWeight,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.NodeWeight),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.State,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.State),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.StatusInformation,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.StatusInformation),
|
||||
v.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A MSCluster_ResourceCollector is a Prometheus collector for WMI MSCluster_Resource metrics
|
||||
type MSCluster_ResourceCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
Characteristics *prometheus.Desc
|
||||
DeadlockTimeout *prometheus.Desc
|
||||
EmbeddedFailureAction *prometheus.Desc
|
||||
Flags *prometheus.Desc
|
||||
IsAlivePollInterval *prometheus.Desc
|
||||
LooksAlivePollInterval *prometheus.Desc
|
||||
MonitorProcessId *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 newMSCluster_ResourceCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mscluster_resource"
|
||||
return &MSCluster_ResourceCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
Characteristics: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
|
||||
"Provides the characteristics of the object.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
),
|
||||
DeadlockTimeout: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
EmbeddedFailureAction: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
Flags: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "flags"),
|
||||
"Provides access to the flags set for the object.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
),
|
||||
IsAlivePollInterval: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
LooksAlivePollInterval: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
MonitorProcessId: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "monitor_process_id"),
|
||||
"Provides the process ID of the resource host service that is currently hosting the resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
),
|
||||
PendingTimeout: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
ResourceClass: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
RestartAction: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
RestartDelay: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "restart_delay"),
|
||||
"Indicates the time delay before a failed resource is restarted.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
),
|
||||
RestartPeriod: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
RestartThreshold: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
RetryPeriodOnFailure: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
State: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
Subclass: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "subclass"),
|
||||
"Provides the list of references to nodes that can be the owner of this resource.",
|
||||
[]string{"type", "owner_group", "name"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MSCluster_Resource docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resource
|
||||
type MSCluster_Resource struct {
|
||||
Name string
|
||||
Type string
|
||||
OwnerGroup string
|
||||
|
||||
Characteristics uint
|
||||
DeadlockTimeout uint
|
||||
EmbeddedFailureAction uint
|
||||
Flags uint
|
||||
IsAlivePollInterval uint
|
||||
LooksAlivePollInterval uint
|
||||
MonitorProcessId uint
|
||||
PendingTimeout uint
|
||||
ResourceClass uint
|
||||
RestartAction uint
|
||||
RestartDelay uint
|
||||
RestartPeriod uint
|
||||
RestartThreshold uint
|
||||
RetryPeriodOnFailure uint
|
||||
State uint
|
||||
Subclass uint
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MSCluster_ResourceCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []MSCluster_Resource
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range dst {
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Characteristics,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Characteristics),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DeadlockTimeout,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DeadlockTimeout),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.EmbeddedFailureAction,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.EmbeddedFailureAction),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Flags,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Flags),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.IsAlivePollInterval,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.IsAlivePollInterval),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.LooksAlivePollInterval,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.LooksAlivePollInterval),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.MonitorProcessId,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.MonitorProcessId),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PendingTimeout,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.PendingTimeout),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ResourceClass,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.ResourceClass),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RestartAction,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RestartAction),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RestartDelay,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RestartDelay),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RestartPeriod,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RestartPeriod),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RestartThreshold,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RestartThreshold),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RetryPeriodOnFailure,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.RetryPeriodOnFailure),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.State,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.State),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Subclass,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Subclass),
|
||||
v.Type, v.OwnerGroup, v.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A MSCluster_ResourceGroupCollector is a Prometheus collector for WMI MSCluster_ResourceGroup metrics
|
||||
type MSCluster_ResourceGroupCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AutoFailbackType *prometheus.Desc
|
||||
Characteristics *prometheus.Desc
|
||||
ColdStartSetting *prometheus.Desc
|
||||
DefaultOwner *prometheus.Desc
|
||||
FailbackWindowEnd *prometheus.Desc
|
||||
FailbackWindowStart *prometheus.Desc
|
||||
FailoverPeriod *prometheus.Desc
|
||||
FailoverThreshold *prometheus.Desc
|
||||
FaultDomain *prometheus.Desc
|
||||
Flags *prometheus.Desc
|
||||
GroupType *prometheus.Desc
|
||||
PlacementOptions *prometheus.Desc
|
||||
Priority *prometheus.Desc
|
||||
ResiliencyPeriod *prometheus.Desc
|
||||
State *prometheus.Desc
|
||||
}
|
||||
|
||||
func newMSCluster_ResourceGroupCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mscluster_resourcegroup"
|
||||
return &MSCluster_ResourceGroupCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
AutoFailbackType: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "auto_failback_type"),
|
||||
"Provides access to the group's AutoFailbackType property.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
Characteristics: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
|
||||
"Provides the characteristics of the group.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
ColdStartSetting: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cold_start_setting"),
|
||||
"Indicates whether a group can start after a cluster cold start.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
DefaultOwner: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "default_owner"),
|
||||
"Number of the last node the resource group was activated on or explicitly moved to.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
FailbackWindowEnd: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
FailbackWindowStart: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
FailoverPeriod: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "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,
|
||||
),
|
||||
FailoverThreshold: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_threshold"),
|
||||
"The FailoverThreshold property specifies the maximum number of failover attempts.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
Flags: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "flags"),
|
||||
"Provides access to the flags set for the group. ",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
GroupType: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "group_type"),
|
||||
"The Type of the resource group.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
Priority: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "priority"),
|
||||
"Priority value of the resource group",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
ResiliencyPeriod: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "resiliency_period"),
|
||||
"The resiliency period for this group, in seconds.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
State: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "state"),
|
||||
"The current state of the resource group. -1: Unknown; 0: Online; 1: Offline; 2: Failed; 3: Partial Online; 4: Pending",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MSCluster_ResourceGroup docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resourcegroup
|
||||
type MSCluster_ResourceGroup struct {
|
||||
Name string
|
||||
|
||||
AutoFailbackType uint
|
||||
Characteristics uint
|
||||
ColdStartSetting uint
|
||||
DefaultOwner uint
|
||||
FailbackWindowEnd int
|
||||
FailbackWindowStart int
|
||||
FailoverPeriod uint
|
||||
FailoverThreshold uint
|
||||
Flags uint
|
||||
GroupType uint
|
||||
Priority uint
|
||||
ResiliencyPeriod uint
|
||||
State uint
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MSCluster_ResourceGroupCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []MSCluster_ResourceGroup
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range dst {
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AutoFailbackType,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.AutoFailbackType),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Characteristics,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Characteristics),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ColdStartSetting,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.ColdStartSetting),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DefaultOwner,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DefaultOwner),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailbackWindowEnd,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.FailbackWindowEnd),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailbackWindowStart,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.FailbackWindowStart),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverPeriod,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.FailoverPeriod),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverThreshold,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.FailoverThreshold),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Flags,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Flags),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.GroupType,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.GroupType),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Priority,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.Priority),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ResiliencyPeriod,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.ResiliencyPeriod),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.State,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.State),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagMsmqWhereClause = "collector.msmq.msmq-where"
|
||||
)
|
||||
|
||||
var (
|
||||
msmqWhereClause *string
|
||||
)
|
||||
|
||||
// A Win32_PerfRawData_MSMQ_MSMQQueueCollector is a Prometheus collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics
|
||||
type Win32_PerfRawData_MSMQ_MSMQQueueCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
BytesinJournalQueue *prometheus.Desc
|
||||
BytesinQueue *prometheus.Desc
|
||||
MessagesinJournalQueue *prometheus.Desc
|
||||
MessagesinQueue *prometheus.Desc
|
||||
|
||||
queryWhereClause string
|
||||
}
|
||||
|
||||
// newMSMQCollectorFlags ..
|
||||
func newMSMQCollectorFlags(app *kingpin.Application) {
|
||||
msmqWhereClause = app.Flag(FlagMsmqWhereClause, "WQL 'where' clause to use in WMI metrics query. Limits the response to the msmqs you specify and reduces the size of the response.").String()
|
||||
}
|
||||
|
||||
// NewWin32_PerfRawData_MSMQ_MSMQQueueCollector ...
|
||||
func newMSMQCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "msmq"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *msmqWhereClause == "" {
|
||||
_ = level.Warn(logger).Log("msg", "No where-clause specified for msmq collector. This will generate a very large number of metrics!")
|
||||
}
|
||||
|
||||
return &Win32_PerfRawData_MSMQ_MSMQQueueCollector{
|
||||
logger: logger,
|
||||
|
||||
BytesinJournalQueue: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "bytes_in_journal_queue"),
|
||||
"Size of queue journal in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
BytesinQueue: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "bytes_in_queue"),
|
||||
"Size of queue in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
MessagesinJournalQueue: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "messages_in_journal_queue"),
|
||||
"Count messages in queue journal",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
MessagesinQueue: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "messages_in_queue"),
|
||||
"Count messages in queue",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
queryWhereClause: *msmqWhereClause,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Win32_PerfRawData_MSMQ_MSMQQueueCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting msmq metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Win32_PerfRawData_MSMQ_MSMQQueue struct {
|
||||
Name string
|
||||
|
||||
BytesinJournalQueue uint64
|
||||
BytesinQueue uint64
|
||||
MessagesinJournalQueue uint64
|
||||
MessagesinQueue uint64
|
||||
}
|
||||
|
||||
func (c *Win32_PerfRawData_MSMQ_MSMQQueueCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_MSMQ_MSMQQueue
|
||||
q := queryAllWhere(&dst, c.queryWhereClause, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, msmq := range dst {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesinJournalQueue,
|
||||
prometheus.GaugeValue,
|
||||
float64(msmq.BytesinJournalQueue),
|
||||
strings.ToLower(msmq.Name),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesinQueue,
|
||||
prometheus.GaugeValue,
|
||||
float64(msmq.BytesinQueue),
|
||||
strings.ToLower(msmq.Name),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.MessagesinJournalQueue,
|
||||
prometheus.GaugeValue,
|
||||
float64(msmq.MessagesinJournalQueue),
|
||||
strings.ToLower(msmq.Name),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.MessagesinQueue,
|
||||
prometheus.GaugeValue,
|
||||
float64(msmq.MessagesinQueue),
|
||||
strings.ToLower(msmq.Name),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkMsmqCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newMSMQCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkMSSQLCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "mssql", newMSSQLCollector)
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A NETFramework_NETCLRExceptionsCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRExceptions metrics
|
||||
type NETFramework_NETCLRExceptionsCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
NumberofExcepsThrown *prometheus.Desc
|
||||
NumberofFilters *prometheus.Desc
|
||||
NumberofFinallys *prometheus.Desc
|
||||
ThrowToCatchDepth *prometheus.Desc
|
||||
}
|
||||
|
||||
// newNETFramework_NETCLRExceptionsCollector ...
|
||||
func newNETFramework_NETCLRExceptionsCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrexceptions"
|
||||
return &NETFramework_NETCLRExceptionsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
NumberofExcepsThrown: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "exceptions_thrown_total"),
|
||||
"Displays the total number of exceptions thrown since the application started. This includes both .NET exceptions and unmanaged exceptions that are converted into .NET exceptions.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
NumberofFilters: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "exceptions_filters_total"),
|
||||
"Displays the total number of .NET exception filters executed. An exception filter evaluates regardless of whether an exception is handled.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
NumberofFinallys: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "exceptions_finallys_total"),
|
||||
"Displays the total number of finally blocks executed. Only the finally blocks executed for an exception are counted; finally blocks on normal code paths are not counted by this counter.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
ThrowToCatchDepth: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "throw_to_catch_depth_total"),
|
||||
"Displays the total number of stack frames traversed, from the frame that threw the exception to the frame that handled the exception.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRExceptionsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrexceptions metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Win32_PerfRawData_NETFramework_NETCLRExceptions struct {
|
||||
Name string
|
||||
|
||||
NumberofExcepsThrown uint32
|
||||
NumberofExcepsThrownPersec uint32
|
||||
NumberofFiltersPersec uint32
|
||||
NumberofFinallysPersec uint32
|
||||
ThrowToCatchDepthPersec uint32
|
||||
}
|
||||
|
||||
func (c *NETFramework_NETCLRExceptionsCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRExceptions
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, process := range dst {
|
||||
|
||||
if process.Name == "_Global_" {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NumberofExcepsThrown,
|
||||
prometheus.CounterValue,
|
||||
float64(process.NumberofExcepsThrown),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NumberofFilters,
|
||||
prometheus.CounterValue,
|
||||
float64(process.NumberofFiltersPersec),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NumberofFinallys,
|
||||
prometheus.CounterValue,
|
||||
float64(process.NumberofFinallysPersec),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ThrowToCatchDepth,
|
||||
prometheus.CounterValue,
|
||||
float64(process.ThrowToCatchDepthPersec),
|
||||
process.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNetFrameworkNETCLRExceptionsCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRExceptionsCollector)
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A NETFramework_NETCLRInteropCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRInterop metrics
|
||||
type NETFramework_NETCLRInteropCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
NumberofCCWs *prometheus.Desc
|
||||
Numberofmarshalling *prometheus.Desc
|
||||
NumberofStubs *prometheus.Desc
|
||||
}
|
||||
|
||||
// newNETFramework_NETCLRInteropCollector ...
|
||||
func newNETFramework_NETCLRInteropCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrinterop"
|
||||
return &NETFramework_NETCLRInteropCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
NumberofCCWs: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "com_callable_wrappers_total"),
|
||||
"Displays the current number of COM callable wrappers (CCWs). A CCW is a proxy for a managed object being referenced from an unmanaged COM client.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
Numberofmarshalling: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "interop_marshalling_total"),
|
||||
"Displays the total number of times arguments and return values have been marshaled from managed to unmanaged code, and vice versa, since the application started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
NumberofStubs: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "interop_stubs_created_total"),
|
||||
"Displays the current number of stubs created by the common language runtime. Stubs are responsible for marshaling arguments and return values from managed to unmanaged code, and vice versa, during a COM interop call or a platform invoke call.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRInteropCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrinterop metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Win32_PerfRawData_NETFramework_NETCLRInterop struct {
|
||||
Name string
|
||||
|
||||
NumberofCCWs uint32
|
||||
Numberofmarshalling uint32
|
||||
NumberofStubs uint32
|
||||
NumberofTLBexportsPersec uint32
|
||||
NumberofTLBimportsPersec uint32
|
||||
}
|
||||
|
||||
func (c *NETFramework_NETCLRInteropCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRInterop
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, process := range dst {
|
||||
|
||||
if process.Name == "_Global_" {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NumberofCCWs,
|
||||
prometheus.CounterValue,
|
||||
float64(process.NumberofCCWs),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Numberofmarshalling,
|
||||
prometheus.CounterValue,
|
||||
float64(process.Numberofmarshalling),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NumberofStubs,
|
||||
prometheus.CounterValue,
|
||||
float64(process.NumberofStubs),
|
||||
process.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRInteropCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRInteropCollector)
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A NETFramework_NETCLRJitCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRJit metrics
|
||||
type NETFramework_NETCLRJitCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
NumberofMethodsJitted *prometheus.Desc
|
||||
TimeinJit *prometheus.Desc
|
||||
StandardJitFailures *prometheus.Desc
|
||||
TotalNumberofILBytesJitted *prometheus.Desc
|
||||
}
|
||||
|
||||
// newNETFramework_NETCLRJitCollector ...
|
||||
func newNETFramework_NETCLRJitCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrjit"
|
||||
return &NETFramework_NETCLRJitCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
NumberofMethodsJitted: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "jit_methods_total"),
|
||||
"Displays the total number of methods JIT-compiled since the application started. This counter does not include pre-JIT-compiled methods.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TimeinJit: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "jit_time_percent"),
|
||||
"Displays the percentage of time spent in JIT compilation. This counter is updated at the end of every JIT compilation phase. A JIT compilation phase occurs when a method and its dependencies are compiled.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
StandardJitFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "jit_standard_failures_total"),
|
||||
"Displays the peak number of methods the JIT compiler has failed to compile since the application started. This failure can occur if the MSIL cannot be verified or if there is an internal error in the JIT compiler.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TotalNumberofILBytesJitted: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "jit_il_bytes_total"),
|
||||
"Displays the total number of Microsoft intermediate language (MSIL) bytes compiled by the just-in-time (JIT) compiler since the application started",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRJitCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrjit metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Win32_PerfRawData_NETFramework_NETCLRJit struct {
|
||||
Name string
|
||||
|
||||
Frequency_PerfTime uint32
|
||||
ILBytesJittedPersec uint32
|
||||
NumberofILBytesJitted uint32
|
||||
NumberofMethodsJitted uint32
|
||||
PercentTimeinJit uint32
|
||||
StandardJitFailures uint32
|
||||
TotalNumberofILBytesJitted uint32
|
||||
}
|
||||
|
||||
func (c *NETFramework_NETCLRJitCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRJit
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, process := range dst {
|
||||
|
||||
if process.Name == "_Global_" {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NumberofMethodsJitted,
|
||||
prometheus.CounterValue,
|
||||
float64(process.NumberofMethodsJitted),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TimeinJit,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.PercentTimeinJit)/float64(process.Frequency_PerfTime),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.StandardJitFailures,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.StandardJitFailures),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalNumberofILBytesJitted,
|
||||
prometheus.CounterValue,
|
||||
float64(process.TotalNumberofILBytesJitted),
|
||||
process.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRJitCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRJitCollector)
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A NETFramework_NETCLRLoadingCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRLoading metrics
|
||||
type NETFramework_NETCLRLoadingCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
BytesinLoaderHeap *prometheus.Desc
|
||||
Currentappdomains *prometheus.Desc
|
||||
CurrentAssemblies *prometheus.Desc
|
||||
CurrentClassesLoaded *prometheus.Desc
|
||||
TotalAppdomains *prometheus.Desc
|
||||
Totalappdomainsunloaded *prometheus.Desc
|
||||
TotalAssemblies *prometheus.Desc
|
||||
TotalClassesLoaded *prometheus.Desc
|
||||
TotalNumberofLoadFailures *prometheus.Desc
|
||||
}
|
||||
|
||||
// newNETFramework_NETCLRLoadingCollector ...
|
||||
func newNETFramework_NETCLRLoadingCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrloading"
|
||||
return &NETFramework_NETCLRLoadingCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
BytesinLoaderHeap: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "loader_heap_size_bytes"),
|
||||
"Displays the current size, in bytes, of the memory committed by the class loader across all application domains. Committed memory is the physical space reserved in the disk paging file.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
Currentappdomains: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "appdomains_loaded_current"),
|
||||
"Displays the current number of application domains loaded in this application.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
CurrentAssemblies: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "assemblies_loaded_current"),
|
||||
"Displays the current number of assemblies loaded across all application domains in the currently running application. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
CurrentClassesLoaded: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "classes_loaded_current"),
|
||||
"Displays the current number of classes loaded in all assemblies.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TotalAppdomains: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "appdomains_loaded_total"),
|
||||
"Displays the peak number of application domains loaded since the application started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
Totalappdomainsunloaded: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "appdomains_unloaded_total"),
|
||||
"Displays the total number of application domains unloaded since the application started. If an application domain is loaded and unloaded multiple times, this counter increments each time the application domain is unloaded.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TotalAssemblies: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "assemblies_loaded_total"),
|
||||
"Displays the total number of assemblies loaded since the application started. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TotalClassesLoaded: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "classes_loaded_total"),
|
||||
"Displays the cumulative number of classes loaded in all assemblies since the application started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TotalNumberofLoadFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "class_load_failures_total"),
|
||||
"Displays the peak number of classes that have failed to load since the application started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRLoadingCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrloading metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Win32_PerfRawData_NETFramework_NETCLRLoading struct {
|
||||
Name string
|
||||
|
||||
AssemblySearchLength uint32
|
||||
BytesinLoaderHeap uint64
|
||||
Currentappdomains uint32
|
||||
CurrentAssemblies uint32
|
||||
CurrentClassesLoaded uint32
|
||||
PercentTimeLoading uint64
|
||||
Rateofappdomains uint32
|
||||
Rateofappdomainsunloaded uint32
|
||||
RateofAssemblies uint32
|
||||
RateofClassesLoaded uint32
|
||||
RateofLoadFailures uint32
|
||||
TotalAppdomains uint32
|
||||
Totalappdomainsunloaded uint32
|
||||
TotalAssemblies uint32
|
||||
TotalClassesLoaded uint32
|
||||
TotalNumberofLoadFailures uint32
|
||||
}
|
||||
|
||||
func (c *NETFramework_NETCLRLoadingCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRLoading
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, process := range dst {
|
||||
|
||||
if process.Name == "_Global_" {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesinLoaderHeap,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.BytesinLoaderHeap),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Currentappdomains,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.Currentappdomains),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CurrentAssemblies,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.CurrentAssemblies),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CurrentClassesLoaded,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.CurrentClassesLoaded),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalAppdomains,
|
||||
prometheus.CounterValue,
|
||||
float64(process.TotalAppdomains),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Totalappdomainsunloaded,
|
||||
prometheus.CounterValue,
|
||||
float64(process.Totalappdomainsunloaded),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalAssemblies,
|
||||
prometheus.CounterValue,
|
||||
float64(process.TotalAssemblies),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalClassesLoaded,
|
||||
prometheus.CounterValue,
|
||||
float64(process.TotalClassesLoaded),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalNumberofLoadFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(process.TotalNumberofLoadFailures),
|
||||
process.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRLoadingCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRLoadingCollector)
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A NETFramework_NETCLRLocksAndThreadsCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads metrics
|
||||
type NETFramework_NETCLRLocksAndThreadsCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
CurrentQueueLength *prometheus.Desc
|
||||
NumberofcurrentlogicalThreads *prometheus.Desc
|
||||
NumberofcurrentphysicalThreads *prometheus.Desc
|
||||
Numberofcurrentrecognizedthreads *prometheus.Desc
|
||||
Numberoftotalrecognizedthreads *prometheus.Desc
|
||||
QueueLengthPeak *prometheus.Desc
|
||||
TotalNumberofContentions *prometheus.Desc
|
||||
}
|
||||
|
||||
// newNETFramework_NETCLRLocksAndThreadsCollector ...
|
||||
func newNETFramework_NETCLRLocksAndThreadsCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrlocksandthreads"
|
||||
return &NETFramework_NETCLRLocksAndThreadsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
CurrentQueueLength: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "current_queue_length"),
|
||||
"Displays the total number of threads that are currently waiting to acquire a managed lock in the application.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
NumberofcurrentlogicalThreads: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "current_logical_threads"),
|
||||
"Displays the number of current managed thread objects in the application. This counter maintains the count of both running and stopped threads. ",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
NumberofcurrentphysicalThreads: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "physical_threads_current"),
|
||||
"Displays the number of native operating system threads created and owned by the common language runtime to act as underlying threads for managed thread objects. This counter's value does not include the threads used by the runtime in its internal operations; it is a subset of the threads in the operating system process.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
Numberofcurrentrecognizedthreads: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "recognized_threads_current"),
|
||||
"Displays the number of threads that are currently recognized by the runtime. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
Numberoftotalrecognizedthreads: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "recognized_threads_total"),
|
||||
"Displays the total number of threads that have been recognized by the runtime since the application started. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
QueueLengthPeak: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "queue_length_total"),
|
||||
"Displays the total number of threads that waited to acquire a managed lock since the application started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TotalNumberofContentions: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "contentions_total"),
|
||||
"Displays the total number of times that threads in the runtime have attempted to acquire a managed lock unsuccessfully.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRLocksAndThreadsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrlocksandthreads metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads struct {
|
||||
Name string
|
||||
|
||||
ContentionRatePersec uint32
|
||||
CurrentQueueLength uint32
|
||||
NumberofcurrentlogicalThreads uint32
|
||||
NumberofcurrentphysicalThreads uint32
|
||||
Numberofcurrentrecognizedthreads uint32
|
||||
Numberoftotalrecognizedthreads uint32
|
||||
QueueLengthPeak uint32
|
||||
QueueLengthPersec uint32
|
||||
RateOfRecognizedThreadsPersec uint32
|
||||
TotalNumberofContentions uint32
|
||||
}
|
||||
|
||||
func (c *NETFramework_NETCLRLocksAndThreadsCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, process := range dst {
|
||||
|
||||
if process.Name == "_Global_" {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CurrentQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.CurrentQueueLength),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NumberofcurrentlogicalThreads,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.NumberofcurrentlogicalThreads),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NumberofcurrentphysicalThreads,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.NumberofcurrentphysicalThreads),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Numberofcurrentrecognizedthreads,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.Numberofcurrentrecognizedthreads),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Numberoftotalrecognizedthreads,
|
||||
prometheus.CounterValue,
|
||||
float64(process.Numberoftotalrecognizedthreads),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.QueueLengthPeak,
|
||||
prometheus.CounterValue,
|
||||
float64(process.QueueLengthPeak),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalNumberofContentions,
|
||||
prometheus.CounterValue,
|
||||
float64(process.TotalNumberofContentions),
|
||||
process.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRLocksAndThreadsCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRLocksAndThreadsCollector)
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRMemoryCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRMemoryCollector)
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A NETFramework_NETCLRRemotingCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRRemoting metrics
|
||||
type NETFramework_NETCLRRemotingCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
Channels *prometheus.Desc
|
||||
ContextBoundClassesLoaded *prometheus.Desc
|
||||
ContextBoundObjects *prometheus.Desc
|
||||
ContextProxies *prometheus.Desc
|
||||
Contexts *prometheus.Desc
|
||||
TotalRemoteCalls *prometheus.Desc
|
||||
}
|
||||
|
||||
// newNETFramework_NETCLRRemotingCollector ...
|
||||
func newNETFramework_NETCLRRemotingCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrremoting"
|
||||
return &NETFramework_NETCLRRemotingCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
Channels: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "channels_total"),
|
||||
"Displays the total number of remoting channels registered across all application domains since application started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
ContextBoundClassesLoaded: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "context_bound_classes_loaded"),
|
||||
"Displays the current number of context-bound classes that are loaded.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
ContextBoundObjects: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "context_bound_objects_total"),
|
||||
"Displays the total number of context-bound objects allocated.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
ContextProxies: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "context_proxies_total"),
|
||||
"Displays the total number of remoting proxy objects in this process since it started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
Contexts: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "contexts"),
|
||||
"Displays the current number of remoting contexts in the application.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TotalRemoteCalls: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "remote_calls_total"),
|
||||
"Displays the total number of remote procedure calls invoked since the application started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRRemotingCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrremoting metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Win32_PerfRawData_NETFramework_NETCLRRemoting struct {
|
||||
Name string
|
||||
|
||||
Channels uint32
|
||||
ContextBoundClassesLoaded uint32
|
||||
ContextBoundObjectsAllocPersec uint32
|
||||
ContextProxies uint32
|
||||
Contexts uint32
|
||||
RemoteCallsPersec uint32
|
||||
TotalRemoteCalls uint32
|
||||
}
|
||||
|
||||
func (c *NETFramework_NETCLRRemotingCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRRemoting
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, process := range dst {
|
||||
|
||||
if process.Name == "_Global_" {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Channels,
|
||||
prometheus.CounterValue,
|
||||
float64(process.Channels),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ContextBoundClassesLoaded,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.ContextBoundClassesLoaded),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ContextBoundObjects,
|
||||
prometheus.CounterValue,
|
||||
float64(process.ContextBoundObjectsAllocPersec),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ContextProxies,
|
||||
prometheus.CounterValue,
|
||||
float64(process.ContextProxies),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Contexts,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.Contexts),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRemoteCalls,
|
||||
prometheus.CounterValue,
|
||||
float64(process.TotalRemoteCalls),
|
||||
process.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRRemotingCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRRemotingCollector)
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A NETFramework_NETCLRSecurityCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRSecurity metrics
|
||||
type NETFramework_NETCLRSecurityCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
NumberLinkTimeChecks *prometheus.Desc
|
||||
TimeinRTchecks *prometheus.Desc
|
||||
StackWalkDepth *prometheus.Desc
|
||||
TotalRuntimeChecks *prometheus.Desc
|
||||
}
|
||||
|
||||
// newNETFramework_NETCLRSecurityCollector ...
|
||||
func newNETFramework_NETCLRSecurityCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrsecurity"
|
||||
return &NETFramework_NETCLRSecurityCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
NumberLinkTimeChecks: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "link_time_checks_total"),
|
||||
"Displays the total number of link-time code access security checks since the application started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TimeinRTchecks: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "rt_checks_time_percent"),
|
||||
"Displays the percentage of time spent performing runtime code access security checks in the last sample.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
StackWalkDepth: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "stack_walk_depth"),
|
||||
"Displays the depth of the stack during that last runtime code access security check.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
TotalRuntimeChecks: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "runtime_checks_total"),
|
||||
"Displays the total number of runtime code access security checks performed since the application started.",
|
||||
[]string{"process"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRSecurityCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrsecurity metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Win32_PerfRawData_NETFramework_NETCLRSecurity struct {
|
||||
Name string
|
||||
|
||||
Frequency_PerfTime uint32
|
||||
NumberLinkTimeChecks uint32
|
||||
PercentTimeinRTchecks uint32
|
||||
PercentTimeSigAuthenticating uint64
|
||||
StackWalkDepth uint32
|
||||
TotalRuntimeChecks uint32
|
||||
}
|
||||
|
||||
func (c *NETFramework_NETCLRSecurityCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRSecurity
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, process := range dst {
|
||||
|
||||
if process.Name == "_Global_" {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NumberLinkTimeChecks,
|
||||
prometheus.CounterValue,
|
||||
float64(process.NumberLinkTimeChecks),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TimeinRTchecks,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.PercentTimeinRTchecks)/float64(process.Frequency_PerfTime),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.StackWalkDepth,
|
||||
prometheus.GaugeValue,
|
||||
float64(process.StackWalkDepth),
|
||||
process.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRuntimeChecks,
|
||||
prometheus.CounterValue,
|
||||
float64(process.TotalRuntimeChecks),
|
||||
process.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRSecurityCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRSecurityCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNPSCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "nps", newNPSCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkOSCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "os", newOSCollector)
|
||||
}
|
||||
@@ -1,298 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagPhysicalDiskExclude = "collector.physical_disk.disk-exclude"
|
||||
FlagPhysicalDiskInclude = "collector.physical_disk.disk-include"
|
||||
)
|
||||
|
||||
var (
|
||||
diskInclude *string
|
||||
diskExclude *string
|
||||
|
||||
diskIncludeSet bool
|
||||
diskExcludeSet bool
|
||||
)
|
||||
|
||||
// A PhysicalDiskCollector is a Prometheus collector for perflib PhysicalDisk metrics
|
||||
type PhysicalDiskCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
RequestsQueued *prometheus.Desc
|
||||
ReadBytesTotal *prometheus.Desc
|
||||
ReadsTotal *prometheus.Desc
|
||||
WriteBytesTotal *prometheus.Desc
|
||||
WritesTotal *prometheus.Desc
|
||||
ReadTime *prometheus.Desc
|
||||
WriteTime *prometheus.Desc
|
||||
IdleTime *prometheus.Desc
|
||||
SplitIOs *prometheus.Desc
|
||||
ReadLatency *prometheus.Desc
|
||||
WriteLatency *prometheus.Desc
|
||||
ReadWriteLatency *prometheus.Desc
|
||||
|
||||
diskIncludePattern *regexp.Regexp
|
||||
diskExcludePattern *regexp.Regexp
|
||||
}
|
||||
|
||||
// newPhysicalDiskCollectorFlags ...
|
||||
func newPhysicalDiskCollectorFlags(app *kingpin.Application) {
|
||||
diskInclude = app.Flag(
|
||||
FlagPhysicalDiskInclude,
|
||||
"Regexp of disks to include. Disk number must both match include and not match exclude to be included.",
|
||||
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
|
||||
diskIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
diskExclude = app.Flag(
|
||||
FlagPhysicalDiskExclude,
|
||||
"Regexp of disks to exclude. Disk number must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
diskExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
}
|
||||
|
||||
// NewPhysicalDiskCollector ...
|
||||
func NewPhysicalDiskCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "physical_disk"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
return &PhysicalDiskCollector{
|
||||
logger: logger,
|
||||
|
||||
RequestsQueued: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "requests_queued"),
|
||||
"The number of requests queued to the disk (PhysicalDisk.CurrentDiskQueueLength)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadBytesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_bytes_total"),
|
||||
"The number of bytes transferred from the disk during read operations (PhysicalDisk.DiskReadBytesPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "reads_total"),
|
||||
"The number of read operations on the disk (PhysicalDisk.DiskReadsPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WriteBytesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_bytes_total"),
|
||||
"The number of bytes transferred to the disk during write operations (PhysicalDisk.DiskWriteBytesPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WritesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "writes_total"),
|
||||
"The number of write operations on the disk (PhysicalDisk.DiskWritesPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_seconds_total"),
|
||||
"Seconds that the disk was busy servicing read requests (PhysicalDisk.PercentDiskReadTime)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WriteTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_seconds_total"),
|
||||
"Seconds that the disk was busy servicing write requests (PhysicalDisk.PercentDiskWriteTime)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
IdleTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "idle_seconds_total"),
|
||||
"Seconds that the disk was idle (PhysicalDisk.PercentIdleTime)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
SplitIOs: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "split_ios_total"),
|
||||
"The number of I/Os to the disk were split into multiple I/Os (PhysicalDisk.SplitIOPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_latency_seconds_total"),
|
||||
"Shows the average time, in seconds, of a read operation from the disk (PhysicalDisk.AvgDiskSecPerRead)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WriteLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_latency_seconds_total"),
|
||||
"Shows the average time, in seconds, of a write operation to the disk (PhysicalDisk.AvgDiskSecPerWrite)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadWriteLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_write_latency_seconds_total"),
|
||||
"Shows the time, in seconds, of the average disk transfer (PhysicalDisk.AvgDiskSecPerTransfer)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
diskIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *diskInclude)),
|
||||
diskExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *diskExclude)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *PhysicalDiskCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting physical_disk metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Win32_PerfRawData_PerfDisk_PhysicalDisk docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/aa394308(v=vs.85) - Win32_PerfRawData_PerfDisk_PhysicalDisk class
|
||||
type PhysicalDisk struct {
|
||||
Name string
|
||||
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
|
||||
DiskReadBytesPerSec float64 `perflib:"Disk Read Bytes/sec"`
|
||||
DiskReadsPerSec float64 `perflib:"Disk Reads/sec"`
|
||||
DiskWriteBytesPerSec float64 `perflib:"Disk Write Bytes/sec"`
|
||||
DiskWritesPerSec float64 `perflib:"Disk Writes/sec"`
|
||||
PercentDiskReadTime float64 `perflib:"% Disk Read Time"`
|
||||
PercentDiskWriteTime float64 `perflib:"% Disk Write Time"`
|
||||
PercentIdleTime float64 `perflib:"% Idle Time"`
|
||||
SplitIOPerSec float64 `perflib:"Split IO/Sec"`
|
||||
AvgDiskSecPerRead float64 `perflib:"Avg. Disk sec/Read"`
|
||||
AvgDiskSecPerWrite float64 `perflib:"Avg. Disk sec/Write"`
|
||||
AvgDiskSecPerTransfer float64 `perflib:"Avg. Disk sec/Transfer"`
|
||||
}
|
||||
|
||||
func (c *PhysicalDiskCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []PhysicalDisk
|
||||
if err := unmarshalObject(ctx.perfObjects["PhysicalDisk"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, disk := range dst {
|
||||
if disk.Name == "_Total" ||
|
||||
c.diskExcludePattern.MatchString(disk.Name) ||
|
||||
!c.diskIncludePattern.MatchString(disk.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse physical disk number from disk.Name. Mountpoint information is
|
||||
// sometimes included, e.g. "1 C:".
|
||||
disk_number, _, _ := strings.Cut(disk.Name, " ")
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RequestsQueued,
|
||||
prometheus.GaugeValue,
|
||||
disk.CurrentDiskQueueLength,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadBytesTotal,
|
||||
prometheus.CounterValue,
|
||||
disk.DiskReadBytesPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
disk.DiskReadsPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteBytesTotal,
|
||||
prometheus.CounterValue,
|
||||
disk.DiskWriteBytesPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WritesTotal,
|
||||
prometheus.CounterValue,
|
||||
disk.DiskWritesPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadTime,
|
||||
prometheus.CounterValue,
|
||||
disk.PercentDiskReadTime,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteTime,
|
||||
prometheus.CounterValue,
|
||||
disk.PercentDiskWriteTime,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.IdleTime,
|
||||
prometheus.CounterValue,
|
||||
disk.PercentIdleTime,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SplitIOs,
|
||||
prometheus.CounterValue,
|
||||
disk.SplitIOPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadLatency,
|
||||
prometheus.CounterValue,
|
||||
disk.AvgDiskSecPerRead*ticksToSecondsScaleFactor,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteLatency,
|
||||
prometheus.CounterValue,
|
||||
disk.AvgDiskSecPerWrite*ticksToSecondsScaleFactor,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadWriteLatency,
|
||||
prometheus.CounterValue,
|
||||
disk.AvgDiskSecPerTransfer*ticksToSecondsScaleFactor,
|
||||
disk_number,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkProcessCollector(b *testing.B) {
|
||||
// Include is not set in testing context (kingpin flags not parsed), causing the collector to skip all processes.
|
||||
localProcessInclude := ".+"
|
||||
processInclude = &localProcessInclude
|
||||
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newProcessCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkRemoteFXCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "remote_fx", newRemoteFx)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkScheduledTaskCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "scheduled_task", newScheduledTask)
|
||||
}
|
||||
@@ -1,332 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagServiceWhereClause = "collector.service.services-where"
|
||||
FlagServiceUseAPI = "collector.service.use-api"
|
||||
)
|
||||
|
||||
var (
|
||||
serviceWhereClause *string
|
||||
useAPI *bool
|
||||
)
|
||||
|
||||
// A serviceCollector is a Prometheus collector for WMI Win32_Service metrics
|
||||
type serviceCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
Information *prometheus.Desc
|
||||
State *prometheus.Desc
|
||||
StartMode *prometheus.Desc
|
||||
Status *prometheus.Desc
|
||||
|
||||
queryWhereClause string
|
||||
}
|
||||
|
||||
// newServiceCollectorFlags ...
|
||||
func newServiceCollectorFlags(app *kingpin.Application) {
|
||||
serviceWhereClause = app.Flag(
|
||||
FlagServiceWhereClause,
|
||||
"WQL 'where' clause to use in WMI metrics query. Limits the response to the services you specify and reduces the size of the response.",
|
||||
).Default("").String()
|
||||
useAPI = app.Flag(
|
||||
FlagServiceUseAPI,
|
||||
"Use API calls to collect service data instead of WMI. Flag 'collector.service.services-where' won't be effective.",
|
||||
).Default("false").Bool()
|
||||
}
|
||||
|
||||
// newserviceCollector ...
|
||||
func newserviceCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "service"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *serviceWhereClause == "" {
|
||||
_ = level.Warn(logger).Log("msg", "No where-clause specified for service collector. This will generate a very large number of metrics!")
|
||||
}
|
||||
if *useAPI {
|
||||
_ = level.Warn(logger).Log("msg", "API collection is enabled.")
|
||||
}
|
||||
|
||||
return &serviceCollector{
|
||||
logger: logger,
|
||||
|
||||
Information: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "info"),
|
||||
"A metric with a constant '1' value labeled with service information",
|
||||
[]string{"name", "display_name", "process_id", "run_as"},
|
||||
nil,
|
||||
),
|
||||
State: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "state"),
|
||||
"The state of the service (State)",
|
||||
[]string{"name", "state"},
|
||||
nil,
|
||||
),
|
||||
StartMode: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "start_mode"),
|
||||
"The start mode of the service (StartMode)",
|
||||
[]string{"name", "start_mode"},
|
||||
nil,
|
||||
),
|
||||
Status: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "status"),
|
||||
"The status of the service (Status)",
|
||||
[]string{"name", "status"},
|
||||
nil,
|
||||
),
|
||||
queryWhereClause: *serviceWhereClause,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *serviceCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if *useAPI {
|
||||
if err := c.collectAPI(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting API service metrics:", "err", err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := c.collectWMI(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting WMI service metrics:", "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Win32_Service docs:
|
||||
// - https://msdn.microsoft.com/en-us/library/aa394418(v=vs.85).aspx
|
||||
type Win32_Service struct {
|
||||
DisplayName string
|
||||
Name string
|
||||
ProcessId uint32
|
||||
State string
|
||||
Status string
|
||||
StartMode string
|
||||
StartName *string
|
||||
}
|
||||
|
||||
var (
|
||||
allStates = []string{
|
||||
"stopped",
|
||||
"start pending",
|
||||
"stop pending",
|
||||
"running",
|
||||
"continue pending",
|
||||
"pause pending",
|
||||
"paused",
|
||||
"unknown",
|
||||
}
|
||||
apiStateValues = map[uint]string{
|
||||
windows.SERVICE_CONTINUE_PENDING: "continue pending",
|
||||
windows.SERVICE_PAUSE_PENDING: "pause pending",
|
||||
windows.SERVICE_PAUSED: "paused",
|
||||
windows.SERVICE_RUNNING: "running",
|
||||
windows.SERVICE_START_PENDING: "start pending",
|
||||
windows.SERVICE_STOP_PENDING: "stop pending",
|
||||
windows.SERVICE_STOPPED: "stopped",
|
||||
}
|
||||
allStartModes = []string{
|
||||
"boot",
|
||||
"system",
|
||||
"auto",
|
||||
"manual",
|
||||
"disabled",
|
||||
}
|
||||
apiStartModeValues = map[uint32]string{
|
||||
windows.SERVICE_AUTO_START: "auto",
|
||||
windows.SERVICE_BOOT_START: "boot",
|
||||
windows.SERVICE_DEMAND_START: "manual",
|
||||
windows.SERVICE_DISABLED: "disabled",
|
||||
windows.SERVICE_SYSTEM_START: "system",
|
||||
}
|
||||
allStatuses = []string{
|
||||
"ok",
|
||||
"error",
|
||||
"degraded",
|
||||
"unknown",
|
||||
"pred fail",
|
||||
"starting",
|
||||
"stopping",
|
||||
"service",
|
||||
"stressed",
|
||||
"nonrecover",
|
||||
"no contact",
|
||||
"lost comm",
|
||||
}
|
||||
)
|
||||
|
||||
func (c *serviceCollector) collectWMI(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_Service
|
||||
q := queryAllWhere(&dst, c.queryWhereClause, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, service := range dst {
|
||||
pid := fmt.Sprintf("%d", uint64(service.ProcessId))
|
||||
|
||||
runAs := ""
|
||||
if service.StartName != nil {
|
||||
runAs = *service.StartName
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Information,
|
||||
prometheus.GaugeValue,
|
||||
1.0,
|
||||
strings.ToLower(service.Name),
|
||||
service.DisplayName,
|
||||
pid,
|
||||
runAs,
|
||||
)
|
||||
|
||||
for _, state := range allStates {
|
||||
isCurrentState := 0.0
|
||||
if state == strings.ToLower(service.State) {
|
||||
isCurrentState = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.State,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
strings.ToLower(service.Name),
|
||||
state,
|
||||
)
|
||||
}
|
||||
|
||||
for _, startMode := range allStartModes {
|
||||
isCurrentStartMode := 0.0
|
||||
if startMode == strings.ToLower(service.StartMode) {
|
||||
isCurrentStartMode = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.StartMode,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentStartMode,
|
||||
strings.ToLower(service.Name),
|
||||
startMode,
|
||||
)
|
||||
}
|
||||
|
||||
for _, status := range allStatuses {
|
||||
isCurrentStatus := 0.0
|
||||
if status == strings.ToLower(service.Status) {
|
||||
isCurrentStatus = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Status,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentStatus,
|
||||
strings.ToLower(service.Name),
|
||||
status,
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *serviceCollector) collectAPI(ch chan<- prometheus.Metric) error {
|
||||
svcmgrConnection, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer svcmgrConnection.Disconnect() //nolint:errcheck
|
||||
|
||||
// List All Services from the Services Manager.
|
||||
serviceList, err := svcmgrConnection.ListServices()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Iterate through the Services List.
|
||||
for _, service := range serviceList {
|
||||
// Get UTF16 service name.
|
||||
serviceName, err := syscall.UTF16PtrFromString(service)
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Service %s get name error: %#v", service, err))
|
||||
continue
|
||||
}
|
||||
|
||||
// Open connection for service handler.
|
||||
serviceHandle, err := windows.OpenService(svcmgrConnection.Handle, serviceName, windows.GENERIC_READ)
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Open service %s error: %#v", service, err))
|
||||
continue
|
||||
}
|
||||
|
||||
// Create handle for each service.
|
||||
serviceManager := &mgr.Service{Name: service, Handle: serviceHandle}
|
||||
defer serviceManager.Close()
|
||||
|
||||
// Get Service Configuration.
|
||||
serviceConfig, err := serviceManager.Config()
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Get service %s config error: %#v", service, err))
|
||||
continue
|
||||
}
|
||||
|
||||
// Get Service Current Status.
|
||||
serviceStatus, err := serviceManager.Query()
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Get service %s status error: %#v", service, err))
|
||||
continue
|
||||
}
|
||||
|
||||
pid := fmt.Sprintf("%d", uint64(serviceStatus.ProcessId))
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Information,
|
||||
prometheus.GaugeValue,
|
||||
1.0,
|
||||
strings.ToLower(service),
|
||||
serviceConfig.DisplayName,
|
||||
pid,
|
||||
serviceConfig.ServiceStartName,
|
||||
)
|
||||
|
||||
for _, state := range apiStateValues {
|
||||
isCurrentState := 0.0
|
||||
if state == apiStateValues[uint(serviceStatus.State)] {
|
||||
isCurrentState = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.State,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
strings.ToLower(service),
|
||||
state,
|
||||
)
|
||||
}
|
||||
|
||||
for _, startMode := range apiStartModeValues {
|
||||
isCurrentStartMode := 0.0
|
||||
if startMode == apiStartModeValues[serviceConfig.StartType] {
|
||||
isCurrentStartMode = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.StartMode,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentStartMode,
|
||||
strings.ToLower(service),
|
||||
startMode,
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkServiceCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "service", newserviceCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkSmtpCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "smtp", newSMTPCollector)
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// A SystemCollector is a Prometheus collector for WMI metrics
|
||||
type SystemCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
ContextSwitchesTotal *prometheus.Desc
|
||||
ExceptionDispatchesTotal *prometheus.Desc
|
||||
ProcessorQueueLength *prometheus.Desc
|
||||
SystemCallsTotal *prometheus.Desc
|
||||
SystemUpTime *prometheus.Desc
|
||||
Threads *prometheus.Desc
|
||||
}
|
||||
|
||||
// newSystemCollector ...
|
||||
func newSystemCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "system"
|
||||
|
||||
return &SystemCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
ContextSwitchesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "context_switches_total"),
|
||||
"Total number of context switches (WMI source: PerfOS_System.ContextSwitchesPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ExceptionDispatchesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "exception_dispatches_total"),
|
||||
"Total number of exceptions dispatched (WMI source: PerfOS_System.ExceptionDispatchesPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ProcessorQueueLength: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "processor_queue_length"),
|
||||
"Length of processor queue (WMI source: PerfOS_System.ProcessorQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SystemCallsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "system_calls_total"),
|
||||
"Total number of system calls (WMI source: PerfOS_System.SystemCallsPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SystemUpTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "system_up_time"),
|
||||
"System boot time (WMI source: PerfOS_System.SystemUpTime)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
Threads: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "threads"),
|
||||
"Current number of threads (WMI source: PerfOS_System.Threads)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *SystemCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting system metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Win32_PerfRawData_PerfOS_System docs:
|
||||
// - https://web.archive.org/web/20050830140516/http://msdn.microsoft.com/library/en-us/wmisdk/wmi/win32_perfrawdata_perfos_system.asp
|
||||
type system struct {
|
||||
ContextSwitchesPersec float64 `perflib:"Context Switches/sec"`
|
||||
ExceptionDispatchesPersec float64 `perflib:"Exception Dispatches/sec"`
|
||||
ProcessorQueueLength float64 `perflib:"Processor Queue Length"`
|
||||
SystemCallsPersec float64 `perflib:"System Calls/sec"`
|
||||
SystemUpTime float64 `perflib:"System Up Time"`
|
||||
Threads float64 `perflib:"Threads"`
|
||||
}
|
||||
|
||||
func (c *SystemCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []system
|
||||
if err := unmarshalObject(ctx.perfObjects["System"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ContextSwitchesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].ContextSwitchesPersec,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ExceptionDispatchesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].ExceptionDispatchesPersec,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ProcessorQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].ProcessorQueueLength,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SystemCallsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SystemCallsPersec,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SystemUpTime,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].SystemUpTime,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Threads,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].Threads,
|
||||
)
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkSystemCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "system", newSystemCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkTCPCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "tcp", newTCPCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkTeradiciPcoipCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "teradici_pcoip", newTeradiciPcoipCollector)
|
||||
}
|
||||
@@ -1,411 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const ConnectionBrokerFeatureID uint32 = 133
|
||||
|
||||
type Win32_ServerFeature struct {
|
||||
ID uint32
|
||||
}
|
||||
|
||||
func isConnectionBrokerServer(logger log.Logger) bool {
|
||||
var dst []Win32_ServerFeature
|
||||
q := queryAll(&dst, logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return false
|
||||
}
|
||||
for _, d := range dst {
|
||||
if d.ID == ConnectionBrokerFeatureID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
_ = level.Debug(logger).Log("msg", "host is not a connection broker skipping Connection Broker performance metrics.")
|
||||
return false
|
||||
}
|
||||
|
||||
// A TerminalServicesCollector is a Prometheus collector for WMI
|
||||
// Win32_PerfRawData_LocalSessionManager_TerminalServices & Win32_PerfRawData_TermService_TerminalServicesSession metrics
|
||||
// https://docs.microsoft.com/en-us/previous-versions/aa394344(v%3Dvs.85)
|
||||
// https://wutils.com/wmi/root/cimv2/win32_perfrawdata_localsessionmanager_terminalservices/
|
||||
type TerminalServicesCollector struct {
|
||||
logger log.Logger
|
||||
connectionBrokerEnabled bool
|
||||
|
||||
LocalSessionCount *prometheus.Desc
|
||||
ConnectionBrokerPerformance *prometheus.Desc
|
||||
HandleCount *prometheus.Desc
|
||||
PageFaultsPersec *prometheus.Desc
|
||||
PageFileBytes *prometheus.Desc
|
||||
PageFileBytesPeak *prometheus.Desc
|
||||
PercentPrivilegedTime *prometheus.Desc
|
||||
PercentProcessorTime *prometheus.Desc
|
||||
PercentUserTime *prometheus.Desc
|
||||
PoolNonpagedBytes *prometheus.Desc
|
||||
PoolPagedBytes *prometheus.Desc
|
||||
PrivateBytes *prometheus.Desc
|
||||
ThreadCount *prometheus.Desc
|
||||
VirtualBytes *prometheus.Desc
|
||||
VirtualBytesPeak *prometheus.Desc
|
||||
WorkingSet *prometheus.Desc
|
||||
WorkingSetPeak *prometheus.Desc
|
||||
}
|
||||
|
||||
// newTerminalServicesCollector ...
|
||||
func newTerminalServicesCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "terminal_services"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
return &TerminalServicesCollector{
|
||||
logger: logger,
|
||||
connectionBrokerEnabled: isConnectionBrokerServer(logger),
|
||||
|
||||
LocalSessionCount: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "local_session_count"),
|
||||
"Number of Terminal Services sessions",
|
||||
[]string{"session"},
|
||||
nil,
|
||||
),
|
||||
ConnectionBrokerPerformance: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_broker_performance_total"),
|
||||
"The total number of connections handled by the Connection Brokers since the service started.",
|
||||
[]string{"connection"},
|
||||
nil,
|
||||
),
|
||||
HandleCount: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "handles"),
|
||||
"Total number of handles currently opened by this process. This number is the sum of the handles currently opened by each thread in this process.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
PageFaultsPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "page_fault_total"),
|
||||
"Rate at which page faults occur in the threads executing in this process. A page fault occurs when a thread refers to a virtual memory page that is not in its working set in main memory. The page may not be retrieved from disk if it is on the standby list and therefore already in main memory. The page also may not be retrieved if it is in use by another process which shares the page.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
PageFileBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "page_file_bytes"),
|
||||
"Current number of bytes this process has used in the paging file(s). Paging files are used to store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes, and lack of space in paging files can prevent other processes from allocating memory.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
PageFileBytesPeak: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "page_file_bytes_peak"),
|
||||
"Maximum number of bytes this process has used in the paging file(s). Paging files are used to store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes, and lack of space in paging files can prevent other processes from allocating memory.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
PercentPrivilegedTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "privileged_time_seconds_total"),
|
||||
"Total elapsed time that the threads of the process have spent executing code in privileged mode.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
PercentProcessorTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "processor_time_seconds_total"),
|
||||
"Total elapsed time that all of the threads of this process used the processor to execute instructions.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
PercentUserTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "user_time_seconds_total"),
|
||||
"Total elapsed time that this process's threads have spent executing code in user mode. Applications, environment subsystems, and integral subsystems execute in user mode.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
PoolNonpagedBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pool_non_paged_bytes"),
|
||||
"Number of bytes in the non-paged pool, an area of system memory (physical memory used by the operating system) for objects that cannot be written to disk, but must remain in physical memory as long as they are allocated. This property displays the last observed value only; it is not an average.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
PoolPagedBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pool_paged_bytes"),
|
||||
"Number of bytes in the paged pool, an area of system memory (physical memory used by the operating system) for objects that can be written to disk when they are not being used. This property displays the last observed value only; it is not an average.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
PrivateBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "private_bytes"),
|
||||
"Current number of bytes this process has allocated that cannot be shared with other processes.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
ThreadCount: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "threads"),
|
||||
"Number of threads currently active in this process. An instruction is the basic unit of execution in a processor, and a thread is the object that executes instructions. Every running process has at least one thread.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
VirtualBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "virtual_bytes"),
|
||||
"Current size, in bytes, of the virtual address space the process is using. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is finite and, by using too much, the process can limit its ability to load libraries.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
VirtualBytesPeak: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "virtual_bytes_peak"),
|
||||
"Maximum number of bytes of virtual address space the process has used at any one time. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is finite and, by using too much, the process might limit its ability to load libraries.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
WorkingSet: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "working_set_bytes"),
|
||||
"Current number of bytes in the working set of this process. The working set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the working set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from working sets. If they are needed, they are then soft-faulted back into the working set before they leave main memory.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
WorkingSetPeak: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "working_set_bytes_peak"),
|
||||
"Maximum number of bytes in the working set of this process at any point in time. The working set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the working set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from working sets. If they are needed, they are then soft-faulted back into the working set before they leave main memory.",
|
||||
[]string{"session_name"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *TerminalServicesCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collectTSSessionCount(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
if desc, err := c.collectTSSessionCounters(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// only collect CollectionBrokerPerformance if host is a Connection Broker
|
||||
if c.connectionBrokerEnabled {
|
||||
if desc, err := c.collectCollectionBrokerPerformanceCounter(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting Connection Broker performance metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type perflibTerminalServices struct {
|
||||
ActiveSessions float64 `perflib:"Active Sessions"`
|
||||
InactiveSessions float64 `perflib:"Inactive Sessions"`
|
||||
TotalSessions float64 `perflib:"Total Sessions"`
|
||||
}
|
||||
|
||||
func (c *TerminalServicesCollector) collectTSSessionCount(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
dst := make([]perflibTerminalServices, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Terminal Services"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dst) == 0 {
|
||||
return nil, errors.New("WMI query returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.LocalSessionCount,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].ActiveSessions,
|
||||
"active",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.LocalSessionCount,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].InactiveSessions,
|
||||
"inactive",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.LocalSessionCount,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].TotalSessions,
|
||||
"total",
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type perflibTerminalServicesSession struct {
|
||||
Name string
|
||||
HandleCount float64 `perflib:"Handle Count"`
|
||||
PageFaultsPersec float64 `perflib:"Page Faults/sec"`
|
||||
PageFileBytes float64 `perflib:"Page File Bytes"`
|
||||
PageFileBytesPeak float64 `perflib:"Page File Bytes Peak"`
|
||||
PercentPrivilegedTime float64 `perflib:"% Privileged Time"`
|
||||
PercentProcessorTime float64 `perflib:"% Processor Time"`
|
||||
PercentUserTime float64 `perflib:"% User Time"`
|
||||
PoolNonpagedBytes float64 `perflib:"Pool Nonpaged Bytes"`
|
||||
PoolPagedBytes float64 `perflib:"Pool Paged Bytes"`
|
||||
PrivateBytes float64 `perflib:"Private Bytes"`
|
||||
ThreadCount float64 `perflib:"Thread Count"`
|
||||
VirtualBytes float64 `perflib:"Virtual Bytes"`
|
||||
VirtualBytesPeak float64 `perflib:"Virtual Bytes Peak"`
|
||||
WorkingSet float64 `perflib:"Working Set"`
|
||||
WorkingSetPeak float64 `perflib:"Working Set Peak"`
|
||||
}
|
||||
|
||||
func (c *TerminalServicesCollector) collectTSSessionCounters(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
dst := make([]perflibTerminalServicesSession, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Terminal Services Session"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
names := make(map[string]bool)
|
||||
|
||||
for _, d := range dst {
|
||||
// only connect metrics for remote named sessions
|
||||
n := strings.ToLower(d.Name)
|
||||
if n == "" || n == "services" || n == "console" {
|
||||
continue
|
||||
}
|
||||
// don't add name already present in labels list
|
||||
if _, ok := names[n]; ok {
|
||||
continue
|
||||
}
|
||||
names[n] = true
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.HandleCount,
|
||||
prometheus.GaugeValue,
|
||||
d.HandleCount,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PageFaultsPersec,
|
||||
prometheus.CounterValue,
|
||||
d.PageFaultsPersec,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PageFileBytes,
|
||||
prometheus.GaugeValue,
|
||||
d.PageFileBytes,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PageFileBytesPeak,
|
||||
prometheus.GaugeValue,
|
||||
d.PageFileBytesPeak,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PercentPrivilegedTime,
|
||||
prometheus.CounterValue,
|
||||
d.PercentPrivilegedTime,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PercentProcessorTime,
|
||||
prometheus.CounterValue,
|
||||
d.PercentProcessorTime,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PercentUserTime,
|
||||
prometheus.CounterValue,
|
||||
d.PercentUserTime,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PoolNonpagedBytes,
|
||||
prometheus.GaugeValue,
|
||||
d.PoolNonpagedBytes,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PoolPagedBytes,
|
||||
prometheus.GaugeValue,
|
||||
d.PoolPagedBytes,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PrivateBytes,
|
||||
prometheus.GaugeValue,
|
||||
d.PrivateBytes,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ThreadCount,
|
||||
prometheus.GaugeValue,
|
||||
d.ThreadCount,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.VirtualBytes,
|
||||
prometheus.GaugeValue,
|
||||
d.VirtualBytes,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.VirtualBytesPeak,
|
||||
prometheus.GaugeValue,
|
||||
d.VirtualBytesPeak,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WorkingSet,
|
||||
prometheus.GaugeValue,
|
||||
d.WorkingSet,
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WorkingSetPeak,
|
||||
prometheus.GaugeValue,
|
||||
d.WorkingSetPeak,
|
||||
d.Name,
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type perflibRemoteDesktopConnectionBrokerCounterset struct {
|
||||
SuccessfulConnections float64 `perflib:"Successful Connections"`
|
||||
PendingConnections float64 `perflib:"Pending Connections"`
|
||||
FailedConnections float64 `perflib:"Failed Connections"`
|
||||
}
|
||||
|
||||
func (c *TerminalServicesCollector) collectCollectionBrokerPerformanceCounter(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
|
||||
dst := make([]perflibRemoteDesktopConnectionBrokerCounterset, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Remote Desktop Connection Broker Counterset"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dst) == 0 {
|
||||
return nil, errors.New("WMI query returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ConnectionBrokerPerformance,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SuccessfulConnections,
|
||||
"Successful",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ConnectionBrokerPerformance,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PendingConnections,
|
||||
"Pending",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ConnectionBrokerPerformance,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FailedConnections,
|
||||
"Failed",
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkTerminalServicesCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "terminal_services", newTerminalServicesCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkThermalZoneCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "thermalzone", newThermalZoneCollector)
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// TimeCollector is a Prometheus collector for Perflib counter metrics
|
||||
type TimeCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
ClockFrequencyAdjustmentPPBTotal *prometheus.Desc
|
||||
ComputedTimeOffset *prometheus.Desc
|
||||
NTPClientTimeSourceCount *prometheus.Desc
|
||||
NTPRoundtripDelay *prometheus.Desc
|
||||
NTPServerIncomingRequestsTotal *prometheus.Desc
|
||||
NTPServerOutgoingResponsesTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
func newTimeCollector(logger log.Logger) (Collector, error) {
|
||||
if getWindowsVersion(logger) <= 6.1 {
|
||||
return nil, errors.New("Windows version older than Server 2016 detected. The time collector will not run and should be disabled via CLI flags or configuration file")
|
||||
}
|
||||
|
||||
const subsystem = "time"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
return &TimeCollector{
|
||||
logger: logger,
|
||||
ClockFrequencyAdjustmentPPBTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "clock_frequency_adjustment_ppb_total"),
|
||||
"Total adjustment made to the local system clock frequency by W32Time in Parts Per Billion (PPB) units.",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ComputedTimeOffset: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "computed_time_offset_seconds"),
|
||||
"Absolute time offset between the system clock and the chosen time source, in seconds",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
NTPClientTimeSourceCount: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ntp_client_time_sources"),
|
||||
"Active number of NTP Time sources being used by the client",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
NTPRoundtripDelay: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ntp_round_trip_delay_seconds"),
|
||||
"Roundtrip delay experienced by the NTP client in receiving a response from the server for the most recent request, in seconds",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
NTPServerOutgoingResponsesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ntp_server_outgoing_responses_total"),
|
||||
"Total number of requests responded to by NTP server",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
NTPServerIncomingRequestsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ntp_server_incoming_requests_total"),
|
||||
"Total number of requests received by NTP server",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *TimeCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting time metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Perflib "Windows Time Service"
|
||||
type windowsTime struct {
|
||||
ClockFrequencyAdjustmentPPBTotal float64 `perflib:"Clock Frequency Adjustment (ppb)"`
|
||||
ComputedTimeOffset float64 `perflib:"Computed Time Offset"`
|
||||
NTPClientTimeSourceCount float64 `perflib:"NTP Client Time Source Count"`
|
||||
NTPRoundtripDelay float64 `perflib:"NTP Roundtrip Delay"`
|
||||
NTPServerIncomingRequestsTotal float64 `perflib:"NTP Server Incoming Requests"`
|
||||
NTPServerOutgoingResponsesTotal float64 `perflib:"NTP Server Outgoing Responses"`
|
||||
}
|
||||
|
||||
func (c *TimeCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []windowsTime // Single-instance class, array is required but will have single entry.
|
||||
if err := unmarshalObject(ctx.perfObjects["Windows Time Service"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ClockFrequencyAdjustmentPPBTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].ClockFrequencyAdjustmentPPBTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ComputedTimeOffset,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].ComputedTimeOffset/1000000, // microseconds -> seconds
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NTPClientTimeSourceCount,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].NTPClientTimeSourceCount,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NTPRoundtripDelay,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].NTPRoundtripDelay/1000000, // microseconds -> seconds
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NTPServerIncomingRequestsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].NTPServerIncomingRequestsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NTPServerOutgoingResponsesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].NTPServerOutgoingResponsesTotal,
|
||||
)
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkTimeCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "time", newTimeCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkVmwareBlastCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "vmware_blast", newVmwareBlastCollector)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkVmwareCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "vmware", newVmwareCollector)
|
||||
}
|
||||
183
exporter.go
183
exporter.go
@@ -1,37 +1,30 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
//Its important that we do these first so that we can register with the windows service control ASAP to avoid timeouts
|
||||
"github.com/prometheus-community/windows_exporter/initiate"
|
||||
winlog "github.com/prometheus-community/windows_exporter/log"
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
stdlog "log"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/collector"
|
||||
"github.com/prometheus-community/windows_exporter/config"
|
||||
"github.com/prometheus-community/windows_exporter/log/flag"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
// Its important that we do these first so that we can register with the windows service control ASAP to avoid timeouts
|
||||
"github.com/prometheus-community/windows_exporter/pkg/initiate"
|
||||
winlog "github.com/prometheus-community/windows_exporter/pkg/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
|
||||
"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/client_golang/prometheus/collectors"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/config"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/log/flag"
|
||||
"github.com/prometheus/common/version"
|
||||
"github.com/prometheus/exporter-toolkit/web"
|
||||
webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag"
|
||||
@@ -48,56 +41,6 @@ type prometheusVersion struct {
|
||||
GoVersion string `json:"goVersion"`
|
||||
}
|
||||
|
||||
const (
|
||||
defaultCollectors = "cpu,cs,logical_disk,physical_disk,net,os,service,system,textfile"
|
||||
defaultCollectorsPlaceholder = "[defaults]"
|
||||
)
|
||||
|
||||
func expandEnabledCollectors(enabled string) []string {
|
||||
expanded := strings.Replace(enabled, defaultCollectorsPlaceholder, defaultCollectors, -1)
|
||||
separated := strings.Split(expanded, ",")
|
||||
unique := map[string]bool{}
|
||||
for _, s := range separated {
|
||||
if s != "" {
|
||||
unique[s] = true
|
||||
}
|
||||
}
|
||||
result := make([]string, 0, len(unique))
|
||||
for s := range unique {
|
||||
result = append(result, s)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func loadCollectors(list string, logger log.Logger) (map[string]collector.Collector, error) {
|
||||
collectors := map[string]collector.Collector{}
|
||||
enabled := expandEnabledCollectors(list)
|
||||
|
||||
for _, name := range enabled {
|
||||
c, err := collector.Build(name, logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
collectors[name] = c
|
||||
}
|
||||
|
||||
return collectors, nil
|
||||
}
|
||||
|
||||
func initWbem(logger log.Logger) {
|
||||
// This initialization prevents a memory leak on WMF 5+. See
|
||||
// https://github.com/prometheus-community/windows_exporter/issues/77 and
|
||||
// linked issues for details.
|
||||
_ = level.Debug(logger).Log("msg", "Initializing SWbemServices")
|
||||
s, err := wmi.InitializeSWbemServices(wmi.DefaultClient)
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
wmi.DefaultClient.AllowMissingFields = true
|
||||
wmi.DefaultClient.SWbemServicesClient = s
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := kingpin.New("windows_exporter", "A metrics collector for Windows.")
|
||||
var (
|
||||
@@ -125,7 +68,7 @@ func main() {
|
||||
enabledCollectors = app.Flag(
|
||||
"collectors.enabled",
|
||||
"Comma-separated list of collectors to use. Use '[defaults]' as a placeholder for all the collectors enabled by default.").
|
||||
Default(defaultCollectors).String()
|
||||
Default(types.DefaultCollectors).String()
|
||||
printCollectors = app.Flag(
|
||||
"collectors.print",
|
||||
"If true, print available collectors and exit.",
|
||||
@@ -143,7 +86,7 @@ func main() {
|
||||
app.HelpFlag.Short('h')
|
||||
|
||||
// Initialize collectors before loading and parsing CLI arguments
|
||||
collector.RegisterCollectorsFlags(app)
|
||||
collectors := collector.NewWithFlags(app)
|
||||
|
||||
// Load values from configuration file(s). Executable flags must first be parsed, in order
|
||||
// to load the specified file(s).
|
||||
@@ -155,6 +98,7 @@ func main() {
|
||||
}
|
||||
|
||||
_ = level.Debug(logger).Log("msg", "Logging has Started")
|
||||
|
||||
if *configFile != "" {
|
||||
resolver, err := config.NewResolver(*configFile, logger, *insecure_skip_verify)
|
||||
if err != nil {
|
||||
@@ -183,25 +127,28 @@ func main() {
|
||||
}
|
||||
|
||||
if *printCollectors {
|
||||
collectors := collector.Available()
|
||||
collectorNames := make(sort.StringSlice, 0, len(collectors))
|
||||
for _, n := range collectors {
|
||||
collectorNames = append(collectorNames, n)
|
||||
}
|
||||
collectorNames.Sort()
|
||||
collectorNames := collector.Available()
|
||||
sort.Strings(collectorNames)
|
||||
|
||||
fmt.Printf("Available collectors:\n")
|
||||
for _, n := range collectorNames {
|
||||
fmt.Printf(" - %s\n", n)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
initWbem(logger)
|
||||
if err = wmi.InitWbem(logger); err != nil {
|
||||
_ = level.Error(logger).Log("err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
enabledCollectorList := utils.ExpandEnabledCollectors(*enabledCollectors)
|
||||
collectors.Enable(enabledCollectorList)
|
||||
collectors.SetLogger(logger)
|
||||
|
||||
// Initialize collectors before loading
|
||||
collector.RegisterCollectors(logger)
|
||||
|
||||
collectors, err := loadCollectors(*enabledCollectors, logger)
|
||||
err = collectors.Build()
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("msg", "Couldn't load collectors", "err", err)
|
||||
os.Exit(1)
|
||||
@@ -214,34 +161,14 @@ func main() {
|
||||
}
|
||||
|
||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("Running as %v", u.Username))
|
||||
|
||||
if strings.Contains(u.Username, "ContainerAdministrator") || strings.Contains(u.Username, "ContainerUser") {
|
||||
_ = level.Warn(logger).Log("msg", "Running as a preconfigured Windows Container user. This may mean you do not have Windows HostProcess containers configured correctly and some functionality will not work as expected.")
|
||||
}
|
||||
|
||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("Enabled collectors: %v", strings.Join(keys(collectors), ", ")))
|
||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("Enabled collectors: %v", strings.Join(enabledCollectorList, ", ")))
|
||||
|
||||
h := &metricsHandler{
|
||||
timeoutMargin: *timeoutMargin,
|
||||
includeExporterMetrics: *disableExporterMetrics,
|
||||
collectorFactory: func(timeout time.Duration, requestedCollectors []string) (error, *collector.Prometheus) {
|
||||
filteredCollectors := make(map[string]collector.Collector)
|
||||
// scrape all enabled collectors if no collector is requested
|
||||
if len(requestedCollectors) == 0 {
|
||||
filteredCollectors = collectors
|
||||
}
|
||||
for _, name := range requestedCollectors {
|
||||
col, exists := collectors[name]
|
||||
if !exists {
|
||||
return fmt.Errorf("unavailable collector: %s", name), nil
|
||||
}
|
||||
filteredCollectors[name] = col
|
||||
}
|
||||
return nil, collector.NewPrometheus(timeout, filteredCollectors, logger)
|
||||
},
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
http.HandleFunc(*metricsPath, withConcurrencyLimit(*maxRequests, h.ServeHTTP))
|
||||
http.HandleFunc(*metricsPath, withConcurrencyLimit(*maxRequests, collectors.BuildServeHTTP(*disableExporterMetrics, *timeoutMargin)))
|
||||
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, err := fmt.Fprintln(w, `{"status":"ok"}`)
|
||||
@@ -312,14 +239,6 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func keys(m map[string]collector.Collector) []string {
|
||||
ret := make([]string, 0, len(m))
|
||||
for key := range m {
|
||||
ret = append(ret, key)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func withConcurrencyLimit(n int, next http.HandlerFunc) http.HandlerFunc {
|
||||
if n <= 0 {
|
||||
return next
|
||||
@@ -338,49 +257,3 @@ func withConcurrencyLimit(n int, next http.HandlerFunc) http.HandlerFunc {
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
type metricsHandler struct {
|
||||
timeoutMargin float64
|
||||
includeExporterMetrics bool
|
||||
collectorFactory func(timeout time.Duration, requestedCollectors []string) (error, *collector.Prometheus)
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
func (mh *metricsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
const defaultTimeout = 10.0
|
||||
|
||||
var timeoutSeconds float64
|
||||
if v := r.Header.Get("X-Prometheus-Scrape-Timeout-Seconds"); v != "" {
|
||||
var err error
|
||||
timeoutSeconds, err = strconv.ParseFloat(v, 64)
|
||||
if err != nil {
|
||||
_ = level.Warn(mh.logger).Log("msg", fmt.Sprintf("Couldn't parse X-Prometheus-Scrape-Timeout-Seconds: %q. Defaulting timeout to %f", v, defaultTimeout))
|
||||
}
|
||||
}
|
||||
if timeoutSeconds == 0 {
|
||||
timeoutSeconds = defaultTimeout
|
||||
}
|
||||
timeoutSeconds = timeoutSeconds - mh.timeoutMargin
|
||||
|
||||
reg := prometheus.NewRegistry()
|
||||
err, wc := mh.collectorFactory(time.Duration(timeoutSeconds*float64(time.Second)), r.URL.Query()["collect[]"])
|
||||
if err != nil {
|
||||
_ = level.Warn(mh.logger).Log("msg", "Couldn't create filtered metrics handler", "err", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't create filtered metrics handler: %s", err))) //nolint:errcheck
|
||||
return
|
||||
}
|
||||
reg.MustRegister(wc)
|
||||
if !mh.includeExporterMetrics {
|
||||
reg.MustRegister(
|
||||
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
|
||||
collectors.NewGoCollector(),
|
||||
version.NewCollector("windows_exporter"),
|
||||
)
|
||||
}
|
||||
|
||||
h := promhttp.HandlerFor(reg, promhttp.HandlerOpts{
|
||||
ErrorLog: stdlog.New(log.NewStdlibAdapter(level.Error(mh.logger)), "", stdlog.Lshortfile),
|
||||
})
|
||||
h.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type expansionTestCase struct {
|
||||
input string
|
||||
expectedOutput []string
|
||||
}
|
||||
|
||||
func TestExpandEnabled(t *testing.T) {
|
||||
expansionTests := []expansionTestCase{
|
||||
{"", []string{}},
|
||||
// Default case
|
||||
{"cs,os", []string{"cs", "os"}},
|
||||
// Placeholder expansion
|
||||
{defaultCollectorsPlaceholder, strings.Split(defaultCollectors, ",")},
|
||||
// De-duplication
|
||||
{"cs,cs", []string{"cs"}},
|
||||
// De-duplicate placeholder
|
||||
{defaultCollectorsPlaceholder + "," + defaultCollectorsPlaceholder, strings.Split(defaultCollectors, ",")},
|
||||
// Composite case
|
||||
{"foo," + defaultCollectorsPlaceholder + ",bar", append(strings.Split(defaultCollectors, ","), "foo", "bar")},
|
||||
}
|
||||
|
||||
for _, testCase := range expansionTests {
|
||||
output := expandEnabledCollectors(testCase.input)
|
||||
sort.Strings(output)
|
||||
|
||||
success := true
|
||||
if len(output) != len(testCase.expectedOutput) {
|
||||
success = false
|
||||
} else {
|
||||
sort.Strings(testCase.expectedOutput)
|
||||
for idx := range output {
|
||||
if output[idx] != testCase.expectedOutput[idx] {
|
||||
success = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
t.Error("For", testCase.input, "expected", testCase.expectedOutput, "got", output)
|
||||
}
|
||||
}
|
||||
}
|
||||
16
go.mod
16
go.mod
@@ -13,8 +13,10 @@ require (
|
||||
github.com/prometheus/common v0.45.0
|
||||
github.com/prometheus/exporter-toolkit v0.10.0
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/yusufpapurcu/wmi v1.2.3
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||
golang.org/x/sys v0.14.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
@@ -27,6 +29,7 @@ require (
|
||||
github.com/containerd/cgroups v1.1.0 // indirect
|
||||
github.com/containerd/containerd v1.7.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
@@ -36,15 +39,16 @@ require (
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/procfs v0.11.1 // indirect
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||
golang.org/x/crypto v0.14.0 // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/crypto v0.15.0 // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/net v0.18.0 // indirect
|
||||
golang.org/x/oauth2 v0.12.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/tools v0.8.0 // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.15.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/grpc v1.56.3 // indirect
|
||||
|
||||
27
go.sum
27
go.sum
@@ -106,6 +106,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@@ -117,16 +118,18 @@ go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
|
||||
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -137,8 +140,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
|
||||
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
|
||||
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
|
||||
@@ -147,8 +150,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -161,8 +164,8 @@ golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -171,8 +174,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
|
||||
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
|
||||
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
|
||||
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package ad
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A ADCollector is a Prometheus collector for WMI Win32_PerfRawData_DirectoryServices_DirectoryServices metrics
|
||||
type ADCollector struct {
|
||||
const Name = "ad"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A collector is a Prometheus collector for WMI Win32_PerfRawData_DirectoryServices_DirectoryServices metrics
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
AddressBookOperationsTotal *prometheus.Desc
|
||||
@@ -80,390 +87,409 @@ type ADCollector struct {
|
||||
TombstonedObjectsVisitedTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
// newADCollector ...
|
||||
func newADCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "ad"
|
||||
return &ADCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
func New(logger log.Logger, _ *Config) types.Collector {
|
||||
c := &collector{}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
AddressBookOperationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "address_book_operations_total"),
|
||||
"",
|
||||
[]string{"operation"},
|
||||
nil,
|
||||
),
|
||||
AddressBookClientSessions: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "address_book_client_sessions"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ApproximateHighestDistinguishedNameTag: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "approximate_highest_distinguished_name_tag"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AtqEstimatedDelaySeconds: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "atq_estimated_delay_seconds"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AtqOutstandingRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "atq_outstanding_requests"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AtqAverageRequestLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "atq_average_request_latency"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AtqCurrentThreads: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "atq_current_threads"),
|
||||
"",
|
||||
[]string{"service"},
|
||||
nil,
|
||||
),
|
||||
SearchesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "searches_total"),
|
||||
"",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
),
|
||||
DatabaseOperationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "database_operations_total"),
|
||||
"",
|
||||
[]string{"operation"},
|
||||
nil,
|
||||
),
|
||||
BindsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "binds_total"),
|
||||
"",
|
||||
[]string{"bind_method"},
|
||||
nil,
|
||||
),
|
||||
ReplicationHighestUsn: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_highest_usn"),
|
||||
"",
|
||||
[]string{"state"},
|
||||
nil,
|
||||
),
|
||||
IntrasiteReplicationDataBytesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_data_intrasite_bytes_total"),
|
||||
"",
|
||||
[]string{"direction"},
|
||||
nil,
|
||||
),
|
||||
IntersiteReplicationDataBytesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_data_intersite_bytes_total"),
|
||||
"",
|
||||
[]string{"direction"},
|
||||
nil,
|
||||
),
|
||||
ReplicationInboundSyncObjectsRemaining: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_inbound_sync_objects_remaining"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationInboundLinkValueUpdatesRemaining: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_inbound_link_value_updates_remaining"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationInboundObjectsUpdatedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_inbound_objects_updated_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationInboundObjectsFilteredTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_inbound_objects_filtered_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationInboundPropertiesUpdatedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_inbound_properties_updated_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationInboundPropertiesFilteredTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_inbound_properties_filtered_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationPendingOperations: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_pending_operations"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationPendingSynchronizations: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_pending_synchronizations"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationSyncRequestsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_sync_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationSyncRequestsSuccessTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_sync_requests_success_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReplicationSyncRequestsSchemaMismatchFailureTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "replication_sync_requests_schema_mismatch_failure_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
NameTranslationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "name_translations_total"),
|
||||
"",
|
||||
[]string{"target_name"},
|
||||
nil,
|
||||
),
|
||||
ChangeMonitorsRegistered: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "change_monitors_registered"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ChangeMonitorUpdatesPending: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "change_monitor_updates_pending"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
NameCacheHitsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "name_cache_hits_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
NameCacheLookupsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "name_cache_lookups_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DirectoryOperationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "directory_operations_total"),
|
||||
"",
|
||||
[]string{"operation", "origin"},
|
||||
nil,
|
||||
),
|
||||
DirectorySearchSuboperationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "directory_search_suboperations_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SecurityDescriptorPropagationEventsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "security_descriptor_propagation_events_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SecurityDescriptorPropagationEventsQueued: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "security_descriptor_propagation_events_queued"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SecurityDescriptorPropagationAccessWaitTotalSeconds: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "security_descriptor_propagation_access_wait_total_seconds"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SecurityDescriptorPropagationItemsQueuedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "security_descriptor_propagation_items_queued_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DirectoryServiceThreads: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "directory_service_threads"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LdapClosedConnectionsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ldap_closed_connections_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LdapOpenedConnectionsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ldap_opened_connections_total"),
|
||||
"",
|
||||
[]string{"type"},
|
||||
nil,
|
||||
),
|
||||
LdapActiveThreads: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ldap_active_threads"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LdapLastBindTimeSeconds: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ldap_last_bind_time_seconds"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LdapSearchesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ldap_searches_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LdapUdpOperationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ldap_udp_operations_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LdapWritesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ldap_writes_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LdapClientSessions: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ldap_client_sessions"),
|
||||
"This is the number of sessions opened by LDAP clients at the time the data is taken. This is helpful in determining LDAP client activity and if the DC is able to handle the load. Of course, spikes during normal periods of authentication — such as first thing in the morning — are not necessarily a problem, but long sustained periods of high values indicate an overworked DC.",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LinkValuesCleanedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "link_values_cleaned_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PhantomObjectsCleanedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "phantom_objects_cleaned_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PhantomObjectsVisitedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "phantom_objects_visited_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamGroupMembershipEvaluationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_group_membership_evaluations_total"),
|
||||
"",
|
||||
[]string{"group_type"},
|
||||
nil,
|
||||
),
|
||||
SamGroupMembershipGlobalCatalogEvaluationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_group_membership_global_catalog_evaluations_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamGroupMembershipEvaluationsNontransitiveTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_group_membership_evaluations_nontransitive_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamGroupMembershipEvaluationsTransitiveTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_group_membership_evaluations_transitive_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamGroupEvaluationLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_group_evaluation_latency"),
|
||||
"The mean latency of the last 100 group evaluations performed for authentication",
|
||||
[]string{"evaluation_type"},
|
||||
nil,
|
||||
),
|
||||
SamComputerCreationRequestsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_computer_creation_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamComputerCreationSuccessfulRequestsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_computer_creation_successful_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamUserCreationRequestsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_user_creation_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamUserCreationSuccessfulRequestsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_user_creation_successful_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamQueryDisplayRequestsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_query_display_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamEnumerationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_enumerations_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamMembershipChangesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_membership_changes_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SamPasswordChangesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sam_password_changes_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TombstonedObjectsCollectedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "tombstoned_objects_collected_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TombstonedObjectsVisitedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "tombstoned_objects_visited_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
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.AddressBookOperationsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "address_book_operations_total"),
|
||||
"",
|
||||
[]string{"operation"},
|
||||
nil,
|
||||
)
|
||||
c.AddressBookClientSessions = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "address_book_client_sessions"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ApproximateHighestDistinguishedNameTag = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "approximate_highest_distinguished_name_tag"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.AtqEstimatedDelaySeconds = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "atq_estimated_delay_seconds"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.AtqOutstandingRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "atq_outstanding_requests"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.AtqAverageRequestLatency = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "atq_average_request_latency"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.AtqCurrentThreads = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "atq_current_threads"),
|
||||
"",
|
||||
[]string{"service"},
|
||||
nil,
|
||||
)
|
||||
c.SearchesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "searches_total"),
|
||||
"",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
)
|
||||
c.DatabaseOperationsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "database_operations_total"),
|
||||
"",
|
||||
[]string{"operation"},
|
||||
nil,
|
||||
)
|
||||
c.BindsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "binds_total"),
|
||||
"",
|
||||
[]string{"bind_method"},
|
||||
nil,
|
||||
)
|
||||
c.ReplicationHighestUsn = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_highest_usn"),
|
||||
"",
|
||||
[]string{"state"},
|
||||
nil,
|
||||
)
|
||||
c.IntrasiteReplicationDataBytesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_data_intrasite_bytes_total"),
|
||||
"",
|
||||
[]string{"direction"},
|
||||
nil,
|
||||
)
|
||||
c.IntersiteReplicationDataBytesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_data_intersite_bytes_total"),
|
||||
"",
|
||||
[]string{"direction"},
|
||||
nil,
|
||||
)
|
||||
c.ReplicationInboundSyncObjectsRemaining = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_inbound_sync_objects_remaining"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationInboundLinkValueUpdatesRemaining = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_inbound_link_value_updates_remaining"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationInboundObjectsUpdatedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_inbound_objects_updated_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationInboundObjectsFilteredTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_inbound_objects_filtered_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationInboundPropertiesUpdatedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_inbound_properties_updated_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationInboundPropertiesFilteredTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_inbound_properties_filtered_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationPendingOperations = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_pending_operations"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationPendingSynchronizations = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_pending_synchronizations"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationSyncRequestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_sync_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationSyncRequestsSuccessTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_sync_requests_success_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReplicationSyncRequestsSchemaMismatchFailureTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replication_sync_requests_schema_mismatch_failure_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.NameTranslationsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "name_translations_total"),
|
||||
"",
|
||||
[]string{"target_name"},
|
||||
nil,
|
||||
)
|
||||
c.ChangeMonitorsRegistered = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "change_monitors_registered"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ChangeMonitorUpdatesPending = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "change_monitor_updates_pending"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.NameCacheHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "name_cache_hits_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.NameCacheLookupsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "name_cache_lookups_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DirectoryOperationsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "directory_operations_total"),
|
||||
"",
|
||||
[]string{"operation", "origin"},
|
||||
nil,
|
||||
)
|
||||
c.DirectorySearchSuboperationsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "directory_search_suboperations_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SecurityDescriptorPropagationEventsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "security_descriptor_propagation_events_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SecurityDescriptorPropagationEventsQueued = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "security_descriptor_propagation_events_queued"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SecurityDescriptorPropagationAccessWaitTotalSeconds = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "security_descriptor_propagation_access_wait_total_seconds"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SecurityDescriptorPropagationItemsQueuedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "security_descriptor_propagation_items_queued_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DirectoryServiceThreads = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "directory_service_threads"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LdapClosedConnectionsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ldap_closed_connections_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LdapOpenedConnectionsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ldap_opened_connections_total"),
|
||||
"",
|
||||
[]string{"type"},
|
||||
nil,
|
||||
)
|
||||
c.LdapActiveThreads = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ldap_active_threads"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LdapLastBindTimeSeconds = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ldap_last_bind_time_seconds"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LdapSearchesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ldap_searches_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LdapUdpOperationsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ldap_udp_operations_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LdapWritesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ldap_writes_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LdapClientSessions = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ldap_client_sessions"),
|
||||
"This is the number of sessions opened by LDAP clients at the time the data is taken. This is helpful in determining LDAP client activity and if the DC is able to handle the load. Of course, spikes during normal periods of authentication — such as first thing in the morning — are not necessarily a problem, but long sustained periods of high values indicate an overworked DC.",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LinkValuesCleanedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "link_values_cleaned_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.PhantomObjectsCleanedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "phantom_objects_cleaned_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.PhantomObjectsVisitedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "phantom_objects_visited_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamGroupMembershipEvaluationsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_group_membership_evaluations_total"),
|
||||
"",
|
||||
[]string{"group_type"},
|
||||
nil,
|
||||
)
|
||||
c.SamGroupMembershipGlobalCatalogEvaluationsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_group_membership_global_catalog_evaluations_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamGroupMembershipEvaluationsNontransitiveTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_group_membership_evaluations_nontransitive_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamGroupMembershipEvaluationsTransitiveTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_group_membership_evaluations_transitive_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamGroupEvaluationLatency = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_group_evaluation_latency"),
|
||||
"The mean latency of the last 100 group evaluations performed for authentication",
|
||||
[]string{"evaluation_type"},
|
||||
nil,
|
||||
)
|
||||
c.SamComputerCreationRequestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_computer_creation_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamComputerCreationSuccessfulRequestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_computer_creation_successful_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamUserCreationRequestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_user_creation_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamUserCreationSuccessfulRequestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_user_creation_successful_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamQueryDisplayRequestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_query_display_requests_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamEnumerationsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_enumerations_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamMembershipChangesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_membership_changes_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SamPasswordChangesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sam_password_changes_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
c.TombstonedObjectsCollectedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "tombstoned_objects_collected_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.TombstonedObjectsVisitedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "tombstoned_objects_visited_total"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *ADCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting ad metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
@@ -623,9 +649,9 @@ type Win32_PerfRawData_DirectoryServices_DirectoryServices struct {
|
||||
TransitivesuboperationsPersec uint32
|
||||
}
|
||||
|
||||
func (c *ADCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_DirectoryServices_DirectoryServices
|
||||
q := queryAll(&dst, c.logger)
|
||||
q := wmi.QueryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
12
pkg/collector/ad/ad_test.go
Normal file
12
pkg/collector/ad/ad_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package ad_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/ad"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, ad.Name, ad.NewWithFlags)
|
||||
}
|
||||
@@ -1,18 +1,27 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package adcs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type adcsCollector struct {
|
||||
const Name = "adcs"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
RequestsPerSecond *prometheus.Desc
|
||||
@@ -30,94 +39,112 @@ type adcsCollector struct {
|
||||
SignedCertificateTimestampListProcessingTime *prometheus.Desc
|
||||
}
|
||||
|
||||
// ADCSCollectorMethod ...
|
||||
func adcsCollectorMethod(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "adcs"
|
||||
return &adcsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
RequestsPerSecond: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "requests_total"),
|
||||
"Total certificate requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
RequestProcessingTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "request_processing_time_seconds"),
|
||||
"Last time elapsed for certificate requests",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
RetrievalsPerSecond: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "retrievals_total"),
|
||||
"Total certificate retrieval requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
RetrievalProcessingTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "retrievals_processing_time_seconds"),
|
||||
"Last time elapsed for certificate retrieval request",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
FailedRequestsPerSecond: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failed_requests_total"),
|
||||
"Total failed certificate requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
IssuedRequestsPerSecond: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "issued_requests_total"),
|
||||
"Total issued certificate requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
PendingRequestsPerSecond: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pending_requests_total"),
|
||||
"Total pending certificate requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
RequestCryptographicSigningTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "request_cryptographic_signing_time_seconds"),
|
||||
"Last time elapsed for signing operation request",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
RequestPolicyModuleProcessingTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "request_policy_module_processing_time_seconds"),
|
||||
"Last time elapsed for policy module processing request",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
ChallengeResponsesPerSecond: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "challenge_responses_total"),
|
||||
"Total certificate challenge responses processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
ChallengeResponseProcessingTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "challenge_response_processing_time_seconds"),
|
||||
"Last time elapsed for challenge response",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
SignedCertificateTimestampListsPerSecond: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "signed_certificate_timestamp_lists_total"),
|
||||
"Total Signed Certificate Timestamp Lists processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
SignedCertificateTimestampListProcessingTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "signed_certificate_timestamp_list_processing_time_seconds"),
|
||||
"Last time elapsed for Signed Certificate Timestamp List",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
func New(logger log.Logger, _ *Config) types.Collector {
|
||||
c := &collector{}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *adcsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
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{"Certification Authority"}, nil
|
||||
}
|
||||
|
||||
func (c *collector) Build() error {
|
||||
c.RequestsPerSecond = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "requests_total"),
|
||||
"Total certificate requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.RequestProcessingTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "request_processing_time_seconds"),
|
||||
"Last time elapsed for certificate requests",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.RetrievalsPerSecond = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "retrievals_total"),
|
||||
"Total certificate retrieval requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.RetrievalProcessingTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "retrievals_processing_time_seconds"),
|
||||
"Last time elapsed for certificate retrieval request",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.FailedRequestsPerSecond = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failed_requests_total"),
|
||||
"Total failed certificate requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.IssuedRequestsPerSecond = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "issued_requests_total"),
|
||||
"Total issued certificate requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.PendingRequestsPerSecond = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "pending_requests_total"),
|
||||
"Total pending certificate requests processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.RequestCryptographicSigningTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "request_cryptographic_signing_time_seconds"),
|
||||
"Last time elapsed for signing operation request",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.RequestPolicyModuleProcessingTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "request_policy_module_processing_time_seconds"),
|
||||
"Last time elapsed for policy module processing request",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.ChallengeResponsesPerSecond = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "challenge_responses_total"),
|
||||
"Total certificate challenge responses processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.ChallengeResponseProcessingTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "challenge_response_processing_time_seconds"),
|
||||
"Last time elapsed for challenge response",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.SignedCertificateTimestampListsPerSecond = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "signed_certificate_timestamp_lists_total"),
|
||||
"Total Signed Certificate Timestamp Lists processed",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
c.SignedCertificateTimestampListProcessingTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "signed_certificate_timestamp_list_processing_time_seconds"),
|
||||
"Last time elapsed for Signed Certificate Timestamp List",
|
||||
[]string{"cert_template"},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collectADCSCounters(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting ADCS metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
@@ -142,17 +169,17 @@ type perflibADCS struct {
|
||||
SignedCertificateTimestampListProcessingTime float64 `perflib:"Signed Certificate Timestamp List processing time (ms)"`
|
||||
}
|
||||
|
||||
func (c *adcsCollector) collectADCSCounters(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
func (c *collector) collectADCSCounters(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
dst := make([]perflibADCS, 0)
|
||||
if _, ok := ctx.perfObjects["Certification Authority"]; !ok {
|
||||
return nil, errors.New("Perflib did not contain an entry for Certification Authority")
|
||||
if _, ok := ctx.PerfObjects["Certification Authority"]; !ok {
|
||||
return nil, errors.New("perflib did not contain an entry for Certification Authority")
|
||||
}
|
||||
err := unmarshalObject(ctx.perfObjects["Certification Authority"], &dst, c.logger)
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dst) == 0 {
|
||||
return nil, errors.New("Perflib query for Certification Authority (ADCS) returned empty result set")
|
||||
return nil, errors.New("perflib query for Certification Authority (ADCS) returned empty result set")
|
||||
}
|
||||
|
||||
for _, d := range dst {
|
||||
@@ -169,7 +196,7 @@ func (c *adcsCollector) collectADCSCounters(ctx *ScrapeContext, ch chan<- promet
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RequestProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
milliSecToSec(d.RequestProcessingTime),
|
||||
utils.MilliSecToSec(d.RequestProcessingTime),
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
@@ -181,7 +208,7 @@ func (c *adcsCollector) collectADCSCounters(ctx *ScrapeContext, ch chan<- promet
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RetrievalProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
milliSecToSec(d.RetrievalProcessingTime),
|
||||
utils.MilliSecToSec(d.RetrievalProcessingTime),
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
@@ -205,13 +232,13 @@ func (c *adcsCollector) collectADCSCounters(ctx *ScrapeContext, ch chan<- promet
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RequestCryptographicSigningTime,
|
||||
prometheus.GaugeValue,
|
||||
milliSecToSec(d.RequestCryptographicSigningTime),
|
||||
utils.MilliSecToSec(d.RequestCryptographicSigningTime),
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RequestPolicyModuleProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
milliSecToSec(d.RequestPolicyModuleProcessingTime),
|
||||
utils.MilliSecToSec(d.RequestPolicyModuleProcessingTime),
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
@@ -223,7 +250,7 @@ func (c *adcsCollector) collectADCSCounters(ctx *ScrapeContext, ch chan<- promet
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ChallengeResponseProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
milliSecToSec(d.ChallengeResponseProcessingTime),
|
||||
utils.MilliSecToSec(d.ChallengeResponseProcessingTime),
|
||||
d.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
@@ -235,7 +262,7 @@ func (c *adcsCollector) collectADCSCounters(ctx *ScrapeContext, ch chan<- promet
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SignedCertificateTimestampListProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
milliSecToSec(d.SignedCertificateTimestampListProcessingTime),
|
||||
utils.MilliSecToSec(d.SignedCertificateTimestampListProcessingTime),
|
||||
d.Name,
|
||||
)
|
||||
}
|
||||
12
pkg/collector/adcs/adcs_test.go
Normal file
12
pkg/collector/adcs/adcs_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package adcs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/adcs"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, adcs.Name, adcs.NewWithFlags)
|
||||
}
|
||||
@@ -1,16 +1,24 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package adfs
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type adfsCollector struct {
|
||||
const Name = "adfs"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
adLoginConnectionFailures *prometheus.Desc
|
||||
@@ -58,272 +66,289 @@ type adfsCollector struct {
|
||||
federationMetadataRequests *prometheus.Desc
|
||||
}
|
||||
|
||||
// newADFSCollector constructs a new adfsCollector
|
||||
func newADFSCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "adfs"
|
||||
func New(logger log.Logger, _ *Config) types.Collector {
|
||||
c := &collector{}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
return &adfsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
func NewWithFlags(_ *kingpin.Application) types.Collector {
|
||||
return &collector{}
|
||||
}
|
||||
|
||||
adLoginConnectionFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ad_login_connection_failures_total"),
|
||||
"Total number of connection failures to an Active Directory domain controller",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
certificateAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "certificate_authentications_total"),
|
||||
"Total number of User Certificate authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
deviceAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "device_authentications_total"),
|
||||
"Total number of Device authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
extranetAccountLockouts: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "extranet_account_lockouts_total"),
|
||||
"Total number of Extranet Account Lockouts",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
federatedAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "federated_authentications_total"),
|
||||
"Total number of authentications from a federated source",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
passportAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "passport_authentications_total"),
|
||||
"Total number of Microsoft Passport SSO authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
passiveRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "passive_requests_total"),
|
||||
"Total number of passive (browser-based) requests",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
passwordChangeFailed: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "password_change_failed_total"),
|
||||
"Total number of failed password changes",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
passwordChangeSucceeded: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "password_change_succeeded_total"),
|
||||
"Total number of successful password changes",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
tokenRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "token_requests_total"),
|
||||
"Total number of token requests",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
windowsIntegratedAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "windows_integrated_authentications_total"),
|
||||
"Total number of Windows integrated authentications (Kerberos/NTLM)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthAuthZRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_authorization_requests_total"),
|
||||
"Total number of incoming requests to the OAuth Authorization endpoint",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_authentication_success_total"),
|
||||
"Total number of successful OAuth client Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientAuthenticationsFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_authentication_failure_total"),
|
||||
"Total number of failed OAuth client Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientCredentialsRequestFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_credentials_failure_total"),
|
||||
"Total number of failed OAuth Client Credentials Requests",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientCredentialsRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_credentials_success_total"),
|
||||
"Total number of successful RP tokens issued for OAuth Client Credentials Requests",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientPrivateKeyJwtAuthenticationFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_privkey_jwt_authentication_failure_total"),
|
||||
"Total number of failed OAuth Client Private Key Jwt Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientPrivateKeyJwtAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_privkey_jwt_authentications_success_total"),
|
||||
"Total number of successful OAuth Client Private Key Jwt Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientSecretBasicAuthenticationFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_secret_basic_authentications_failure_total"),
|
||||
"Total number of failed OAuth Client Secret Basic Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientSecretBasicAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_secret_basic_authentications_success_total"),
|
||||
"Total number of successful OAuth Client Secret Basic Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientSecretPostAuthenticationFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_secret_post_authentications_failure_total"),
|
||||
"Total number of failed OAuth Client Secret Post Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientSecretPostAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_secret_post_authentications_success_total"),
|
||||
"Total number of successful OAuth Client Secret Post Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientWindowsIntegratedAuthenticationFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_windows_authentications_failure_total"),
|
||||
"Total number of failed OAuth Client Windows Integrated Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthClientWindowsIntegratedAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_windows_authentications_success_total"),
|
||||
"Total number of successful OAuth Client Windows Integrated Authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthLogonCertificateRequestFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_logon_certificate_requests_failure_total"),
|
||||
"Total number of failed OAuth Logon Certificate Requests",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthLogonCertificateTokenRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_logon_certificate_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued for OAuth Logon Certificate Requests",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthPasswordGrantRequestFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_password_grant_requests_failure_total"),
|
||||
"Total number of failed OAuth Password Grant Requests",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthPasswordGrantRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_password_grant_requests_success_total"),
|
||||
"Total number of successful OAuth Password Grant Requests",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
oAuthTokenRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over OAuth protocol",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
samlPTokenRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "samlp_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over SAML-P protocol",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ssoAuthenticationFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sso_authentications_failure_total"),
|
||||
"Total number of failed SSO authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ssoAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sso_authentications_success_total"),
|
||||
"Total number of successful SSO authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
wsfedTokenRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "wsfed_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over WS-Fed protocol",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
wstrustTokenRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "wstrust_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over WS-Trust protocol",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
upAuthenticationFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "userpassword_authentications_failure_total"),
|
||||
"Total number of failed AD U/P authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
upAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "userpassword_authentications_success_total"),
|
||||
"Total number of successful AD U/P authentications",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
externalAuthenticationFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "external_authentications_failure_total"),
|
||||
"Total number of failed authentications from external MFA providers",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
externalAuthentications: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "external_authentications_success_total"),
|
||||
"Total number of successful authentications from external MFA providers",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
artifactDBFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "db_artifact_failure_total"),
|
||||
"Total number of failures connecting to the artifact database",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
avgArtifactDBQueryTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "db_artifact_query_time_seconds_total"),
|
||||
"Accumulator of time taken for an artifact database query",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
configDBFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "db_config_failure_total"),
|
||||
"Total number of failures connecting to the configuration database",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
avgConfigDBQueryTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "db_config_query_time_seconds_total"),
|
||||
"Accumulator of time taken for a configuration database query",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
federationMetadataRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "federation_metadata_requests_total"),
|
||||
"Total number of Federation Metadata requests",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
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{"AD FS"}, nil
|
||||
}
|
||||
|
||||
func (c *collector) Build() error {
|
||||
c.adLoginConnectionFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ad_login_connection_failures_total"),
|
||||
"Total number of connection failures to an Active Directory domain controller",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.certificateAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "certificate_authentications_total"),
|
||||
"Total number of User Certificate authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.deviceAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "device_authentications_total"),
|
||||
"Total number of Device authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.extranetAccountLockouts = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "extranet_account_lockouts_total"),
|
||||
"Total number of Extranet Account Lockouts",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.federatedAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "federated_authentications_total"),
|
||||
"Total number of authentications from a federated source",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.passportAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "passport_authentications_total"),
|
||||
"Total number of Microsoft Passport SSO authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.passiveRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "passive_requests_total"),
|
||||
"Total number of passive (browser-based) requests",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.passwordChangeFailed = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "password_change_failed_total"),
|
||||
"Total number of failed password changes",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.passwordChangeSucceeded = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "password_change_succeeded_total"),
|
||||
"Total number of successful password changes",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.tokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "token_requests_total"),
|
||||
"Total number of token requests",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.windowsIntegratedAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "windows_integrated_authentications_total"),
|
||||
"Total number of Windows integrated authentications (Kerberos/NTLM)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthAuthZRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_authorization_requests_total"),
|
||||
"Total number of incoming requests to the OAuth Authorization endpoint",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_authentication_success_total"),
|
||||
"Total number of successful OAuth client Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientAuthenticationsFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_authentication_failure_total"),
|
||||
"Total number of failed OAuth client Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientCredentialsRequestFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_credentials_failure_total"),
|
||||
"Total number of failed OAuth Client Credentials Requests",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientCredentialsRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_credentials_success_total"),
|
||||
"Total number of successful RP tokens issued for OAuth Client Credentials Requests",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientPrivateKeyJwtAuthenticationFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_privkey_jwt_authentication_failure_total"),
|
||||
"Total number of failed OAuth Client Private Key Jwt Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientPrivateKeyJwtAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_privkey_jwt_authentications_success_total"),
|
||||
"Total number of successful OAuth Client Private Key Jwt Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientSecretBasicAuthenticationFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_secret_basic_authentications_failure_total"),
|
||||
"Total number of failed OAuth Client Secret Basic Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientSecretBasicAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_secret_basic_authentications_success_total"),
|
||||
"Total number of successful OAuth Client Secret Basic Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientSecretPostAuthenticationFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_secret_post_authentications_failure_total"),
|
||||
"Total number of failed OAuth Client Secret Post Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientSecretPostAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_secret_post_authentications_success_total"),
|
||||
"Total number of successful OAuth Client Secret Post Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientWindowsIntegratedAuthenticationFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_windows_authentications_failure_total"),
|
||||
"Total number of failed OAuth Client Windows Integrated Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthClientWindowsIntegratedAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_client_windows_authentications_success_total"),
|
||||
"Total number of successful OAuth Client Windows Integrated Authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthLogonCertificateRequestFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_logon_certificate_requests_failure_total"),
|
||||
"Total number of failed OAuth Logon Certificate Requests",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthLogonCertificateTokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_logon_certificate_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued for OAuth Logon Certificate Requests",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthPasswordGrantRequestFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_password_grant_requests_failure_total"),
|
||||
"Total number of failed OAuth Password Grant Requests",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthPasswordGrantRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_password_grant_requests_success_total"),
|
||||
"Total number of successful OAuth Password Grant Requests",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.oAuthTokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "oauth_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over OAuth protocol",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.samlPTokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "samlp_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over SAML-P protocol",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ssoAuthenticationFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sso_authentications_failure_total"),
|
||||
"Total number of failed SSO authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ssoAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sso_authentications_success_total"),
|
||||
"Total number of successful SSO authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.wsfedTokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "wsfed_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over WS-Fed protocol",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.wstrustTokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "wstrust_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over WS-Trust protocol",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.upAuthenticationFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "userpassword_authentications_failure_total"),
|
||||
"Total number of failed AD U/P authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.upAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "userpassword_authentications_success_total"),
|
||||
"Total number of successful AD U/P authentications",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.externalAuthenticationFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "external_authentications_failure_total"),
|
||||
"Total number of failed authentications from external MFA providers",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.externalAuthentications = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "external_authentications_success_total"),
|
||||
"Total number of successful authentications from external MFA providers",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.artifactDBFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "db_artifact_failure_total"),
|
||||
"Total number of failures connecting to the artifact database",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.avgArtifactDBQueryTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "db_artifact_query_time_seconds_total"),
|
||||
"Accumulator of time taken for an artifact database query",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.configDBFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "db_config_failure_total"),
|
||||
"Total number of failures connecting to the configuration database",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.avgConfigDBQueryTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "db_config_query_time_seconds_total"),
|
||||
"Accumulator of time taken for a configuration database query",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.federationMetadataRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "federation_metadata_requests_total"),
|
||||
"Total number of Federation Metadata requests",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type perflibADFS struct {
|
||||
@@ -372,9 +397,9 @@ type perflibADFS struct {
|
||||
FederationMetadataRequests float64 `perflib:"Federation Metadata Requests"`
|
||||
}
|
||||
|
||||
func (c *adfsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var adfsData []perflibADFS
|
||||
err := unmarshalObject(ctx.perfObjects["AD FS"], &adfsData, c.logger)
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["AD FS"], &adfsData, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
12
pkg/collector/adfs/adfs_test.go
Normal file
12
pkg/collector/adfs/adfs_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package adfs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/adfs"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, adfs.Name, adfs.NewWithFlags)
|
||||
}
|
||||
399
collector/cache.go → pkg/collector/cache/cache.go
vendored
399
collector/cache.go → pkg/collector/cache/cache.go
vendored
@@ -1,16 +1,24 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package cache
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// A CacheCollector is a Prometheus collector for Perflib Cache metrics
|
||||
type CacheCollector struct {
|
||||
const Name = "cache"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A collector is a Prometheus collector for Perflib Cache metrics
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
AsyncCopyReadsTotal *prometheus.Desc
|
||||
@@ -44,191 +52,208 @@ type CacheCollector struct {
|
||||
SyncPinReadsTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewCacheCollector ...
|
||||
func newCacheCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "cache"
|
||||
return &CacheCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
func New(logger log.Logger, _ *Config) types.Collector {
|
||||
c := &collector{}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
AsyncCopyReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "async_copy_reads_total"),
|
||||
"(AsyncCopyReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AsyncDataMapsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "async_data_maps_total"),
|
||||
"(AsyncDataMapsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AsyncFastReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "async_fast_reads_total"),
|
||||
"(AsyncFastReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AsyncMDLReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "async_mdl_reads_total"),
|
||||
"(AsyncMDLReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AsyncPinReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "async_pin_reads_total"),
|
||||
"(AsyncPinReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
CopyReadHitsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "copy_read_hits_total"),
|
||||
"(CopyReadHitsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
CopyReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "copy_reads_total"),
|
||||
"(CopyReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DataFlushesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "data_flushes_total"),
|
||||
"(DataFlushesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DataFlushPagesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "data_flush_pages_total"),
|
||||
"(DataFlushPagesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DataMapHitsPercent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "data_map_hits_percent"),
|
||||
"(DataMapHitsPercent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DataMapPinsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "data_map_pins_total"),
|
||||
"(DataMapPinsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DataMapsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "data_maps_total"),
|
||||
"(DataMapsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DirtyPages: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "dirty_pages"),
|
||||
"(DirtyPages)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DirtyPageThreshold: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "dirty_page_threshold"),
|
||||
"(DirtyPageThreshold)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FastReadNotPossiblesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "fast_read_not_possibles_total"),
|
||||
"(FastReadNotPossiblesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FastReadResourceMissesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "fast_read_resource_misses_total"),
|
||||
"(FastReadResourceMissesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FastReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "fast_reads_total"),
|
||||
"(FastReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LazyWriteFlushesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "lazy_write_flushes_total"),
|
||||
"(LazyWriteFlushesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LazyWritePagesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "lazy_write_pages_total"),
|
||||
"(LazyWritePagesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
MDLReadHitsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "mdl_read_hits_total"),
|
||||
"(MDLReadHitsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
MDLReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "mdl_reads_total"),
|
||||
"(MDLReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PinReadHitsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pin_read_hits_total"),
|
||||
"(PinReadHitsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PinReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "pin_reads_total"),
|
||||
"(PinReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReadAheadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_aheads_total"),
|
||||
"(ReadAheadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SyncCopyReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sync_copy_reads_total"),
|
||||
"(SyncCopyReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SyncDataMapsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sync_data_maps_total"),
|
||||
"(SyncDataMapsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SyncFastReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sync_fast_reads_total"),
|
||||
"(SyncFastReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SyncMDLReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sync_mdl_reads_total"),
|
||||
"(SyncMDLReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SyncPinReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "sync_pin_reads_total"),
|
||||
"(SyncPinReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
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{"Cache"}, nil
|
||||
}
|
||||
|
||||
func (c *collector) Build() error {
|
||||
c.AsyncCopyReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "async_copy_reads_total"),
|
||||
"(AsyncCopyReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.AsyncDataMapsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "async_data_maps_total"),
|
||||
"(AsyncDataMapsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.AsyncFastReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "async_fast_reads_total"),
|
||||
"(AsyncFastReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.AsyncMDLReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "async_mdl_reads_total"),
|
||||
"(AsyncMDLReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.AsyncPinReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "async_pin_reads_total"),
|
||||
"(AsyncPinReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.CopyReadHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "copy_read_hits_total"),
|
||||
"(CopyReadHitsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.CopyReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "copy_reads_total"),
|
||||
"(CopyReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DataFlushesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "data_flushes_total"),
|
||||
"(DataFlushesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DataFlushPagesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "data_flush_pages_total"),
|
||||
"(DataFlushPagesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DataMapHitsPercent = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "data_map_hits_percent"),
|
||||
"(DataMapHitsPercent)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DataMapPinsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "data_map_pins_total"),
|
||||
"(DataMapPinsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DataMapsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "data_maps_total"),
|
||||
"(DataMapsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DirtyPages = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dirty_pages"),
|
||||
"(DirtyPages)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DirtyPageThreshold = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dirty_page_threshold"),
|
||||
"(DirtyPageThreshold)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FastReadNotPossiblesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "fast_read_not_possibles_total"),
|
||||
"(FastReadNotPossiblesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FastReadResourceMissesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "fast_read_resource_misses_total"),
|
||||
"(FastReadResourceMissesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FastReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "fast_reads_total"),
|
||||
"(FastReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LazyWriteFlushesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "lazy_write_flushes_total"),
|
||||
"(LazyWriteFlushesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.LazyWritePagesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "lazy_write_pages_total"),
|
||||
"(LazyWritePagesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.MDLReadHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "mdl_read_hits_total"),
|
||||
"(MDLReadHitsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.MDLReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "mdl_reads_total"),
|
||||
"(MDLReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.PinReadHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "pin_read_hits_total"),
|
||||
"(PinReadHitsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.PinReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "pin_reads_total"),
|
||||
"(PinReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReadAheadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "read_aheads_total"),
|
||||
"(ReadAheadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SyncCopyReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sync_copy_reads_total"),
|
||||
"(SyncCopyReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SyncDataMapsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sync_data_maps_total"),
|
||||
"(SyncDataMapsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SyncFastReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sync_fast_reads_total"),
|
||||
"(SyncFastReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SyncMDLReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sync_mdl_reads_total"),
|
||||
"(SyncMDLReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SyncPinReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sync_pin_reads_total"),
|
||||
"(SyncPinReadsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect implements the Collector interface
|
||||
func (c *CacheCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting cache metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
@@ -270,9 +295,9 @@ type perflibCache struct {
|
||||
SyncPinReadsTotal float64 `perflib:"Sync Pin Reads/sec"`
|
||||
}
|
||||
|
||||
func (c *CacheCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []perflibCache // Single-instance class, array is required but will have single entry.
|
||||
if err := unmarshalObject(ctx.perfObjects["Cache"], &dst, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["Cache"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
105
pkg/collector/collector.go
Normal file
105
pkg/collector/collector.go
Normal file
@@ -0,0 +1,105 @@
|
||||
//go:build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
)
|
||||
|
||||
type Collectors struct {
|
||||
logger log.Logger
|
||||
|
||||
collectors map[string]types.Collector
|
||||
perfCounterQuery string
|
||||
}
|
||||
|
||||
// NewWithFlags To be called by the exporter for collector initialization before running kingpin.Parse
|
||||
func NewWithFlags(app *kingpin.Application) Collectors {
|
||||
collectors := map[string]types.Collector{}
|
||||
|
||||
for name, builder := range Map {
|
||||
collectors[name] = builder(app)
|
||||
}
|
||||
|
||||
return New(collectors)
|
||||
}
|
||||
|
||||
// New To be called by the external libraries for collector initialization without running kingpin.Parse
|
||||
func New(collectors map[string]types.Collector) Collectors {
|
||||
return Collectors{
|
||||
collectors: collectors,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Collectors) SetLogger(logger log.Logger) {
|
||||
c.logger = logger
|
||||
|
||||
for _, collector := range c.collectors {
|
||||
collector.SetLogger(logger)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Collectors) SetPerfCounterQuery() error {
|
||||
var (
|
||||
err error
|
||||
|
||||
perfCounterDependencies []string
|
||||
perfCounterNames []string
|
||||
perfIndicies []string
|
||||
)
|
||||
|
||||
for _, collector := range c.collectors {
|
||||
perfCounterNames, err = collector.GetPerfCounter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
perfIndicies = make([]string, 0, len(perfCounterNames))
|
||||
for _, cn := range perfCounterNames {
|
||||
perfIndicies = append(perfIndicies, perflib.MapCounterToIndex(cn))
|
||||
}
|
||||
|
||||
perfCounterDependencies = append(perfCounterDependencies, strings.Join(perfIndicies, " "))
|
||||
}
|
||||
|
||||
c.perfCounterQuery = strings.Join(perfCounterDependencies, " ")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Enable removes all collectors that not enabledCollectors
|
||||
func (c *Collectors) Enable(enabledCollectors []string) {
|
||||
for name := range c.collectors {
|
||||
if !slices.Contains(enabledCollectors, name) {
|
||||
delete(c.collectors, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build To be called by the exporter for collector initialization
|
||||
func (c *Collectors) Build() error {
|
||||
var err error
|
||||
for _, collector := range c.collectors {
|
||||
if err = collector.Build(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrepareScrapeContext creates a ScrapeContext to be used during a single scrape
|
||||
func (c *Collectors) PrepareScrapeContext() (*types.ScrapeContext, error) {
|
||||
objs, err := perflib.GetPerflibSnapshot(c.perfCounterQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.ScrapeContext{PerfObjects: objs}, nil
|
||||
}
|
||||
165
pkg/collector/config.go
Normal file
165
pkg/collector/config.go
Normal file
@@ -0,0 +1,165 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"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/adfs"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/cache"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/container"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/cpu"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/cpu_info"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/cs"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/dfsr"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/dhcp"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/diskdrive"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/dns"
|
||||
"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/iis"
|
||||
"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/msmq"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/mssql"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/net"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/netframework_clrexceptions"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/netframework_clrinterop"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/netframework_clrjit"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/netframework_clrloading"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/netframework_clrlocksandthreads"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/netframework_clrmemory"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/netframework_clrremoting"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/netframework_clrsecurity"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/nps"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/os"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/physical_disk"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/process"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/remote_fx"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/scheduled_task"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/service"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/smtp"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/system"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/tcp"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/teradici_pcoip"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/terminal_services"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/textfile"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/thermalzone"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/time"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/vmware"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/vmware_blast"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Ad ad.Config `yaml:"ad"`
|
||||
Adcs adcs.Config `yaml:"adcs"`
|
||||
Adfs adfs.Config `yaml:"adfs"`
|
||||
Cache cache.Config `yaml:"cache"`
|
||||
Container container.Config `yaml:"container"`
|
||||
Cpu cpu.Config `yaml:"cpu"`
|
||||
CpuInfo cpu_info.Config `yaml:"cpu_info"`
|
||||
Cs cs.Config `yaml:"cs"`
|
||||
Dfsr dfsr.Config `yaml:"dfsr"`
|
||||
Dhcp dhcp.Config `yaml:"dhcp"`
|
||||
Diskdrive diskdrive.Config `yaml:"diskdrive"`
|
||||
Dns dns.Config `yaml:"dns"`
|
||||
Exchange exchange.Config `yaml:"exchange"`
|
||||
Fsrmquota exchange.Config `yaml:"fsrmquota"`
|
||||
Hyperv hyperv.Config `yaml:"hyperv"`
|
||||
Iis iis.Config `yaml:"iis"`
|
||||
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"`
|
||||
Msmq msmq.Config `yaml:"msmq"`
|
||||
Mssql mssql.Config `yaml:"mssql"`
|
||||
Net net.Config `yaml:"net"`
|
||||
NetframeworkClrexceptions netframework_clrexceptions.Config `yaml:"netframework_clrexceptions"`
|
||||
NetframeworkClrinterop netframework_clrinterop.Config `yaml:"netframework_clrinterop"`
|
||||
NetframeworkClrjit netframework_clrjit.Config `yaml:"netframework_clrjit"`
|
||||
NetframeworkClrloading netframework_clrloading.Config `yaml:"netframework_clrloading"`
|
||||
NetframeworkClrlocksandthreads netframework_clrlocksandthreads.Config `yaml:"netframework_clrlocksandthreads"`
|
||||
NetframeworkClrmemory netframework_clrmemory.Config `yaml:"netframework_clrmemory"`
|
||||
NetframeworkClrremoting netframework_clrremoting.Config `yaml:"netframework_clrremoting"`
|
||||
NetframeworkClrsecurity netframework_clrsecurity.Config `yaml:"netframework_clrsecurity"`
|
||||
Nps nps.Config `yaml:"nps"`
|
||||
Os os.Config `yaml:"os"`
|
||||
PhysicalDisk physical_disk.Config `yaml:"physical_disk"`
|
||||
Process process.Config `yaml:"process"`
|
||||
RemoteFx remote_fx.Config `yaml:"remote_fx"`
|
||||
ScheduledTask scheduled_task.Config `yaml:"scheduled_task"`
|
||||
Service service.Config `yaml:"service"`
|
||||
Smtp smtp.Config `yaml:"smtp"`
|
||||
System system.Config `yaml:"system"`
|
||||
TeradiciPcoip teradici_pcoip.Config `yaml:"teradici_pcoip"`
|
||||
Tcp tcp.Config `yaml:"tcp"`
|
||||
TerminalServices terminal_services.Config `yaml:"terminal_services"`
|
||||
Textfile textfile.Config `yaml:"textfile"`
|
||||
Thermalzone thermalzone.Config `yaml:"thermalzone"`
|
||||
Time time.Config `yaml:"time"`
|
||||
Vmware vmware.Config `yaml:"vmware"`
|
||||
VmwareBlast vmware_blast.Config `yaml:"vmware_blast"`
|
||||
}
|
||||
|
||||
var ConfigDefaults = Config{
|
||||
Ad: ad.ConfigDefaults,
|
||||
Adcs: adcs.ConfigDefaults,
|
||||
Adfs: adfs.ConfigDefaults,
|
||||
Cache: cache.ConfigDefaults,
|
||||
Container: container.ConfigDefaults,
|
||||
Cpu: cpu.ConfigDefaults,
|
||||
CpuInfo: cpu_info.ConfigDefaults,
|
||||
Cs: cs.ConfigDefaults,
|
||||
Dfsr: dfsr.ConfigDefaults,
|
||||
Dhcp: dhcp.ConfigDefaults,
|
||||
Diskdrive: diskdrive.ConfigDefaults,
|
||||
Dns: dns.ConfigDefaults,
|
||||
Exchange: exchange.ConfigDefaults,
|
||||
Fsrmquota: exchange.ConfigDefaults,
|
||||
Hyperv: hyperv.ConfigDefaults,
|
||||
Iis: iis.ConfigDefaults,
|
||||
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,
|
||||
Msmq: msmq.ConfigDefaults,
|
||||
Mssql: mssql.ConfigDefaults,
|
||||
Net: net.ConfigDefaults,
|
||||
NetframeworkClrexceptions: netframework_clrexceptions.ConfigDefaults,
|
||||
NetframeworkClrinterop: netframework_clrinterop.ConfigDefaults,
|
||||
NetframeworkClrjit: netframework_clrjit.ConfigDefaults,
|
||||
NetframeworkClrloading: netframework_clrloading.ConfigDefaults,
|
||||
NetframeworkClrlocksandthreads: netframework_clrlocksandthreads.ConfigDefaults,
|
||||
NetframeworkClrmemory: netframework_clrmemory.ConfigDefaults,
|
||||
NetframeworkClrremoting: netframework_clrremoting.ConfigDefaults,
|
||||
NetframeworkClrsecurity: netframework_clrsecurity.ConfigDefaults,
|
||||
Nps: nps.ConfigDefaults,
|
||||
Os: os.ConfigDefaults,
|
||||
PhysicalDisk: physical_disk.ConfigDefaults,
|
||||
Process: process.ConfigDefaults,
|
||||
RemoteFx: remote_fx.ConfigDefaults,
|
||||
ScheduledTask: scheduled_task.ConfigDefaults,
|
||||
Service: service.ConfigDefaults,
|
||||
Smtp: smtp.ConfigDefaults,
|
||||
System: system.ConfigDefaults,
|
||||
TeradiciPcoip: teradici_pcoip.ConfigDefaults,
|
||||
Tcp: tcp.ConfigDefaults,
|
||||
TerminalServices: terminal_services.ConfigDefaults,
|
||||
Textfile: textfile.ConfigDefaults,
|
||||
Thermalzone: thermalzone.ConfigDefaults,
|
||||
Time: time.ConfigDefaults,
|
||||
Vmware: vmware.ConfigDefaults,
|
||||
VmwareBlast: vmware_blast.ConfigDefaults,
|
||||
}
|
||||
400
pkg/collector/container/container.go
Normal file
400
pkg/collector/container/container.go
Normal file
@@ -0,0 +1,400 @@
|
||||
//go:build windows
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "container"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A collector is a Prometheus collector for containers metrics
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
// Presence
|
||||
ContainerAvailable *prometheus.Desc
|
||||
|
||||
// Number of containers
|
||||
ContainersCount *prometheus.Desc
|
||||
// memory
|
||||
UsageCommitBytes *prometheus.Desc
|
||||
UsageCommitPeakBytes *prometheus.Desc
|
||||
UsagePrivateWorkingSetBytes *prometheus.Desc
|
||||
|
||||
// CPU
|
||||
RuntimeTotal *prometheus.Desc
|
||||
RuntimeUser *prometheus.Desc
|
||||
RuntimeKernel *prometheus.Desc
|
||||
|
||||
// Network
|
||||
BytesReceived *prometheus.Desc
|
||||
BytesSent *prometheus.Desc
|
||||
PacketsReceived *prometheus.Desc
|
||||
PacketsSent *prometheus.Desc
|
||||
DroppedPacketsIncoming *prometheus.Desc
|
||||
DroppedPacketsOutgoing *prometheus.Desc
|
||||
|
||||
// Storage
|
||||
ReadCountNormalized *prometheus.Desc
|
||||
ReadSizeBytes *prometheus.Desc
|
||||
WriteCountNormalized *prometheus.Desc
|
||||
WriteSizeBytes *prometheus.Desc
|
||||
}
|
||||
|
||||
// New constructs a new collector
|
||||
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.ContainerAvailable = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "available"),
|
||||
"Available",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.ContainersCount = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "count"),
|
||||
"Number of containers",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.UsageCommitBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "memory_usage_commit_bytes"),
|
||||
"Memory Usage Commit Bytes",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.UsageCommitPeakBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "memory_usage_commit_peak_bytes"),
|
||||
"Memory Usage Commit Peak Bytes",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.UsagePrivateWorkingSetBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "memory_usage_private_working_set_bytes"),
|
||||
"Memory Usage Private Working Set Bytes",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.RuntimeTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cpu_usage_seconds_total"),
|
||||
"Total Run time in Seconds",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.RuntimeUser = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cpu_usage_seconds_usermode"),
|
||||
"Run Time in User mode in Seconds",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.RuntimeKernel = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cpu_usage_seconds_kernelmode"),
|
||||
"Run time in Kernel mode in Seconds",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.BytesReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "network_receive_bytes_total"),
|
||||
"Bytes Received on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
)
|
||||
c.BytesSent = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "network_transmit_bytes_total"),
|
||||
"Bytes Sent on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
)
|
||||
c.PacketsReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "network_receive_packets_total"),
|
||||
"Packets Received on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
)
|
||||
c.PacketsSent = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "network_transmit_packets_total"),
|
||||
"Packets Sent on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
)
|
||||
c.DroppedPacketsIncoming = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "network_receive_packets_dropped_total"),
|
||||
"Dropped Incoming Packets on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
)
|
||||
c.DroppedPacketsOutgoing = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "network_transmit_packets_dropped_total"),
|
||||
"Dropped Outgoing Packets on Interface",
|
||||
[]string{"container_id", "interface"},
|
||||
nil,
|
||||
)
|
||||
c.ReadCountNormalized = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "storage_read_count_normalized_total"),
|
||||
"Read Count Normalized",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.ReadSizeBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "storage_read_size_bytes_total"),
|
||||
"Read Size Bytes",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.WriteCountNormalized = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "storage_write_count_normalized_total"),
|
||||
"Write Count Normalized",
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
c.WriteSizeBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "storage_write_size_bytes_total"),
|
||||
"Write Size Bytes",
|
||||
[]string{"container_id"},
|
||||
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 desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting collector metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// containerClose closes the container resource
|
||||
func (c *collector) containerClose(container hcsshim.Container) {
|
||||
err := container.Close()
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
// Types Container is passed to get the containers compute systems only
|
||||
containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "Err in Getting containers", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
count := len(containers)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ContainersCount,
|
||||
prometheus.GaugeValue,
|
||||
float64(count),
|
||||
)
|
||||
if count == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
containerPrefixes := make(map[string]string)
|
||||
|
||||
for _, containerDetails := range containers {
|
||||
// https://stackoverflow.com/questions/45617758/proper-way-to-release-resources-with-defer-in-a-loop
|
||||
func() {
|
||||
container, err := hcsshim.OpenContainer(containerDetails.ID)
|
||||
if container != nil {
|
||||
defer c.containerClose(container)
|
||||
}
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "err in opening container", "containerId", containerDetails.ID, "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
cstats, err := container.Statistics()
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "err in fetching container Statistics", "containerId", containerDetails.ID, "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
containerIdWithPrefix := getContainerIdWithPrefix(containerDetails)
|
||||
containerPrefixes[containerDetails.ID] = containerIdWithPrefix
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ContainerAvailable,
|
||||
prometheus.CounterValue,
|
||||
1,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.UsageCommitBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(cstats.Memory.UsageCommitBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.UsageCommitPeakBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(cstats.Memory.UsageCommitPeakBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.UsagePrivateWorkingSetBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(cstats.Memory.UsagePrivateWorkingSetBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RuntimeTotal,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Processor.TotalRuntime100ns)*perflib.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RuntimeUser,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Processor.RuntimeUser100ns)*perflib.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RuntimeKernel,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Processor.RuntimeKernel100ns)*perflib.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadCountNormalized,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.ReadCountNormalized),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadSizeBytes,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.ReadSizeBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteCountNormalized,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.WriteCountNormalized),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteSizeBytes,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.WriteSizeBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
}()
|
||||
}
|
||||
|
||||
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for containers")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if len(hnsEndpoints) == 0 {
|
||||
_ = level.Info(c.logger).Log("msg", fmt.Sprintf("No network stats for containers to collect"))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, endpoint := range hnsEndpoints {
|
||||
endpointStats, err := hcsshim.GetHNSEndpointStats(endpoint.Id)
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Failed to collect network stats for interface %s", endpoint.Id), "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, containerId := range endpoint.SharedContainers {
|
||||
containerIdWithPrefix, ok := containerPrefixes[containerId]
|
||||
endpointId := strings.ToUpper(endpoint.Id)
|
||||
|
||||
if !ok {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Failed to collect network stats for container %s", containerId))
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.BytesReceived),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesSent,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.BytesSent),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.PacketsReceived),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.PacketsSent),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DroppedPacketsIncoming,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.DroppedPacketsIncoming),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DroppedPacketsOutgoing,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.DroppedPacketsOutgoing),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getContainerIdWithPrefix(containerDetails hcsshim.ContainerProperties) string {
|
||||
switch containerDetails.Owner {
|
||||
case "containerd-shim-runhcs-v1.exe":
|
||||
return "containerd://" + containerDetails.ID
|
||||
default:
|
||||
// default to docker or if owner is not set
|
||||
return "docker://" + containerDetails.ID
|
||||
}
|
||||
}
|
||||
12
pkg/collector/container/container_test.go
Normal file
12
pkg/collector/container/container_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package container_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/container"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, container.Name, container.NewWithFlags)
|
||||
}
|
||||
@@ -1,30 +1,32 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/winversion"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type cpuCollectorBasic struct {
|
||||
const Name = "cpu"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
CStateSecondsTotal *prometheus.Desc
|
||||
TimeTotal *prometheus.Desc
|
||||
InterruptsTotal *prometheus.Desc
|
||||
DPCsTotal *prometheus.Desc
|
||||
}
|
||||
type cpuCollectorFull struct {
|
||||
logger log.Logger
|
||||
|
||||
CStateSecondsTotal *prometheus.Desc
|
||||
TimeTotal *prometheus.Desc
|
||||
InterruptsTotal *prometheus.Desc
|
||||
DPCsTotal *prometheus.Desc
|
||||
ClockInterruptsTotal *prometheus.Desc
|
||||
IdleBreakEventsTotal *prometheus.Desc
|
||||
ParkingStatus *prometheus.Desc
|
||||
@@ -37,129 +39,155 @@ type cpuCollectorFull struct {
|
||||
ProcessorPrivUtility *prometheus.Desc
|
||||
}
|
||||
|
||||
// newCPUCollector constructs a new cpuCollector, appropriate for the running OS
|
||||
func newCPUCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "cpu"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
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) {
|
||||
if winversion.WindowsVersionFloat > 6.05 {
|
||||
return []string{"Processor Information"}, nil
|
||||
}
|
||||
return []string{"Processor"}, nil
|
||||
}
|
||||
|
||||
func (c *collector) Build() error {
|
||||
c.CStateSecondsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cstate_seconds_total"),
|
||||
"Time spent in low-power idle state",
|
||||
[]string{"core", "state"},
|
||||
nil,
|
||||
)
|
||||
c.TimeTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "time_total"),
|
||||
"Time that processor spent in different modes (dpc, idle, interrupt, privileged, user)",
|
||||
[]string{"core", "mode"},
|
||||
nil,
|
||||
)
|
||||
c.InterruptsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "interrupts_total"),
|
||||
"Total number of received and serviced hardware interrupts",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.DPCsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dpcs_total"),
|
||||
"Total number of received and serviced deferred procedure calls (DPCs)",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
|
||||
version := getWindowsVersion(logger)
|
||||
// For Windows 2008 (version 6.0) or earlier we only have the "Processor"
|
||||
// class. As of Windows 2008 R2 (version 6.1) the more detailed
|
||||
// "Processor Information" set is available (although some of the counters
|
||||
// are added in later versions, so we aren't guaranteed to get all of
|
||||
// them).
|
||||
// Value 6.05 was selected to split between Windows versions.
|
||||
if version < 6.05 {
|
||||
return &cpuCollectorBasic{
|
||||
logger: logger,
|
||||
CStateSecondsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cstate_seconds_total"),
|
||||
"Time spent in low-power idle state",
|
||||
[]string{"core", "state"},
|
||||
nil,
|
||||
),
|
||||
TimeTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "time_total"),
|
||||
"Time that processor spent in different modes (dpc, idle, interrupt, privileged, user)",
|
||||
[]string{"core", "mode"},
|
||||
nil,
|
||||
),
|
||||
InterruptsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "interrupts_total"),
|
||||
"Total number of received and serviced hardware interrupts",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
DPCsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "dpcs_total"),
|
||||
"Total number of received and serviced deferred procedure calls (DPCs)",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
if winversion.WindowsVersionFloat < 6.05 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &cpuCollectorFull{
|
||||
logger: logger,
|
||||
CStateSecondsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cstate_seconds_total"),
|
||||
"Time spent in low-power idle state",
|
||||
[]string{"core", "state"},
|
||||
nil,
|
||||
),
|
||||
TimeTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "time_total"),
|
||||
"Time that processor spent in different modes (dpc, idle, interrupt, privileged, user)",
|
||||
[]string{"core", "mode"},
|
||||
nil,
|
||||
),
|
||||
InterruptsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "interrupts_total"),
|
||||
"Total number of received and serviced hardware interrupts",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
DPCsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "dpcs_total"),
|
||||
"Total number of received and serviced deferred procedure calls (DPCs)",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
ClockInterruptsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "clock_interrupts_total"),
|
||||
"Total number of received and serviced clock tick interrupts",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
IdleBreakEventsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "idle_break_events_total"),
|
||||
"Total number of time processor was woken from idle",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
ParkingStatus: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "parking_status"),
|
||||
"Parking Status represents whether a processor is parked or not",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
ProcessorFrequencyMHz: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "core_frequency_mhz"),
|
||||
"Core frequency in megahertz",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
ProcessorPerformance: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "processor_performance_total"),
|
||||
"Processor Performance is the average performance of the processor while it is executing instructions, as a percentage of the nominal performance of the processor. On some processors, Processor Performance may exceed 100%",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
ProcessorMPerf: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "processor_mperf_total"),
|
||||
"Processor MPerf is the number of TSC ticks incremented while executing instructions",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
ProcessorRTC: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "processor_rtc_total"),
|
||||
"Processor RTC represents the number of RTC ticks made since the system booted. It should consistently be 64e6, and can be used to properly derive Processor Utility Rate",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
ProcessorUtility: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "processor_utility_total"),
|
||||
"Processor Utility represents is the amount of time the core spends executing instructions",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
ProcessorPrivUtility: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "processor_privileged_utility_total"),
|
||||
"Processor Privilieged Utility represents is the amount of time the core has spent executing instructions inside the kernel",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
c.CStateSecondsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cstate_seconds_total"),
|
||||
"Time spent in low-power idle state",
|
||||
[]string{"core", "state"},
|
||||
nil,
|
||||
)
|
||||
c.TimeTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "time_total"),
|
||||
"Time that processor spent in different modes (dpc, idle, interrupt, privileged, user)",
|
||||
[]string{"core", "mode"},
|
||||
nil,
|
||||
)
|
||||
c.InterruptsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "interrupts_total"),
|
||||
"Total number of received and serviced hardware interrupts",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.DPCsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dpcs_total"),
|
||||
"Total number of received and serviced deferred procedure calls (DPCs)",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.ClockInterruptsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "clock_interrupts_total"),
|
||||
"Total number of received and serviced clock tick interrupts",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.IdleBreakEventsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "idle_break_events_total"),
|
||||
"Total number of time processor was woken from idle",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.ParkingStatus = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "parking_status"),
|
||||
"Parking Status represents whether a processor is parked or not",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.ProcessorFrequencyMHz = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "core_frequency_mhz"),
|
||||
"Core frequency in megahertz",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.ProcessorPerformance = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "processor_performance_total"),
|
||||
"Processor Performance is the average performance of the processor while it is executing instructions, as a percentage of the nominal performance of the processor. On some processors, Processor Performance may exceed 100%",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.ProcessorMPerf = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "processor_mperf_total"),
|
||||
"Processor MPerf is the number of TSC ticks incremented while executing instructions",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.ProcessorRTC = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "processor_rtc_total"),
|
||||
"Processor RTC represents the number of RTC ticks made since the system booted. It should consistently be 64e6, and can be used to properly derive Processor Utility Rate",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.ProcessorUtility = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "processor_utility_total"),
|
||||
"Processor Utility represents is the amount of time the core spends executing instructions",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
c.ProcessorPrivUtility = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "processor_privileged_utility_total"),
|
||||
"Processor Privilieged Utility represents is the amount of time the core has spent executing instructions inside the kernel",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if winversion.WindowsVersionFloat > 6.05 {
|
||||
return c.CollectFull(ctx, ch)
|
||||
}
|
||||
|
||||
return c.CollectBasic(ctx, ch)
|
||||
}
|
||||
|
||||
type perflibProcessor struct {
|
||||
@@ -181,9 +209,9 @@ type perflibProcessor struct {
|
||||
PercentUserTime float64 `perflib:"% User Time"`
|
||||
}
|
||||
|
||||
func (c *cpuCollectorBasic) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) CollectBasic(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
data := make([]perflibProcessor, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Processor"], &data, c.logger)
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Processor"], &data, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -290,9 +318,9 @@ type perflibProcessorInformation struct {
|
||||
UserTimeSeconds float64 `perflib:"% User Time"`
|
||||
}
|
||||
|
||||
func (c *cpuCollectorFull) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) CollectFull(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
data := make([]perflibProcessorInformation, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Processor Information"], &data, c.logger)
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Processor Information"], &data, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
12
pkg/collector/cpu/cpu_test.go
Normal file
12
pkg/collector/cpu/cpu_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package cpu_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/cpu"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, cpu.Name, cpu.NewWithFlags)
|
||||
}
|
||||
@@ -1,50 +1,76 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package cpu_info
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// If you are adding additional labels to the metric, make sure that they get added in here as well. See below for explanation.
|
||||
const (
|
||||
Name = "cpu_info"
|
||||
// If you are adding additional labels to the metric, make sure that they get added in here as well. See below for explanation.
|
||||
win32ProcessorQuery = "SELECT Architecture, DeviceId, Description, Family, L2CacheSize, L3CacheSize, Name FROM Win32_Processor"
|
||||
)
|
||||
|
||||
// A CpuInfoCollector is a Prometheus collector for a few WMI metrics in Win32_Processor
|
||||
type CpuInfoCollector struct {
|
||||
logger log.Logger
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A collector is a Prometheus collector for a few WMI metrics in Win32_Processor
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
CpuInfo *prometheus.Desc
|
||||
}
|
||||
|
||||
func newCpuInfoCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "cpu_info"
|
||||
func New(logger log.Logger, _ *Config) types.Collector {
|
||||
c := &collector{}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
return &CpuInfoCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
func NewWithFlags(_ *kingpin.Application) types.Collector {
|
||||
return &collector{}
|
||||
}
|
||||
|
||||
CpuInfo: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, "", subsystem),
|
||||
"Labeled CPU information as provided provided by Win32_Processor",
|
||||
[]string{
|
||||
"architecture",
|
||||
"device_id",
|
||||
"description",
|
||||
"family",
|
||||
"l2_cache_size",
|
||||
"l3_cache_size",
|
||||
"name"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
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.CpuInfo = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, "", Name),
|
||||
"Labeled CPU information as provided provided by Win32_Processor",
|
||||
[]string{
|
||||
"architecture",
|
||||
"device_id",
|
||||
"description",
|
||||
"family",
|
||||
"l2_cache_size",
|
||||
"l3_cache_size",
|
||||
"name",
|
||||
},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type win32_Processor struct {
|
||||
@@ -59,7 +85,7 @@ type win32_Processor struct {
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *CpuInfoCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting cpu_info metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
@@ -67,10 +93,10 @@ func (c *CpuInfoCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CpuInfoCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []win32_Processor
|
||||
// We use a static query here because the provided methods in wmi.go all issue a SELECT *;
|
||||
// This results in the time consuming LoadPercentage field being read which seems to measure each CPU
|
||||
// This results in the time-consuming LoadPercentage field being read which seems to measure each CPU
|
||||
// serially over a 1 second interval, so the scrape time is at least 1s * num_sockets
|
||||
if err := wmi.Query(win32ProcessorQuery, &dst); err != nil {
|
||||
return nil, err
|
||||
132
pkg/collector/cs/cs.go
Normal file
132
pkg/collector/cs/cs.go
Normal file
@@ -0,0 +1,132 @@
|
||||
//go:build windows
|
||||
|
||||
package cs
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/headers/sysinfoapi"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "cs"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A collector is a Prometheus collector for WMI metrics
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
PhysicalMemoryBytes *prometheus.Desc
|
||||
LogicalProcessors *prometheus.Desc
|
||||
Hostname *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.LogicalProcessors = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "logical_processors"),
|
||||
"ComputerSystem.NumberOfLogicalProcessors",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.PhysicalMemoryBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "physical_memory_bytes"),
|
||||
"ComputerSystem.TotalPhysicalMemory",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.Hostname = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "hostname"),
|
||||
"Labeled system hostname information as provided by ComputerSystem.DNSHostName and ComputerSystem.Domain",
|
||||
[]string{
|
||||
"hostname",
|
||||
"domain",
|
||||
"fqdn",
|
||||
},
|
||||
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 desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting cs metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
// Get systeminfo for number of processors
|
||||
systemInfo := sysinfoapi.GetSystemInfo()
|
||||
|
||||
// Get memory status for physical memory
|
||||
mem, err := sysinfoapi.GlobalMemoryStatusEx()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.LogicalProcessors,
|
||||
prometheus.GaugeValue,
|
||||
float64(systemInfo.NumberOfProcessors),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PhysicalMemoryBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(mem.TotalPhys),
|
||||
)
|
||||
|
||||
hostname, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSHostname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domain, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSDomain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fqdn, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSFullyQualified)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Hostname,
|
||||
prometheus.GaugeValue,
|
||||
1.0,
|
||||
hostname,
|
||||
domain,
|
||||
fqdn,
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
12
pkg/collector/cs/cs_test.go
Normal file
12
pkg/collector/cs/cs_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package cs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/cs"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, cs.Name, cs.NewWithFlags)
|
||||
}
|
||||
@@ -1,25 +1,36 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package dfsr
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
Name = "dfsr"
|
||||
FlagDfsrEnabledCollectors = "collectors.dfsr.sources-enabled"
|
||||
)
|
||||
|
||||
var dfsrEnabledCollectors *string
|
||||
type Config struct {
|
||||
DfsrEnabledCollectors string `yaml:"enabled_collectors"`
|
||||
}
|
||||
|
||||
// DFSRCollector contains the metric and state data of the DFSR collectors.
|
||||
type DFSRCollector struct {
|
||||
var ConfigDefaults = Config{
|
||||
DfsrEnabledCollectors: "",
|
||||
}
|
||||
|
||||
// collector contains the metric and state data of the DFSR collectors.
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
dfsrEnabledCollectors *string
|
||||
|
||||
// Connection source
|
||||
ConnectionBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc
|
||||
ConnectionBytesReceivedTotal *prometheus.Desc
|
||||
@@ -71,10 +82,10 @@ type DFSRCollector struct {
|
||||
dfsrChildCollectors []dfsrCollectorFunc
|
||||
}
|
||||
|
||||
type dfsrCollectorFunc func(ctx *ScrapeContext, ch chan<- prometheus.Metric) error
|
||||
type dfsrCollectorFunc func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error
|
||||
|
||||
// Map Perflib sources to DFSR collector names
|
||||
// E.G. volume -> DFS Replication Service Volumes
|
||||
// e.g, volume -> DFS Replication Service Volumes
|
||||
func dfsrGetPerfObjectName(collector string) string {
|
||||
prefix := "DFS "
|
||||
suffix := ""
|
||||
@@ -86,329 +97,348 @@ func dfsrGetPerfObjectName(collector string) string {
|
||||
case "volume":
|
||||
suffix = "Replication Service Volumes"
|
||||
}
|
||||
return (prefix + suffix)
|
||||
return prefix + suffix
|
||||
}
|
||||
|
||||
// newDFSRCollectorFlags is registered
|
||||
func newDFSRCollectorFlags(app *kingpin.Application) {
|
||||
dfsrEnabledCollectors = app.Flag(FlagDfsrEnabledCollectors, "Comma-seperated list of DFSR Perflib sources to use.").Default("connection,folder,volume").String()
|
||||
func New(logger log.Logger, config *Config) types.Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
c := &collector{
|
||||
dfsrEnabledCollectors: &config.DfsrEnabledCollectors,
|
||||
}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
// newDFSRCollector is registered
|
||||
func newDFSRCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "dfsr"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
_ = level.Info(logger).Log("msg", "dfsr collector is in an experimental state! Metrics for this collector have not been tested.")
|
||||
|
||||
enabled := expandEnabledChildCollectors(*dfsrEnabledCollectors)
|
||||
perfCounters := make([]string, 0, len(enabled))
|
||||
for _, c := range enabled {
|
||||
perfCounters = append(perfCounters, dfsrGetPerfObjectName(c))
|
||||
func NewWithFlags(app *kingpin.Application) types.Collector {
|
||||
return &collector{
|
||||
dfsrEnabledCollectors: app.
|
||||
Flag(FlagDfsrEnabledCollectors, "Comma-seperated list of DFSR Perflib sources to use.").Default("connection,folder,volume").
|
||||
Default(ConfigDefaults.DfsrEnabledCollectors).String(),
|
||||
}
|
||||
addPerfCounterDependencies(subsystem, perfCounters)
|
||||
}
|
||||
|
||||
dfsrCollector := DFSRCollector{
|
||||
logger: logger,
|
||||
func (c *collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
// Connection
|
||||
ConnectionBandwidthSavingsUsingDFSReplicationTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_bandwidth_savings_using_dfs_replication_bytes_total"),
|
||||
"Total bytes of bandwidth saved using DFS Replication for this connection",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
func (c *collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
|
||||
ConnectionBytesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_bytes_received_total"),
|
||||
"Total bytes received for connection",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ConnectionCompressedSizeOfFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_compressed_size_of_files_received_bytes_total"),
|
||||
"Total compressed size of files received on the connection, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ConnectionFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_received_files_total"),
|
||||
"Total number of files received for connection",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ConnectionRDCBytesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_rdc_received_bytes_total"),
|
||||
"Total bytes received on the connection while replicating files using Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ConnectionRDCCompressedSizeOfFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_rdc_compressed_size_of_received_files_bytes_total"),
|
||||
"Total uncompressed size of files received with Remote Differential Compression for connection",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ConnectionRDCNumberofFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_rdc_received_files_total"),
|
||||
"Total number of files received using remote differential compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ConnectionRDCSizeOfFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_rdc_size_of_received_files_bytes_total"),
|
||||
"Total size of received Remote Differential Compression files, in bytes.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ConnectionSizeOfFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_files_received_bytes_total"),
|
||||
"Total size of files received, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
// Folder
|
||||
FolderBandwidthSavingsUsingDFSReplicationTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_bandwidth_savings_using_dfs_replication_bytes_total"),
|
||||
"Total bytes of bandwidth saved using DFS Replication for this folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderCompressedSizeOfFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_compressed_size_of_received_files_bytes_total"),
|
||||
"Total compressed size of files received on the folder, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderConflictBytesCleanedupTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_conflict_cleaned_up_bytes_total"),
|
||||
"Total size of conflict loser files and folders deleted from the Conflict and Deleted folder, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderConflictBytesGeneratedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_conflict_generated_bytes_total"),
|
||||
"Total size of conflict loser files and folders moved to the Conflict and Deleted folder, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderConflictFilesCleanedUpTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_conflict_cleaned_up_files_total"),
|
||||
"Number of conflict loser files deleted from the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderConflictFilesGeneratedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_conflict_generated_files_total"),
|
||||
"Number of files and folders moved to the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderConflictFolderCleanupsCompletedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_conflict_folder_cleanups_total"),
|
||||
"Number of deletions of conflict loser files and folders in the Conflict and Deleted",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderConflictSpaceInUse: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_conflict_space_in_use_bytes"),
|
||||
"Total size of the conflict loser files and folders currently in the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderDeletedSpaceInUse: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_deleted_space_in_use_bytes"),
|
||||
"Total size (in bytes) of the deleted files and folders currently in the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderDeletedBytesCleanedUpTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_deleted_cleaned_up_bytes_total"),
|
||||
"Total size (in bytes) of replicating deleted files and folders that were cleaned up from the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderDeletedBytesGeneratedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_deleted_generated_bytes_total"),
|
||||
"Total size (in bytes) of replicated deleted files and folders that were moved to the Conflict and Deleted folder after they were deleted from a replicated folder on a sending member",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderDeletedFilesCleanedUpTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_deleted_cleaned_up_files_total"),
|
||||
"Number of files and folders that were cleaned up from the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderDeletedFilesGeneratedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_deleted_generated_files_total"),
|
||||
"Number of deleted files and folders that were moved to the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderFileInstallsRetriedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_file_installs_retried_total"),
|
||||
"Total number of file installs that are being retried due to sharing violations or other errors encountered when installing the files",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderFileInstallsSucceededTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_file_installs_succeeded_total"),
|
||||
"Total number of files that were successfully received from sending members and installed locally on this server",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_received_files_total"),
|
||||
"Total number of files received",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderRDCBytesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_rdc_received_bytes_total"),
|
||||
"Total number of bytes received in replicating files using Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderRDCCompressedSizeOfFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_rdc_compressed_size_of_received_files_bytes_total"),
|
||||
"Total compressed size (in bytes) of the files received with Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderRDCNumberofFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_rdc_received_files_total"),
|
||||
"Total number of files received with Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderRDCSizeOfFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_rdc_files_received_bytes_total"),
|
||||
"Total uncompressed size (in bytes) of the files received with Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderSizeOfFilesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_files_received_bytes_total"),
|
||||
"Total uncompressed size (in bytes) of the files received",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderStagingSpaceInUse: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_staging_space_in_use_bytes"),
|
||||
"Total size of files and folders currently in the staging folder.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderStagingBytesCleanedUpTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_staging_cleaned_up_bytes_total"),
|
||||
"Total size (in bytes) of the files and folders that have been cleaned up from the staging folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderStagingBytesGeneratedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_staging_generated_bytes_total"),
|
||||
"Total size (in bytes) of replicated files and folders in the staging folder created by the DFS Replication service since last restart",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderStagingFilesCleanedUpTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_staging_cleaned_up_files_total"),
|
||||
"Total number of files and folders that have been cleaned up from the staging folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderStagingFilesGeneratedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_staging_generated_files_total"),
|
||||
"Total number of times replicated files and folders have been staged by the DFS Replication service",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
FolderUpdatesDroppedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "folder_dropped_updates_total"),
|
||||
"Total number of redundant file replication update records that have been ignored by the DFS Replication service because they did not change the replicated file or folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
// Volume
|
||||
VolumeDatabaseCommitsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "volume_database_commits_total"),
|
||||
"Total number of DFSR Volume database commits",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
VolumeDatabaseLookupsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "volume_database_lookups_total"),
|
||||
"Total number of DFSR Volume database lookups",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
VolumeUSNJournalUnreadPercentage: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "volume_usn_journal_unread_percentage"),
|
||||
"Percentage of DFSR Volume USN journal records that are unread",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
VolumeUSNJournalRecordsAcceptedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "volume_usn_journal_accepted_records_total"),
|
||||
"Total number of USN journal records accepted",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
VolumeUSNJournalRecordsReadTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "volume_usn_journal_read_records_total"),
|
||||
"Total number of DFSR Volume USN journal records read",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
func (c *collector) GetPerfCounter() ([]string, error) {
|
||||
// Perflib sources are dynamic, depending on the enabled child collectors
|
||||
var perflibDependencies []string
|
||||
for _, source := range utils.ExpandEnabledChildCollectors(*c.dfsrEnabledCollectors) {
|
||||
perflibDependencies = append(perflibDependencies, dfsrGetPerfObjectName(source))
|
||||
}
|
||||
|
||||
dfsrCollector.dfsrChildCollectors = dfsrCollector.getDFSRChildCollectors(enabled)
|
||||
return perflibDependencies, nil
|
||||
}
|
||||
|
||||
return &dfsrCollector, nil
|
||||
func (c *collector) Build() error {
|
||||
_ = level.Info(c.logger).Log("msg", "dfsr collector is in an experimental state! Metrics for this collector have not been tested.")
|
||||
|
||||
// Connection
|
||||
c.ConnectionBandwidthSavingsUsingDFSReplicationTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_bandwidth_savings_using_dfs_replication_bytes_total"),
|
||||
"Total bytes of bandwidth saved using DFS Replication for this connection",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.ConnectionBytesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_bytes_received_total"),
|
||||
"Total bytes received for connection",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.ConnectionCompressedSizeOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_compressed_size_of_files_received_bytes_total"),
|
||||
"Total compressed size of files received on the connection, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.ConnectionFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_received_files_total"),
|
||||
"Total number of files received for connection",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.ConnectionRDCBytesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_received_bytes_total"),
|
||||
"Total bytes received on the connection while replicating files using Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.ConnectionRDCCompressedSizeOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_compressed_size_of_received_files_bytes_total"),
|
||||
"Total uncompressed size of files received with Remote Differential Compression for connection",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.ConnectionRDCNumberofFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_received_files_total"),
|
||||
"Total number of files received using remote differential compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.ConnectionRDCSizeOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_size_of_received_files_bytes_total"),
|
||||
"Total size of received Remote Differential Compression files, in bytes.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.ConnectionSizeOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_files_received_bytes_total"),
|
||||
"Total size of files received, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c. // Folder
|
||||
FolderBandwidthSavingsUsingDFSReplicationTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_bandwidth_savings_using_dfs_replication_bytes_total"),
|
||||
"Total bytes of bandwidth saved using DFS Replication for this folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderCompressedSizeOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_compressed_size_of_received_files_bytes_total"),
|
||||
"Total compressed size of files received on the folder, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderConflictBytesCleanedupTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_cleaned_up_bytes_total"),
|
||||
"Total size of conflict loser files and folders deleted from the Conflict and Deleted folder, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderConflictBytesGeneratedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_generated_bytes_total"),
|
||||
"Total size of conflict loser files and folders moved to the Conflict and Deleted folder, in bytes",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderConflictFilesCleanedUpTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_cleaned_up_files_total"),
|
||||
"Number of conflict loser files deleted from the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderConflictFilesGeneratedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_generated_files_total"),
|
||||
"Number of files and folders moved to the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderConflictFolderCleanupsCompletedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_folder_cleanups_total"),
|
||||
"Number of deletions of conflict loser files and folders in the Conflict and Deleted",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderConflictSpaceInUse = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_space_in_use_bytes"),
|
||||
"Total size of the conflict loser files and folders currently in the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderDeletedSpaceInUse = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_space_in_use_bytes"),
|
||||
"Total size (in bytes) of the deleted files and folders currently in the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderDeletedBytesCleanedUpTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_cleaned_up_bytes_total"),
|
||||
"Total size (in bytes) of replicating deleted files and folders that were cleaned up from the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderDeletedBytesGeneratedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_generated_bytes_total"),
|
||||
"Total size (in bytes) of replicated deleted files and folders that were moved to the Conflict and Deleted folder after they were deleted from a replicated folder on a sending member",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderDeletedFilesCleanedUpTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_cleaned_up_files_total"),
|
||||
"Number of files and folders that were cleaned up from the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderDeletedFilesGeneratedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_generated_files_total"),
|
||||
"Number of deleted files and folders that were moved to the Conflict and Deleted folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderFileInstallsRetriedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_file_installs_retried_total"),
|
||||
"Total number of file installs that are being retried due to sharing violations or other errors encountered when installing the files",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderFileInstallsSucceededTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_file_installs_succeeded_total"),
|
||||
"Total number of files that were successfully received from sending members and installed locally on this server",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_received_files_total"),
|
||||
"Total number of files received",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderRDCBytesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_received_bytes_total"),
|
||||
"Total number of bytes received in replicating files using Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderRDCCompressedSizeOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_compressed_size_of_received_files_bytes_total"),
|
||||
"Total compressed size (in bytes) of the files received with Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderRDCNumberofFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_received_files_total"),
|
||||
"Total number of files received with Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderRDCSizeOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_files_received_bytes_total"),
|
||||
"Total uncompressed size (in bytes) of the files received with Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderSizeOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_files_received_bytes_total"),
|
||||
"Total uncompressed size (in bytes) of the files received",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderStagingSpaceInUse = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_space_in_use_bytes"),
|
||||
"Total size of files and folders currently in the staging folder.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderStagingBytesCleanedUpTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_cleaned_up_bytes_total"),
|
||||
"Total size (in bytes) of the files and folders that have been cleaned up from the staging folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderStagingBytesGeneratedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_generated_bytes_total"),
|
||||
"Total size (in bytes) of replicated files and folders in the staging folder created by the DFS Replication service since last restart",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderStagingFilesCleanedUpTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_cleaned_up_files_total"),
|
||||
"Total number of files and folders that have been cleaned up from the staging folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderStagingFilesGeneratedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_generated_files_total"),
|
||||
"Total number of times replicated files and folders have been staged by the DFS Replication service",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.FolderUpdatesDroppedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_dropped_updates_total"),
|
||||
"Total number of redundant file replication update records that have been ignored by the DFS Replication service because they did not change the replicated file or folder",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c. // Volume
|
||||
VolumeDatabaseCommitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "volume_database_commits_total"),
|
||||
"Total number of DFSR Volume database commits",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.VolumeDatabaseLookupsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "volume_database_lookups_total"),
|
||||
"Total number of DFSR Volume database lookups",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.VolumeUSNJournalUnreadPercentage = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "volume_usn_journal_unread_percentage"),
|
||||
"Percentage of DFSR Volume USN journal records that are unread",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.VolumeUSNJournalRecordsAcceptedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "volume_usn_journal_accepted_records_total"),
|
||||
"Total number of USN journal records accepted",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.VolumeUSNJournalRecordsReadTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "volume_usn_journal_read_records_total"),
|
||||
"Total number of DFSR Volume USN journal records read",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.dfsrChildCollectors = c.getDFSRChildCollectors(utils.ExpandEnabledChildCollectors(*c.dfsrEnabledCollectors))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Maps enabled child collectors names to their relevant collection function,
|
||||
// for use in DFSRCollector.Collect()
|
||||
func (c *DFSRCollector) getDFSRChildCollectors(enabledCollectors []string) []dfsrCollectorFunc {
|
||||
// for use in collector.Collect()
|
||||
func (c *collector) getDFSRChildCollectors(enabledCollectors []string) []dfsrCollectorFunc {
|
||||
var dfsrCollectors []dfsrCollectorFunc
|
||||
for _, collector := range enabledCollectors {
|
||||
switch collector {
|
||||
@@ -426,7 +456,7 @@ func (c *DFSRCollector) getDFSRChildCollectors(enabledCollectors []string) []dfs
|
||||
|
||||
// Collect implements the Collector interface.
|
||||
// Sends metric values for each metric to the provided prometheus Metric channel.
|
||||
func (c *DFSRCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
for _, fn := range c.dfsrChildCollectors {
|
||||
err := fn(ctx, ch)
|
||||
if err != nil {
|
||||
@@ -436,7 +466,7 @@ func (c *DFSRCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Perflib: "DFS Replication Service Connections"
|
||||
// PerflibDFSRConnection Perflib: "DFS Replication Service Connections"
|
||||
type PerflibDFSRConnection struct {
|
||||
Name string
|
||||
|
||||
@@ -451,9 +481,9 @@ type PerflibDFSRConnection struct {
|
||||
SizeOfFilesReceivedTotal float64 `perflib:"Size of Files Received"`
|
||||
}
|
||||
|
||||
func (c *DFSRCollector) collectConnection(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectConnection(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []PerflibDFSRConnection
|
||||
if err := unmarshalObject(ctx.perfObjects["DFS Replication Connections"], &dst, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Connections"], &dst, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -525,7 +555,7 @@ func (c *DFSRCollector) collectConnection(ctx *ScrapeContext, ch chan<- promethe
|
||||
return nil
|
||||
}
|
||||
|
||||
// Perflib: "DFS Replicated Folder"
|
||||
// PerflibDFSRFolder Perflib: "DFS Replicated Folder"
|
||||
type PerflibDFSRFolder struct {
|
||||
Name string
|
||||
|
||||
@@ -558,9 +588,9 @@ type PerflibDFSRFolder struct {
|
||||
UpdatesDroppedTotal float64 `perflib:"Updates Dropped"`
|
||||
}
|
||||
|
||||
func (c *DFSRCollector) collectFolder(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectFolder(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []PerflibDFSRFolder
|
||||
if err := unmarshalObject(ctx.perfObjects["DFS Replicated Folders"], &dst, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replicated Folders"], &dst, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -757,7 +787,7 @@ func (c *DFSRCollector) collectFolder(ctx *ScrapeContext, ch chan<- prometheus.M
|
||||
return nil
|
||||
}
|
||||
|
||||
// Perflib: "DFS Replication Service Volumes"
|
||||
// PerflibDFSRVolume Perflib: "DFS Replication Service Volumes"
|
||||
type PerflibDFSRVolume struct {
|
||||
Name string
|
||||
|
||||
@@ -768,9 +798,9 @@ type PerflibDFSRVolume struct {
|
||||
USNJournalUnreadPercentage float64 `perflib:"USN Journal Records Unread Percentage"`
|
||||
}
|
||||
|
||||
func (c *DFSRCollector) collectVolume(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectVolume(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []PerflibDFSRVolume
|
||||
if err := unmarshalObject(ctx.perfObjects["DFS Replication Service Volumes"], &dst, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Service Volumes"], &dst, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
12
pkg/collector/dfsr/dfsr_test.go
Normal file
12
pkg/collector/dfsr/dfsr_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package dfsr_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/dfsr"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, dfsr.Name, dfsr.NewWithFlags)
|
||||
}
|
||||
@@ -1,15 +1,23 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package dhcp
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// A DhcpCollector is a Prometheus collector perflib DHCP metrics
|
||||
type DhcpCollector struct {
|
||||
const Name = "dhcp"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A collector is a Prometheus collector perflib DHCP metrics
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
PacketsReceivedTotal *prometheus.Desc
|
||||
@@ -39,163 +47,180 @@ type DhcpCollector struct {
|
||||
FailoverBndupdDropped *prometheus.Desc
|
||||
}
|
||||
|
||||
func newDhcpCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "dhcp"
|
||||
func New(logger log.Logger, _ *Config) types.Collector {
|
||||
c := &collector{}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
return &DhcpCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
func NewWithFlags(_ *kingpin.Application) types.Collector {
|
||||
return &collector{}
|
||||
}
|
||||
|
||||
PacketsReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "packets_received_total"),
|
||||
"Total number of packets received by the DHCP server (PacketsReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DuplicatesDroppedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "duplicates_dropped_total"),
|
||||
"Total number of duplicate packets received by the DHCP server (DuplicatesDroppedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PacketsExpiredTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "packets_expired_total"),
|
||||
"Total number of packets expired in the DHCP server message queue (PacketsExpiredTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ActiveQueueLength: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "active_queue_length"),
|
||||
"Number of packets in the processing queue of the DHCP server (ActiveQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ConflictCheckQueueLength: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "conflict_check_queue_length"),
|
||||
"Number of packets in the DHCP server queue waiting on conflict detection (ping). (ConflictCheckQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DiscoversTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "discovers_total"),
|
||||
"Total DHCP Discovers received by the DHCP server (DiscoversTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
OffersTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "offers_total"),
|
||||
"Total DHCP Offers sent by the DHCP server (OffersTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
RequestsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "requests_total"),
|
||||
"Total DHCP Requests received by the DHCP server (RequestsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
InformsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "informs_total"),
|
||||
"Total DHCP Informs received by the DHCP server (InformsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AcksTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "acks_total"),
|
||||
"Total DHCP Acks sent by the DHCP server (AcksTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
NacksTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "nacks_total"),
|
||||
"Total DHCP Nacks sent by the DHCP server (NacksTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DeclinesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "declines_total"),
|
||||
"Total DHCP Declines received by the DHCP server (DeclinesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ReleasesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "releases_total"),
|
||||
"Total DHCP Releases received by the DHCP server (ReleasesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
OfferQueueLength: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "offer_queue_length"),
|
||||
"Number of packets in the offer queue of the DHCP server (OfferQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DeniedDueToMatch: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "denied_due_to_match_total"),
|
||||
"Total number of DHCP requests denied, based on matches from the Deny list (DeniedDueToMatch)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DeniedDueToNonMatch: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "denied_due_to_nonmatch_total"),
|
||||
"Total number of DHCP requests denied, based on non-matches from the Allow list (DeniedDueToNonMatch)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FailoverBndupdSentTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_bndupd_sent_total"),
|
||||
"Number of DHCP failover Binding Update messages sent (FailoverBndupdSentTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FailoverBndupdReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_bndupd_received_total"),
|
||||
"Number of DHCP failover Binding Update messages received (FailoverBndupdReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FailoverBndackSentTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_bndack_sent_total"),
|
||||
"Number of DHCP failover Binding Ack messages sent (FailoverBndackSentTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FailoverBndackReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_bndack_received_total"),
|
||||
"Number of DHCP failover Binding Ack messages received (FailoverBndackReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FailoverBndupdPendingOutboundQueue: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_bndupd_pending_in_outbound_queue"),
|
||||
"Number of pending outbound DHCP failover Binding Update messages (FailoverBndupdPendingOutboundQueue)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FailoverTransitionsCommunicationinterruptedState: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_transitions_communicationinterrupted_state_total"),
|
||||
"Total number of transitions into COMMUNICATION INTERRUPTED state (FailoverTransitionsCommunicationinterruptedState)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FailoverTransitionsPartnerdownState: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_transitions_partnerdown_state_total"),
|
||||
"Total number of transitions into PARTNER DOWN state (FailoverTransitionsPartnerdownState)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FailoverTransitionsRecoverState: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_transitions_recover_total"),
|
||||
"Total number of transitions into RECOVER state (FailoverTransitionsRecoverState)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
FailoverBndupdDropped: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "failover_bndupd_dropped_total"),
|
||||
"Total number of DHCP faileover Binding Updates dropped (FailoverBndupdDropped)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
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.PacketsReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "packets_received_total"),
|
||||
"Total number of packets received by the DHCP server (PacketsReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DuplicatesDroppedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "duplicates_dropped_total"),
|
||||
"Total number of duplicate packets received by the DHCP server (DuplicatesDroppedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.PacketsExpiredTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "packets_expired_total"),
|
||||
"Total number of packets expired in the DHCP server message queue (PacketsExpiredTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ActiveQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "active_queue_length"),
|
||||
"Number of packets in the processing queue of the DHCP server (ActiveQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ConflictCheckQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "conflict_check_queue_length"),
|
||||
"Number of packets in the DHCP server queue waiting on conflict detection (ping). (ConflictCheckQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DiscoversTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "discovers_total"),
|
||||
"Total DHCP Discovers received by the DHCP server (DiscoversTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.OffersTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "offers_total"),
|
||||
"Total DHCP Offers sent by the DHCP server (OffersTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.RequestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "requests_total"),
|
||||
"Total DHCP Requests received by the DHCP server (RequestsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.InformsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "informs_total"),
|
||||
"Total DHCP Informs received by the DHCP server (InformsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.AcksTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "acks_total"),
|
||||
"Total DHCP Acks sent by the DHCP server (AcksTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.NacksTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "nacks_total"),
|
||||
"Total DHCP Nacks sent by the DHCP server (NacksTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DeclinesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "declines_total"),
|
||||
"Total DHCP Declines received by the DHCP server (DeclinesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.ReleasesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "releases_total"),
|
||||
"Total DHCP Releases received by the DHCP server (ReleasesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.OfferQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "offer_queue_length"),
|
||||
"Number of packets in the offer queue of the DHCP server (OfferQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DeniedDueToMatch = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "denied_due_to_match_total"),
|
||||
"Total number of DHCP requests denied, based on matches from the Deny list (DeniedDueToMatch)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DeniedDueToNonMatch = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "denied_due_to_nonmatch_total"),
|
||||
"Total number of DHCP requests denied, based on non-matches from the Allow list (DeniedDueToNonMatch)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FailoverBndupdSentTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_sent_total"),
|
||||
"Number of DHCP fail over Binding Update messages sent (FailoverBndupdSentTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FailoverBndupdReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_received_total"),
|
||||
"Number of DHCP fail over Binding Update messages received (FailoverBndupdReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FailoverBndackSentTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndack_sent_total"),
|
||||
"Number of DHCP fail over Binding Ack messages sent (FailoverBndackSentTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FailoverBndackReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndack_received_total"),
|
||||
"Number of DHCP fail over Binding Ack messages received (FailoverBndackReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FailoverBndupdPendingOutboundQueue = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_pending_in_outbound_queue"),
|
||||
"Number of pending outbound DHCP fail over Binding Update messages (FailoverBndupdPendingOutboundQueue)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FailoverTransitionsCommunicationinterruptedState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_transitions_communicationinterrupted_state_total"),
|
||||
"Total number of transitions into COMMUNICATION INTERRUPTED state (FailoverTransitionsCommunicationinterruptedState)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FailoverTransitionsPartnerdownState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_transitions_partnerdown_state_total"),
|
||||
"Total number of transitions into PARTNER DOWN state (FailoverTransitionsPartnerdownState)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FailoverTransitionsRecoverState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_transitions_recover_total"),
|
||||
"Total number of transitions into RECOVER state (FailoverTransitionsRecoverState)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.FailoverBndupdDropped = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_dropped_total"),
|
||||
"Total number of DHCP fail over Binding Updates dropped (FailoverBndupdDropped)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// represents perflib metrics from the DHCP Server class.
|
||||
@@ -229,160 +254,160 @@ type dhcpPerf struct {
|
||||
FailoverBndupdDropped float64 `perflib:"Failover: BndUpd Dropped."`
|
||||
}
|
||||
|
||||
func (c *DhcpCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var perflib []dhcpPerf
|
||||
if err := unmarshalObject(ctx.perfObjects["DHCP Server"], &perflib, c.logger); err != nil {
|
||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dhcpPerfs []dhcpPerf
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DHCP Server"], &dhcpPerfs, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].PacketsReceivedTotal,
|
||||
dhcpPerfs[0].PacketsReceivedTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DuplicatesDroppedTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].DuplicatesDroppedTotal,
|
||||
dhcpPerfs[0].DuplicatesDroppedTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsExpiredTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].PacketsExpiredTotal,
|
||||
dhcpPerfs[0].PacketsExpiredTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ActiveQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
perflib[0].ActiveQueueLength,
|
||||
dhcpPerfs[0].ActiveQueueLength,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ConflictCheckQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
perflib[0].ConflictCheckQueueLength,
|
||||
dhcpPerfs[0].ConflictCheckQueueLength,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DiscoversTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].DiscoversTotal,
|
||||
dhcpPerfs[0].DiscoversTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.OffersTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].OffersTotal,
|
||||
dhcpPerfs[0].OffersTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RequestsTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].RequestsTotal,
|
||||
dhcpPerfs[0].RequestsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.InformsTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].InformsTotal,
|
||||
dhcpPerfs[0].InformsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AcksTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].AcksTotal,
|
||||
dhcpPerfs[0].AcksTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.NacksTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].NacksTotal,
|
||||
dhcpPerfs[0].NacksTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DeclinesTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].DeclinesTotal,
|
||||
dhcpPerfs[0].DeclinesTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReleasesTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].ReleasesTotal,
|
||||
dhcpPerfs[0].ReleasesTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.OfferQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
perflib[0].OfferQueueLength,
|
||||
dhcpPerfs[0].OfferQueueLength,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DeniedDueToMatch,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].DeniedDueToMatch,
|
||||
dhcpPerfs[0].DeniedDueToMatch,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DeniedDueToNonMatch,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].DeniedDueToNonMatch,
|
||||
dhcpPerfs[0].DeniedDueToNonMatch,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverBndupdSentTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].FailoverBndupdSentTotal,
|
||||
dhcpPerfs[0].FailoverBndupdSentTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverBndupdReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].FailoverBndupdReceivedTotal,
|
||||
dhcpPerfs[0].FailoverBndupdReceivedTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverBndackSentTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].FailoverBndackSentTotal,
|
||||
dhcpPerfs[0].FailoverBndackSentTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverBndackReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].FailoverBndackReceivedTotal,
|
||||
dhcpPerfs[0].FailoverBndackReceivedTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverBndupdPendingOutboundQueue,
|
||||
prometheus.GaugeValue,
|
||||
perflib[0].FailoverBndupdPendingOutboundQueue,
|
||||
dhcpPerfs[0].FailoverBndupdPendingOutboundQueue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverTransitionsCommunicationinterruptedState,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].FailoverTransitionsCommunicationinterruptedState,
|
||||
dhcpPerfs[0].FailoverTransitionsCommunicationinterruptedState,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverTransitionsPartnerdownState,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].FailoverTransitionsPartnerdownState,
|
||||
dhcpPerfs[0].FailoverTransitionsPartnerdownState,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverTransitionsRecoverState,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].FailoverTransitionsRecoverState,
|
||||
dhcpPerfs[0].FailoverTransitionsRecoverState,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.FailoverBndupdDropped,
|
||||
prometheus.CounterValue,
|
||||
perflib[0].FailoverBndupdDropped,
|
||||
dhcpPerfs[0].FailoverBndupdDropped,
|
||||
)
|
||||
|
||||
return nil
|
||||
12
pkg/collector/dhcp/dhcp_test.go
Normal file
12
pkg/collector/dhcp/dhcp_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package dhcp_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/dhcp"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, dhcp.Name, dhcp.NewWithFlags)
|
||||
}
|
||||
@@ -1,24 +1,30 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package diskdrive
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const (
|
||||
Name = "diskdrive"
|
||||
win32DiskQuery = "SELECT DeviceID, Model, Caption, Name, Partitions, Size, Status, Availability FROM WIN32_DiskDrive"
|
||||
)
|
||||
|
||||
// A DiskDriveInfoCollector is a Prometheus collector for a few WMI metrics in Win32_DiskDrive
|
||||
type DiskDriveInfoCollector struct {
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A collector is a Prometheus collector for a few WMI metrics in Win32_DiskDrive
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
DiskInfo *prometheus.Desc
|
||||
@@ -28,54 +34,66 @@ type DiskDriveInfoCollector struct {
|
||||
Availability *prometheus.Desc
|
||||
}
|
||||
|
||||
func newDiskDriveInfoCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "diskdrive"
|
||||
func New(logger log.Logger, _ *Config) types.Collector {
|
||||
c := &collector{}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
return &DiskDriveInfoCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
func NewWithFlags(_ *kingpin.Application) types.Collector {
|
||||
return &collector{}
|
||||
}
|
||||
|
||||
DiskInfo: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "info"),
|
||||
"General drive information",
|
||||
[]string{
|
||||
"device_id",
|
||||
"model",
|
||||
"caption",
|
||||
"name",
|
||||
},
|
||||
nil,
|
||||
),
|
||||
func (c *collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
Status: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "status"),
|
||||
"Status of the drive",
|
||||
[]string{
|
||||
"name", "status"},
|
||||
nil,
|
||||
),
|
||||
func (c *collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
|
||||
Size: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "size"),
|
||||
"Size of the disk drive. It is calculated by multiplying the total number of cylinders, tracks in each cylinder, sectors in each track, and bytes in each sector.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
func (c *collector) GetPerfCounter() ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
Partitions: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "partitions"),
|
||||
"Number of partitions",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
func (c *collector) Build() error {
|
||||
c.DiskInfo = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||
"General drive information",
|
||||
[]string{
|
||||
"device_id",
|
||||
"model",
|
||||
"caption",
|
||||
"name",
|
||||
},
|
||||
nil,
|
||||
)
|
||||
c.Status = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "status"),
|
||||
"Status of the drive",
|
||||
[]string{"name", "status"},
|
||||
nil,
|
||||
)
|
||||
c.Size = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "size"),
|
||||
"Size of the disk drive. It is calculated by multiplying the total number of cylinders, tracks in each cylinder, sectors in each track, and bytes in each sector.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.Partitions = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "partitions"),
|
||||
"Number of partitions",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.Availability = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "availability"),
|
||||
"Availability Status",
|
||||
[]string{"name", "availability"},
|
||||
nil,
|
||||
)
|
||||
|
||||
Availability: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "availability"),
|
||||
"Availability Status",
|
||||
[]string{
|
||||
"name", "availability"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
type Win32_DiskDrive struct {
|
||||
@@ -106,7 +124,6 @@ var (
|
||||
}
|
||||
|
||||
availMap = map[int]string{
|
||||
|
||||
1: "Other",
|
||||
2: "Unknown",
|
||||
3: "Running / Full Power",
|
||||
@@ -132,7 +149,7 @@ var (
|
||||
)
|
||||
|
||||
// Collect sends the metric values for each metric to the provided prometheus Metric channel.
|
||||
func (c *DiskDriveInfoCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting disk_drive_info metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
@@ -140,7 +157,7 @@ func (c *DiskDriveInfoCollector) Collect(ctx *ScrapeContext, ch chan<- prometheu
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *DiskDriveInfoCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_DiskDrive
|
||||
|
||||
if err := wmi.Query(win32DiskQuery, &dst); err != nil {
|
||||
12
pkg/collector/diskdrive/diskdrive_test.go
Normal file
12
pkg/collector/diskdrive/diskdrive_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package diskdrive_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/diskdrive"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, diskdrive.Name, diskdrive.NewWithFlags)
|
||||
}
|
||||
@@ -1,19 +1,26 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package dns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A DNSCollector is a Prometheus collector for WMI Win32_PerfRawData_DNS_DNS metrics
|
||||
type DNSCollector struct {
|
||||
const Name = "dns"
|
||||
|
||||
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
|
||||
|
||||
ZoneTransferRequestsReceived *prometheus.Desc
|
||||
@@ -40,150 +47,167 @@ type DNSCollector struct {
|
||||
UnmatchedResponsesReceived *prometheus.Desc
|
||||
}
|
||||
|
||||
// newDNSCollector ...
|
||||
func newDNSCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "dns"
|
||||
return &DNSCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
func New(logger log.Logger, _ *Config) types.Collector {
|
||||
c := &collector{}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
ZoneTransferRequestsReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "zone_transfer_requests_received_total"),
|
||||
"Number of zone transfer requests (AXFR/IXFR) received by the master DNS server",
|
||||
[]string{"qtype"},
|
||||
nil,
|
||||
),
|
||||
ZoneTransferRequestsSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "zone_transfer_requests_sent_total"),
|
||||
"Number of zone transfer requests (AXFR/IXFR) sent by the secondary DNS server",
|
||||
[]string{"qtype"},
|
||||
nil,
|
||||
),
|
||||
ZoneTransferResponsesReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "zone_transfer_response_received_total"),
|
||||
"Number of zone transfer responses (AXFR/IXFR) received by the secondary DNS server",
|
||||
[]string{"qtype"},
|
||||
nil,
|
||||
),
|
||||
ZoneTransferSuccessReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "zone_transfer_success_received_total"),
|
||||
"Number of successful zone transfers (AXFR/IXFR) received by the secondary DNS server",
|
||||
[]string{"qtype", "protocol"},
|
||||
nil,
|
||||
),
|
||||
ZoneTransferSuccessSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "zone_transfer_success_sent_total"),
|
||||
"Number of successful zone transfers (AXFR/IXFR) of the master DNS server",
|
||||
[]string{"qtype"},
|
||||
nil,
|
||||
),
|
||||
ZoneTransferFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "zone_transfer_failures_total"),
|
||||
"Number of failed zone transfers of the master DNS server",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
MemoryUsedBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "memory_used_bytes"),
|
||||
"Current memory used by DNS server",
|
||||
[]string{"area"},
|
||||
nil,
|
||||
),
|
||||
DynamicUpdatesQueued: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "dynamic_updates_queued"),
|
||||
"Number of dynamic updates queued by the DNS server",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DynamicUpdatesReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "dynamic_updates_received_total"),
|
||||
"Number of secure update requests received by the DNS server",
|
||||
[]string{"operation"},
|
||||
nil,
|
||||
),
|
||||
DynamicUpdatesFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "dynamic_updates_failures_total"),
|
||||
"Number of dynamic updates which timed out or were rejected by the DNS server",
|
||||
[]string{"reason"},
|
||||
nil,
|
||||
),
|
||||
NotifyReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "notify_received_total"),
|
||||
"Number of notifies received by the secondary DNS server",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
NotifySent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "notify_sent_total"),
|
||||
"Number of notifies sent by the master DNS server",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SecureUpdateFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "secure_update_failures_total"),
|
||||
"Number of secure updates that failed on the DNS server",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SecureUpdateReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "secure_update_received_total"),
|
||||
"Number of secure update requests received by the DNS server",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
Queries: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "queries_total"),
|
||||
"Number of queries received by DNS server",
|
||||
[]string{"protocol"},
|
||||
nil,
|
||||
),
|
||||
Responses: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "responses_total"),
|
||||
"Number of responses sent by DNS server",
|
||||
[]string{"protocol"},
|
||||
nil,
|
||||
),
|
||||
RecursiveQueries: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "recursive_queries_total"),
|
||||
"Number of recursive queries received by DNS server",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
RecursiveQueryFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "recursive_query_failures_total"),
|
||||
"Number of recursive query failures",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
RecursiveQuerySendTimeouts: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "recursive_query_send_timeouts_total"),
|
||||
"Number of recursive query sending timeouts",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
WinsQueries: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "wins_queries_total"),
|
||||
"Number of WINS lookup requests received by the server",
|
||||
[]string{"direction"},
|
||||
nil,
|
||||
),
|
||||
WinsResponses: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "wins_responses_total"),
|
||||
"Number of WINS lookup responses sent by the server",
|
||||
[]string{"direction"},
|
||||
nil,
|
||||
),
|
||||
UnmatchedResponsesReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "unmatched_responses_total"),
|
||||
"Number of response packets received by the DNS server that do not match any outstanding remote query",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
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.ZoneTransferRequestsReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_received_total"),
|
||||
"Number of zone transfer requests (AXFR/IXFR) received by the master DNS server",
|
||||
[]string{"qtype"},
|
||||
nil,
|
||||
)
|
||||
c.ZoneTransferRequestsSent = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_sent_total"),
|
||||
"Number of zone transfer requests (AXFR/IXFR) sent by the secondary DNS server",
|
||||
[]string{"qtype"},
|
||||
nil,
|
||||
)
|
||||
c.ZoneTransferResponsesReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_response_received_total"),
|
||||
"Number of zone transfer responses (AXFR/IXFR) received by the secondary DNS server",
|
||||
[]string{"qtype"},
|
||||
nil,
|
||||
)
|
||||
c.ZoneTransferSuccessReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_success_received_total"),
|
||||
"Number of successful zone transfers (AXFR/IXFR) received by the secondary DNS server",
|
||||
[]string{"qtype", "protocol"},
|
||||
nil,
|
||||
)
|
||||
c.ZoneTransferSuccessSent = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_success_sent_total"),
|
||||
"Number of successful zone transfers (AXFR/IXFR) of the master DNS server",
|
||||
[]string{"qtype"},
|
||||
nil,
|
||||
)
|
||||
c.ZoneTransferFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_failures_total"),
|
||||
"Number of failed zone transfers of the master DNS server",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.MemoryUsedBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "memory_used_bytes"),
|
||||
"Current memory used by DNS server",
|
||||
[]string{"area"},
|
||||
nil,
|
||||
)
|
||||
c.DynamicUpdatesQueued = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dynamic_updates_queued"),
|
||||
"Number of dynamic updates queued by the DNS server",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.DynamicUpdatesReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dynamic_updates_received_total"),
|
||||
"Number of secure update requests received by the DNS server",
|
||||
[]string{"operation"},
|
||||
nil,
|
||||
)
|
||||
c.DynamicUpdatesFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dynamic_updates_failures_total"),
|
||||
"Number of dynamic updates which timed out or were rejected by the DNS server",
|
||||
[]string{"reason"},
|
||||
nil,
|
||||
)
|
||||
c.NotifyReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "notify_received_total"),
|
||||
"Number of notifies received by the secondary DNS server",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.NotifySent = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "notify_sent_total"),
|
||||
"Number of notifies sent by the master DNS server",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SecureUpdateFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "secure_update_failures_total"),
|
||||
"Number of secure updates that failed on the DNS server",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.SecureUpdateReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "secure_update_received_total"),
|
||||
"Number of secure update requests received by the DNS server",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.Queries = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "queries_total"),
|
||||
"Number of queries received by DNS server",
|
||||
[]string{"protocol"},
|
||||
nil,
|
||||
)
|
||||
c.Responses = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "responses_total"),
|
||||
"Number of responses sent by DNS server",
|
||||
[]string{"protocol"},
|
||||
nil,
|
||||
)
|
||||
c.RecursiveQueries = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "recursive_queries_total"),
|
||||
"Number of recursive queries received by DNS server",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.RecursiveQueryFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "recursive_query_failures_total"),
|
||||
"Number of recursive query failures",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.RecursiveQuerySendTimeouts = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "recursive_query_send_timeouts_total"),
|
||||
"Number of recursive query sending timeouts",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.WinsQueries = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "wins_queries_total"),
|
||||
"Number of WINS lookup requests received by the server",
|
||||
[]string{"direction"},
|
||||
nil,
|
||||
)
|
||||
c.WinsResponses = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "wins_responses_total"),
|
||||
"Number of WINS lookup responses sent by the server",
|
||||
[]string{"direction"},
|
||||
nil,
|
||||
)
|
||||
c.UnmatchedResponsesReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "unmatched_responses_total"),
|
||||
"Number of response packets received by the DNS server that do not match any outstanding remote query",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *DNSCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting dns metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
@@ -237,9 +261,9 @@ type Win32_PerfRawData_DNS_DNS struct {
|
||||
ZoneTransferSOARequestSent uint32
|
||||
}
|
||||
|
||||
func (c *DNSCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_DNS_DNS
|
||||
q := queryAll(&dst, c.logger)
|
||||
q := wmi.QueryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
12
pkg/collector/dns/dns_test.go
Normal file
12
pkg/collector/dns/dns_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package dns_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/dns"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, dns.Name, dns.NewWithFlags)
|
||||
}
|
||||
@@ -1,27 +1,41 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
Name = "exchange"
|
||||
FlagExchangeListAllCollectors = "collectors.exchange.list"
|
||||
FlagExchangeCollectorsEnabled = "collectors.exchange.enabled"
|
||||
)
|
||||
|
||||
type exchangeCollector struct {
|
||||
type Config struct {
|
||||
CollectorsEnabled string `yaml:"collectors_enabled"`
|
||||
}
|
||||
|
||||
var ConfigDefaults = Config{
|
||||
CollectorsEnabled: "",
|
||||
}
|
||||
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
exchangeListAllCollectors *bool
|
||||
exchangeCollectorsEnabled *string
|
||||
|
||||
LDAPReadTime *prometheus.Desc
|
||||
LDAPSearchTime *prometheus.Desc
|
||||
LDAPWriteTime *prometheus.Desc
|
||||
@@ -63,95 +77,119 @@ type exchangeCollector struct {
|
||||
enabledCollectors []string
|
||||
}
|
||||
|
||||
var (
|
||||
// All available collector functions
|
||||
exchangeAllCollectorNames = []string{
|
||||
"ADAccessProcesses",
|
||||
"TransportQueues",
|
||||
"HttpProxy",
|
||||
"ActiveSync",
|
||||
"AvailabilityService",
|
||||
"OutlookWebAccess",
|
||||
"Autodiscover",
|
||||
"WorkloadManagement",
|
||||
"RpcClientAccess",
|
||||
}
|
||||
|
||||
argExchangeListAllCollectors *bool
|
||||
|
||||
argExchangeCollectorsEnabled *string
|
||||
)
|
||||
|
||||
// newExchangeCollectorFlags ...
|
||||
func newExchangeCollectorFlags(app *kingpin.Application) {
|
||||
argExchangeListAllCollectors = app.Flag(
|
||||
FlagExchangeListAllCollectors,
|
||||
"List the collectors along with their perflib object name/ids",
|
||||
).Bool()
|
||||
|
||||
argExchangeCollectorsEnabled = app.Flag(
|
||||
FlagExchangeCollectorsEnabled,
|
||||
"Comma-separated list of collectors to use. Defaults to all, if not specified.",
|
||||
).Default("").String()
|
||||
// All available collector functions
|
||||
var exchangeAllCollectorNames = []string{
|
||||
"ADAccessProcesses",
|
||||
"TransportQueues",
|
||||
"HttpProxy",
|
||||
"ActiveSync",
|
||||
"AvailabilityService",
|
||||
"OutlookWebAccess",
|
||||
"Autodiscover",
|
||||
"WorkloadManagement",
|
||||
"RpcClientAccess",
|
||||
}
|
||||
|
||||
// newExchangeCollector returns a new Collector
|
||||
func newExchangeCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "exchange"
|
||||
func New(logger log.Logger, config *Config) types.Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
exchangeListAllCollectors := false
|
||||
c := &collector{
|
||||
exchangeCollectorsEnabled: &config.CollectorsEnabled,
|
||||
exchangeListAllCollectors: &exchangeListAllCollectors,
|
||||
}
|
||||
c.SetLogger(logger)
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(app *kingpin.Application) types.Collector {
|
||||
return &collector{
|
||||
exchangeListAllCollectors: app.Flag(
|
||||
FlagExchangeListAllCollectors,
|
||||
"List the collectors along with their perflib object name/ids",
|
||||
).Bool(),
|
||||
|
||||
exchangeCollectorsEnabled: app.Flag(
|
||||
FlagExchangeCollectorsEnabled,
|
||||
"Comma-separated list of collectors to use. Defaults to all, if not specified.",
|
||||
).Default(ConfigDefaults.CollectorsEnabled).String(),
|
||||
}
|
||||
}
|
||||
|
||||
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{
|
||||
"MSExchange ADAccess Processes",
|
||||
"MSExchangeTransport Queues",
|
||||
"MSExchange HttpProxy",
|
||||
"MSExchange ActiveSync",
|
||||
"MSExchange Availability Service",
|
||||
"MSExchange OWA",
|
||||
"MSExchangeAutodiscover",
|
||||
"MSExchange WorkloadManagement Workloads",
|
||||
"MSExchange RpcClientAccess",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *collector) Build() error {
|
||||
// desc creates a new prometheus description
|
||||
desc := func(metricName string, description string, labels ...string) *prometheus.Desc {
|
||||
return prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, "exchange", metricName),
|
||||
prometheus.BuildFQName(types.Namespace, "exchange", metricName),
|
||||
description,
|
||||
labels,
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
c := exchangeCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
c.RPCAveragedLatency = desc("rpc_avg_latency_sec", "The latency (sec) averaged for the past 1024 packets")
|
||||
c.RPCRequests = desc("rpc_requests", "Number of client requests currently being processed by the RPC Client Access service")
|
||||
c.ActiveUserCount = desc("rpc_active_user_count", "Number of unique users that have shown some kind of activity in the last 2 minutes")
|
||||
c.ConnectionCount = desc("rpc_connection_count", "Total number of client connections maintained")
|
||||
c.RPCOperationsPerSec = desc("rpc_operations_total", "The rate at which RPC operations occur")
|
||||
c.UserCount = desc("rpc_user_count", "Number of users")
|
||||
c.LDAPReadTime = desc("ldap_read_time_sec", "Time (sec) to send an LDAP read request and receive a response", "name")
|
||||
c.LDAPSearchTime = desc("ldap_search_time_sec", "Time (sec) to send an LDAP search request and receive a response", "name")
|
||||
c.LDAPWriteTime = desc("ldap_write_time_sec", "Time (sec) to send an LDAP Add/Modify/Delete request and receive a response", "name")
|
||||
c.LDAPTimeoutErrorsPerSec = desc("ldap_timeout_errors_total", "Total number of LDAP timeout errors", "name")
|
||||
c.LongRunningLDAPOperationsPerMin = desc("ldap_long_running_ops_per_sec", "Long Running LDAP operations per second", "name")
|
||||
c.ExternalActiveRemoteDeliveryQueueLength = desc("transport_queues_external_active_remote_delivery", "External Active Remote Delivery Queue length", "name")
|
||||
c.InternalActiveRemoteDeliveryQueueLength = desc("transport_queues_internal_active_remote_delivery", "Internal Active Remote Delivery Queue length", "name")
|
||||
c.ActiveMailboxDeliveryQueueLength = desc("transport_queues_active_mailbox_delivery", "Active Mailbox Delivery Queue length", "name")
|
||||
c.RetryMailboxDeliveryQueueLength = desc("transport_queues_retry_mailbox_delivery", "Retry Mailbox Delivery Queue length", "name")
|
||||
c.UnreachableQueueLength = desc("transport_queues_unreachable", "Unreachable Queue length", "name")
|
||||
c.ExternalLargestDeliveryQueueLength = desc("transport_queues_external_largest_delivery", "External Largest Delivery Queue length", "name")
|
||||
c.InternalLargestDeliveryQueueLength = desc("transport_queues_internal_largest_delivery", "Internal Largest Delivery Queue length", "name")
|
||||
c.PoisonQueueLength = desc("transport_queues_poison", "Poison Queue length", "name")
|
||||
c.MailboxServerLocatorAverageLatency = desc("http_proxy_mailbox_server_locator_avg_latency_sec", "Average latency (sec) of MailboxServerLocator web service calls", "name")
|
||||
c.AverageAuthenticationLatency = desc("http_proxy_avg_auth_latency", "Average time spent authenticating CAS requests over the last 200 samples", "name")
|
||||
c.OutstandingProxyRequests = desc("http_proxy_outstanding_proxy_requests", "Number of concurrent outstanding proxy requests", "name")
|
||||
c.ProxyRequestsPerSec = desc("http_proxy_requests_total", "Number of proxy requests processed each second", "name")
|
||||
c.AvailabilityRequestsSec = desc("avail_service_requests_per_sec", "Number of requests serviced per second")
|
||||
c.CurrentUniqueUsers = desc("owa_current_unique_users", "Number of unique users currently logged on to Outlook Web App")
|
||||
c.OWARequestsPerSec = desc("owa_requests_total", "Number of requests handled by Outlook Web App per second")
|
||||
c.AutodiscoverRequestsPerSec = desc("autodiscover_requests_total", "Number of autodiscover service requests processed each second")
|
||||
c.ActiveTasks = desc("workload_active_tasks", "Number of active tasks currently running in the background for workload management", "name")
|
||||
c.CompletedTasks = desc("workload_completed_tasks", "Number of workload management tasks that have been completed", "name")
|
||||
c.QueuedTasks = desc("workload_queued_tasks", "Number of workload management tasks that are currently queued up waiting to be processed", "name")
|
||||
c.YieldedTasks = desc("workload_yielded_tasks", "The total number of tasks that have been yielded by a workload", "name")
|
||||
c.IsActive = desc("workload_is_active", "Active indicates whether the workload is in an active (1) or paused (0) state", "name")
|
||||
c.ActiveSyncRequestsPerSec = desc("activesync_requests_total", "Num HTTP requests received from the client via ASP.NET per sec. Shows Current user load")
|
||||
c.AverageCASProcessingLatency = desc("http_proxy_avg_cas_proccessing_latency_sec", "Average latency (sec) of CAS processing time over the last 200 reqs", "name")
|
||||
c.MailboxServerProxyFailureRate = desc("http_proxy_mailbox_proxy_failure_rate", "% of failures between this CAS and MBX servers over the last 200 samples", "name")
|
||||
c.PingCommandsPending = desc("activesync_ping_cmds_pending", "Number of ping commands currently pending in the queue")
|
||||
c.SyncCommandsPerSec = desc("activesync_sync_cmds_total", "Number of sync commands processed per second. Clients use this command to synchronize items within a folder")
|
||||
|
||||
RPCAveragedLatency: desc("rpc_avg_latency_sec", "The latency (sec), averaged for the past 1024 packets"),
|
||||
RPCRequests: desc("rpc_requests", "Number of client requests currently being processed by the RPC Client Access service"),
|
||||
ActiveUserCount: desc("rpc_active_user_count", "Number of unique users that have shown some kind of activity in the last 2 minutes"),
|
||||
ConnectionCount: desc("rpc_connection_count", "Total number of client connections maintained"),
|
||||
RPCOperationsPerSec: desc("rpc_operations_total", "The rate at which RPC operations occur"),
|
||||
UserCount: desc("rpc_user_count", "Number of users"),
|
||||
LDAPReadTime: desc("ldap_read_time_sec", "Time (sec) to send an LDAP read request and receive a response", "name"),
|
||||
LDAPSearchTime: desc("ldap_search_time_sec", "Time (sec) to send an LDAP search request and receive a response", "name"),
|
||||
LDAPWriteTime: desc("ldap_write_time_sec", "Time (sec) to send an LDAP Add/Modify/Delete request and receive a response", "name"),
|
||||
LDAPTimeoutErrorsPerSec: desc("ldap_timeout_errors_total", "Total number of LDAP timeout errors", "name"),
|
||||
LongRunningLDAPOperationsPerMin: desc("ldap_long_running_ops_per_sec", "Long Running LDAP operations per second", "name"),
|
||||
ExternalActiveRemoteDeliveryQueueLength: desc("transport_queues_external_active_remote_delivery", "External Active Remote Delivery Queue length", "name"),
|
||||
InternalActiveRemoteDeliveryQueueLength: desc("transport_queues_internal_active_remote_delivery", "Internal Active Remote Delivery Queue length", "name"),
|
||||
ActiveMailboxDeliveryQueueLength: desc("transport_queues_active_mailbox_delivery", "Active Mailbox Delivery Queue length", "name"),
|
||||
RetryMailboxDeliveryQueueLength: desc("transport_queues_retry_mailbox_delivery", "Retry Mailbox Delivery Queue length", "name"),
|
||||
UnreachableQueueLength: desc("transport_queues_unreachable", "Unreachable Queue length", "name"),
|
||||
ExternalLargestDeliveryQueueLength: desc("transport_queues_external_largest_delivery", "External Largest Delivery Queue length", "name"),
|
||||
InternalLargestDeliveryQueueLength: desc("transport_queues_internal_largest_delivery", "Internal Largest Delivery Queue length", "name"),
|
||||
PoisonQueueLength: desc("transport_queues_poison", "Poison Queue length", "name"),
|
||||
MailboxServerLocatorAverageLatency: desc("http_proxy_mailbox_server_locator_avg_latency_sec", "Average latency (sec) of MailboxServerLocator web service calls", "name"),
|
||||
AverageAuthenticationLatency: desc("http_proxy_avg_auth_latency", "Average time spent authenticating CAS requests over the last 200 samples", "name"),
|
||||
OutstandingProxyRequests: desc("http_proxy_outstanding_proxy_requests", "Number of concurrent outstanding proxy requests", "name"),
|
||||
ProxyRequestsPerSec: desc("http_proxy_requests_total", "Number of proxy requests processed each second", "name"),
|
||||
AvailabilityRequestsSec: desc("avail_service_requests_per_sec", "Number of requests serviced per second"),
|
||||
CurrentUniqueUsers: desc("owa_current_unique_users", "Number of unique users currently logged on to Outlook Web App"),
|
||||
OWARequestsPerSec: desc("owa_requests_total", "Number of requests handled by Outlook Web App per second"),
|
||||
AutodiscoverRequestsPerSec: desc("autodiscover_requests_total", "Number of autodiscover service requests processed each second"),
|
||||
ActiveTasks: desc("workload_active_tasks", "Number of active tasks currently running in the background for workload management", "name"),
|
||||
CompletedTasks: desc("workload_completed_tasks", "Number of workload management tasks that have been completed", "name"),
|
||||
QueuedTasks: desc("workload_queued_tasks", "Number of workload management tasks that are currently queued up waiting to be processed", "name"),
|
||||
YieldedTasks: desc("workload_yielded_tasks", "The total number of tasks that have been yielded by a workload", "name"),
|
||||
IsActive: desc("workload_is_active", "Active indicates whether the workload is in an active (1) or paused (0) state", "name"),
|
||||
ActiveSyncRequestsPerSec: desc("activesync_requests_total", "Num HTTP requests received from the client via ASP.NET per sec. Shows Current user load"),
|
||||
AverageCASProcessingLatency: desc("http_proxy_avg_cas_proccessing_latency_sec", "Average latency (sec) of CAS processing time over the last 200 reqs", "name"),
|
||||
MailboxServerProxyFailureRate: desc("http_proxy_mailbox_proxy_failure_rate", "% of failures between this CAS and MBX servers over the last 200 samples", "name"),
|
||||
PingCommandsPending: desc("activesync_ping_cmds_pending", "Number of ping commands currently pending in the queue"),
|
||||
SyncCommandsPerSec: desc("activesync_sync_cmds_total", "Number of sync commands processed per second. Clients use this command to synchronize items within a folder"),
|
||||
|
||||
enabledCollectors: make([]string, 0, len(exchangeAllCollectorNames)),
|
||||
}
|
||||
c.enabledCollectors = make([]string, 0, len(exchangeAllCollectorNames))
|
||||
|
||||
collectorDesc := map[string]string{
|
||||
"ADAccessProcesses": "[19108] MSExchange ADAccess Processes",
|
||||
@@ -165,7 +203,7 @@ func newExchangeCollector(logger log.Logger) (Collector, error) {
|
||||
"RpcClientAccess": "[29336] MSExchange RpcClientAccess",
|
||||
}
|
||||
|
||||
if *argExchangeListAllCollectors {
|
||||
if *c.exchangeListAllCollectors {
|
||||
fmt.Printf("%-32s %-32s\n", "Collector Name", "[PerfID] Perflib Object")
|
||||
for _, cname := range exchangeAllCollectorNames {
|
||||
fmt.Printf("%-32s %-32s\n", cname, collectorDesc[cname])
|
||||
@@ -173,27 +211,26 @@ func newExchangeCollector(logger log.Logger) (Collector, error) {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if *argExchangeCollectorsEnabled == "" {
|
||||
if *c.exchangeCollectorsEnabled == "" {
|
||||
for _, collectorName := range exchangeAllCollectorNames {
|
||||
c.enabledCollectors = append(c.enabledCollectors, collectorName)
|
||||
}
|
||||
} else {
|
||||
for _, collectorName := range strings.Split(*argExchangeCollectorsEnabled, ",") {
|
||||
if find(exchangeAllCollectorNames, collectorName) {
|
||||
for _, collectorName := range strings.Split(*c.exchangeCollectorsEnabled, ",") {
|
||||
if slices.Contains(exchangeAllCollectorNames, collectorName) {
|
||||
c.enabledCollectors = append(c.enabledCollectors, collectorName)
|
||||
} else {
|
||||
return nil, fmt.Errorf("Unknown exchange collector: %s", collectorName)
|
||||
return fmt.Errorf("unknown exchange collector: %s", collectorName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &c, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect collects exchange metrics and sends them to prometheus
|
||||
func (c *exchangeCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
|
||||
collectorFuncs := map[string]func(ctx *ScrapeContext, ch chan<- prometheus.Metric) error{
|
||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
|
||||
"ADAccessProcesses": c.collectADAccessProcesses,
|
||||
"TransportQueues": c.collectTransportQueues,
|
||||
"HttpProxy": c.collectHTTPProxy,
|
||||
@@ -225,9 +262,9 @@ type perflibADAccessProcesses struct {
|
||||
LongRunningLDAPOperationsPerMin float64 `perflib:"Long Running LDAP Operations/min"`
|
||||
}
|
||||
|
||||
func (c *exchangeCollector) collectADAccessProcesses(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectADAccessProcesses(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibADAccessProcesses
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange ADAccess Processes"], &data, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange ADAccess Processes"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -238,8 +275,8 @@ func (c *exchangeCollector) collectADAccessProcesses(ctx *ScrapeContext, ch chan
|
||||
continue
|
||||
}
|
||||
|
||||
// since we're not including the PID suffix from the instance names in the label names,
|
||||
// we get an occasional duplicate. This seems to affect about 4 instances only on this object.
|
||||
// Since we're not including the PID suffix from the instance names in the label names, we get an occasional duplicate.
|
||||
// This seems to affect about 4 instances only of this object.
|
||||
labelUseCount[labelName]++
|
||||
if labelUseCount[labelName] > 1 {
|
||||
labelName = fmt.Sprintf("%s_%d", labelName, labelUseCount[labelName])
|
||||
@@ -283,9 +320,9 @@ type perflibAvailabilityService struct {
|
||||
RequestsSec float64 `perflib:"Availability Requests (sec)"`
|
||||
}
|
||||
|
||||
func (c *exchangeCollector) collectAvailabilityService(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectAvailabilityService(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibAvailabilityService
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange Availability Service"], &data, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange Availability Service"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -311,9 +348,9 @@ type perflibHTTPProxy struct {
|
||||
ProxyRequestsPerSec float64 `perflib:"Proxy Requests/Sec"`
|
||||
}
|
||||
|
||||
func (c *exchangeCollector) collectHTTPProxy(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectHTTPProxy(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibHTTPProxy
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange HttpProxy"], &data, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange HttpProxy"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -365,9 +402,9 @@ type perflibOWA struct {
|
||||
RequestsPerSec float64 `perflib:"Requests/sec"`
|
||||
}
|
||||
|
||||
func (c *exchangeCollector) collectOWA(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectOWA(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibOWA
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange OWA"], &data, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange OWA"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -393,9 +430,9 @@ type perflibActiveSync struct {
|
||||
SyncCommandsPerSec float64 `perflib:"Sync Commands/sec"`
|
||||
}
|
||||
|
||||
func (c *exchangeCollector) collectActiveSync(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectActiveSync(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibActiveSync
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange ActiveSync"], &data, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange ActiveSync"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -429,9 +466,9 @@ type perflibRPCClientAccess struct {
|
||||
UserCount float64 `perflib:"User Count"`
|
||||
}
|
||||
|
||||
func (c *exchangeCollector) collectRPC(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectRPC(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibRPCClientAccess
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange RpcClientAccess"], &data, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange RpcClientAccess"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -485,9 +522,9 @@ type perflibTransportQueues struct {
|
||||
PoisonQueueLength float64 `perflib:"Poison Queue Length"`
|
||||
}
|
||||
|
||||
func (c *exchangeCollector) collectTransportQueues(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectTransportQueues(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibTransportQueues
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchangeTransport Queues"], &data, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchangeTransport Queues"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -559,9 +596,9 @@ type perflibWorkloadManagementWorkloads struct {
|
||||
IsActive float64 `perflib:"Active"`
|
||||
}
|
||||
|
||||
func (c *exchangeCollector) collectWorkloadManagementWorkloads(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectWorkloadManagementWorkloads(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibWorkloadManagementWorkloads
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange WorkloadManagement Workloads"], &data, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange WorkloadManagement Workloads"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -610,9 +647,9 @@ type perflibAutodiscover struct {
|
||||
RequestsPerSec float64 `perflib:"Requests/sec"`
|
||||
}
|
||||
|
||||
func (c *exchangeCollector) collectAutoDiscover(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *collector) collectAutoDiscover(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibAutodiscover
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchangeAutodiscover"], &data, c.logger); err != nil {
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchangeAutodiscover"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, autodisc := range data {
|
||||
@@ -625,14 +662,14 @@ func (c *exchangeCollector) collectAutoDiscover(ctx *ScrapeContext, ch chan<- pr
|
||||
return nil
|
||||
}
|
||||
|
||||
// toLabelName converts strings to lowercase and replaces all whitespace and dots with underscores
|
||||
func (c *exchangeCollector) toLabelName(name string) string {
|
||||
// toLabelName converts strings to lowercase and replaces all whitespaces and dots with underscores
|
||||
func (c *collector) toLabelName(name string) string {
|
||||
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
|
||||
s = strings.ReplaceAll(s, "__", "_")
|
||||
return s
|
||||
}
|
||||
|
||||
// msToSec converts from ms to seconds
|
||||
func (c *exchangeCollector) msToSec(t float64) float64 {
|
||||
func (c *collector) msToSec(t float64) float64 {
|
||||
return t / 1000
|
||||
}
|
||||
12
pkg/collector/exchange/exchange_test.go
Normal file
12
pkg/collector/exchange/exchange_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package exchange_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, exchange.Name, exchange.NewWithFlags)
|
||||
}
|
||||
218
pkg/collector/fsrmquota/fsrmquota.go
Normal file
218
pkg/collector/fsrmquota/fsrmquota.go
Normal file
@@ -0,0 +1,218 @@
|
||||
//go:build windows
|
||||
|
||||
package fsrmquota
|
||||
|
||||
import (
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "fsrmquota"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
type collector struct {
|
||||
logger log.Logger
|
||||
|
||||
QuotasCount *prometheus.Desc
|
||||
Path *prometheus.Desc
|
||||
PeakUsage *prometheus.Desc
|
||||
Size *prometheus.Desc
|
||||
Usage *prometheus.Desc
|
||||
|
||||
Description *prometheus.Desc
|
||||
Disabled *prometheus.Desc
|
||||
MatchesTemplate *prometheus.Desc
|
||||
SoftLimit *prometheus.Desc
|
||||
Template *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.QuotasCount = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "count"),
|
||||
"Number of Quotas",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.PeakUsage = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "peak_usage_bytes"),
|
||||
"The highest amount of disk space usage charged to this quota. (PeakUsage)",
|
||||
[]string{"path", "template"},
|
||||
nil,
|
||||
)
|
||||
c.Size = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "size_bytes"),
|
||||
"The size of the quota. (Size)",
|
||||
[]string{"path", "template"},
|
||||
nil,
|
||||
)
|
||||
c.Usage = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "usage_bytes"),
|
||||
"The current amount of disk space usage charged to this quota. (Usage)",
|
||||
[]string{"path", "template"},
|
||||
nil,
|
||||
)
|
||||
c.Description = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "description"),
|
||||
"Description of the quota (Description)",
|
||||
[]string{"path", "template", "description"},
|
||||
nil,
|
||||
)
|
||||
c.Disabled = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "disabled"),
|
||||
"If 1, the quota is disabled. The default value is 0. (Disabled)",
|
||||
[]string{"path", "template"},
|
||||
nil,
|
||||
)
|
||||
c.SoftLimit = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "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,
|
||||
)
|
||||
c.Template = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "template"),
|
||||
"Quota template name. (Template)",
|
||||
[]string{"path", "template"},
|
||||
nil,
|
||||
)
|
||||
c.MatchesTemplate = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "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,
|
||||
)
|
||||
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 desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting fsrmquota metrics", "desc", desc, "err", 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 *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []MSFT_FSRMQuota
|
||||
q := wmi.QueryAll(&dst, c.logger)
|
||||
|
||||
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,
|
||||
utils.BoolToFloat(quota.Disabled),
|
||||
path,
|
||||
template,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.MatchesTemplate,
|
||||
prometheus.GaugeValue,
|
||||
utils.BoolToFloat(quota.MatchesTemplate),
|
||||
path,
|
||||
template,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SoftLimit,
|
||||
prometheus.GaugeValue,
|
||||
utils.BoolToFloat(quota.SoftLimit),
|
||||
path,
|
||||
template,
|
||||
)
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.QuotasCount,
|
||||
prometheus.GaugeValue,
|
||||
float64(count),
|
||||
)
|
||||
return nil, nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user