mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-13 16:36:37 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9404c6cc2 |
@@ -3,8 +3,6 @@
|
|||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -15,21 +13,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerCollector("process", newProcessCollector, "Process")
|
registerCollector("process", NewProcessCollector)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
processWhitelist = kingpin.Flag(
|
processWhereClause = kingpin.Flag(
|
||||||
"collector.process.whitelist",
|
"collector.process.processes-where",
|
||||||
"Regexp of processes to include. Process name must both match whitelist and not match blacklist to be included.",
|
"WQL 'where' clause to use in WMI metrics query. Limits the response to the processes you specify and reduces the size of the response.",
|
||||||
).Default(".*").String()
|
|
||||||
processBlacklist = kingpin.Flag(
|
|
||||||
"collector.process.blacklist",
|
|
||||||
"Regexp of processes to exclude. Process name must both match whitelist and not match blacklist to be included.",
|
|
||||||
).Default("").String()
|
).Default("").String()
|
||||||
)
|
)
|
||||||
|
|
||||||
type processCollector struct {
|
// A ProcessCollector is a Prometheus collector for WMI Win32_PerfRawData_PerfProc_Process metrics
|
||||||
|
type ProcessCollector struct {
|
||||||
StartTime *prometheus.Desc
|
StartTime *prometheus.Desc
|
||||||
CPUTimeTotal *prometheus.Desc
|
CPUTimeTotal *prometheus.Desc
|
||||||
HandleCount *prometheus.Desc
|
HandleCount *prometheus.Desc
|
||||||
@@ -44,19 +39,18 @@ type processCollector struct {
|
|||||||
VirtualBytes *prometheus.Desc
|
VirtualBytes *prometheus.Desc
|
||||||
WorkingSet *prometheus.Desc
|
WorkingSet *prometheus.Desc
|
||||||
|
|
||||||
processWhitelistPattern *regexp.Regexp
|
queryWhereClause string
|
||||||
processBlacklistPattern *regexp.Regexp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProcessCollector ...
|
// NewProcessCollector ...
|
||||||
func newProcessCollector() (Collector, error) {
|
func NewProcessCollector() (Collector, error) {
|
||||||
const subsystem = "process"
|
const subsystem = "process"
|
||||||
|
|
||||||
if *processWhitelist == ".*" && *processBlacklist == "" {
|
if *processWhereClause == "" {
|
||||||
log.Warn("No filters specified for process collector. This will generate a very large number of metrics!")
|
log.Warn("No where-clause specified for process collector. This will generate a very large number of metrics!")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &processCollector{
|
return &ProcessCollector{
|
||||||
StartTime: prometheus.NewDesc(
|
StartTime: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(Namespace, subsystem, "start_time"),
|
prometheus.BuildFQName(Namespace, subsystem, "start_time"),
|
||||||
"Time of process start.",
|
"Time of process start.",
|
||||||
@@ -135,53 +129,66 @@ func newProcessCollector() (Collector, error) {
|
|||||||
[]string{"process", "process_id", "creating_process_id"},
|
[]string{"process", "process_id", "creating_process_id"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
processWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processWhitelist)),
|
queryWhereClause: *processWhereClause,
|
||||||
processBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processBlacklist)),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type perflibProcess struct {
|
// Collect sends the metric values for each metric
|
||||||
|
// to the provided prometheus Metric channel.
|
||||||
|
func (c *ProcessCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
|
if desc, err := c.collect(ch); err != nil {
|
||||||
|
log.Error("failed collecting process metrics:", desc, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Win32_PerfRawData_PerfProc_Process docs:
|
||||||
|
// - https://msdn.microsoft.com/en-us/library/aa394323(v=vs.85).aspx
|
||||||
|
type Win32_PerfRawData_PerfProc_Process struct {
|
||||||
Name string
|
Name string
|
||||||
PercentProcessorTime float64 `perflib:"% Processor Time"`
|
CreatingProcessID uint32
|
||||||
PercentPrivilegedTime float64 `perflib:"% Privileged Time"`
|
ElapsedTime uint64
|
||||||
PercentUserTime float64 `perflib:"% User Time"`
|
Frequency_Object uint64
|
||||||
CreatingProcessID float64 `perflib:"Creating Process ID"`
|
HandleCount uint32
|
||||||
ElapsedTime float64 `perflib:"Elapsed Time"`
|
IDProcess uint32
|
||||||
HandleCount float64 `perflib:"Handle Count"`
|
IODataBytesPersec uint64
|
||||||
IDProcess float64 `perflib:"ID Process"`
|
IODataOperationsPersec uint64
|
||||||
IODataBytesPerSec float64 `perflib:"IO Data Bytes/sec"`
|
IOOtherBytesPersec uint64
|
||||||
IODataOperationsPerSec float64 `perflib:"IO Data Operations/sec"`
|
IOOtherOperationsPersec uint64
|
||||||
IOOtherBytesPerSec float64 `perflib:"IO Other Bytes/sec"`
|
IOReadBytesPersec uint64
|
||||||
IOOtherOperationsPerSec float64 `perflib:"IO Other Operations/sec"`
|
IOReadOperationsPersec uint64
|
||||||
IOReadBytesPerSec float64 `perflib:"IO Read Bytes/sec"`
|
IOWriteBytesPersec uint64
|
||||||
IOReadOperationsPerSec float64 `perflib:"IO Read Operations/sec"`
|
IOWriteOperationsPersec uint64
|
||||||
IOWriteBytesPerSec float64 `perflib:"IO Write Bytes/sec"`
|
PageFaultsPersec uint32
|
||||||
IOWriteOperationsPerSec float64 `perflib:"IO Write Operations/sec"`
|
PageFileBytes uint64
|
||||||
PageFaultsPerSec float64 `perflib:"Page Faults/sec"`
|
PageFileBytesPeak uint64
|
||||||
PageFileBytesPeak float64 `perflib:"Page File Bytes Peak"`
|
PercentPrivilegedTime uint64
|
||||||
PageFileBytes float64 `perflib:"Page File Bytes"`
|
PercentProcessorTime uint64
|
||||||
PoolNonpagedBytes float64 `perflib:"Pool Nonpaged Bytes"`
|
PercentUserTime uint64
|
||||||
PoolPagedBytes float64 `perflib:"Pool Paged Bytes"`
|
PoolNonpagedBytes uint32
|
||||||
PriorityBase float64 `perflib:"Priority Base"`
|
PoolPagedBytes uint32
|
||||||
PrivateBytes float64 `perflib:"Private Bytes"`
|
PriorityBase uint32
|
||||||
ThreadCount float64 `perflib:"Thread Count"`
|
PrivateBytes uint64
|
||||||
VirtualBytesPeak float64 `perflib:"Virtual Bytes Peak"`
|
ThreadCount uint32
|
||||||
VirtualBytes float64 `perflib:"Virtual Bytes"`
|
Timestamp_Object uint64
|
||||||
WorkingSetPrivate float64 `perflib:"Working Set - Private"`
|
VirtualBytes uint64
|
||||||
WorkingSetPeak float64 `perflib:"Working Set Peak"`
|
VirtualBytesPeak uint64
|
||||||
WorkingSet float64 `perflib:"Working Set"`
|
WorkingSet uint64
|
||||||
|
WorkingSetPeak uint64
|
||||||
|
WorkingSetPrivate uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type WorkerProcess struct {
|
type WorkerProcess struct {
|
||||||
AppPoolName string
|
AppPoolName string
|
||||||
ProcessId uint64
|
ProcessId uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||||
data := make([]perflibProcess, 0)
|
var dst []Win32_PerfRawData_PerfProc_Process
|
||||||
err := unmarshalObject(ctx.perfObjects["Process"], &data)
|
q := queryAllWhere(&dst, c.queryWhereClause)
|
||||||
if err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var dst_wp []WorkerProcess
|
var dst_wp []WorkerProcess
|
||||||
@@ -190,10 +197,9 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
log.Debugf("Could not query WebAdministration namespace for IIS worker processes: %v. Skipping", err)
|
log.Debugf("Could not query WebAdministration namespace for IIS worker processes: %v. Skipping", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range data {
|
for _, process := range dst {
|
||||||
if process.Name == "_Total" ||
|
|
||||||
c.processBlacklistPattern.MatchString(process.Name) ||
|
if process.Name == "_Total" {
|
||||||
!c.processWhitelistPattern.MatchString(process.Name) {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Duplicate processes are suffixed # and an index number. Remove those.
|
// Duplicate processes are suffixed # and an index number. Remove those.
|
||||||
@@ -202,7 +208,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
cpid := strconv.FormatUint(uint64(process.CreatingProcessID), 10)
|
cpid := strconv.FormatUint(uint64(process.CreatingProcessID), 10)
|
||||||
|
|
||||||
for _, wp := range dst_wp {
|
for _, wp := range dst_wp {
|
||||||
if wp.ProcessId == uint64(process.IDProcess) {
|
if wp.ProcessId == process.IDProcess {
|
||||||
processName = strings.Join([]string{processName, wp.AppPoolName}, "_")
|
processName = strings.Join([]string{processName, wp.AppPoolName}, "_")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -211,7 +217,8 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.StartTime,
|
c.StartTime,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.ElapsedTime,
|
// convert from Windows timestamp (1 jan 1601) to unix timestamp (1 jan 1970)
|
||||||
|
float64(process.ElapsedTime-116444736000000000)/float64(process.Frequency_Object),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -220,7 +227,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.HandleCount,
|
c.HandleCount,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.HandleCount,
|
float64(process.HandleCount),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -229,7 +236,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CPUTimeTotal,
|
c.CPUTimeTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.PercentPrivilegedTime,
|
float64(process.PercentPrivilegedTime)*ticksToSecondsScaleFactor,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -239,7 +246,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CPUTimeTotal,
|
c.CPUTimeTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.PercentUserTime,
|
float64(process.PercentUserTime)*ticksToSecondsScaleFactor,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -249,7 +256,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOBytesTotal,
|
c.IOBytesTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOOtherBytesPerSec,
|
float64(process.IOOtherBytesPersec),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -259,7 +266,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOOperationsTotal,
|
c.IOOperationsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOOtherOperationsPerSec,
|
float64(process.IOOtherOperationsPersec),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -269,7 +276,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOBytesTotal,
|
c.IOBytesTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOReadBytesPerSec,
|
float64(process.IOReadBytesPersec),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -279,7 +286,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOOperationsTotal,
|
c.IOOperationsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOReadOperationsPerSec,
|
float64(process.IOReadOperationsPersec),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -289,7 +296,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOBytesTotal,
|
c.IOBytesTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOWriteBytesPerSec,
|
float64(process.IOWriteBytesPersec),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -299,7 +306,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOOperationsTotal,
|
c.IOOperationsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOWriteOperationsPerSec,
|
float64(process.IOWriteOperationsPersec),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -309,7 +316,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PageFaultsTotal,
|
c.PageFaultsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.PageFaultsPerSec,
|
float64(process.PageFaultsPersec),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -318,7 +325,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PageFileBytes,
|
c.PageFileBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PageFileBytes,
|
float64(process.PageFileBytes),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -327,7 +334,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PoolBytes,
|
c.PoolBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PoolNonpagedBytes,
|
float64(process.PoolNonpagedBytes),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -337,7 +344,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PoolBytes,
|
c.PoolBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PoolPagedBytes,
|
float64(process.PoolPagedBytes),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -347,7 +354,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PriorityBase,
|
c.PriorityBase,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PriorityBase,
|
float64(process.PriorityBase),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -356,7 +363,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PrivateBytes,
|
c.PrivateBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PrivateBytes,
|
float64(process.PrivateBytes),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -365,7 +372,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.ThreadCount,
|
c.ThreadCount,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.ThreadCount,
|
float64(process.ThreadCount),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -374,7 +381,7 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.VirtualBytes,
|
c.VirtualBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.VirtualBytes,
|
float64(process.VirtualBytes),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -383,12 +390,12 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.WorkingSet,
|
c.WorkingSet,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.WorkingSet,
|
float64(process.WorkingSet),
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|||||||
84
collector/terminal_services.go
Normal file
84
collector/terminal_services.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/StackExchange/wmi"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/common/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registerCollector("terminal_services", NewTerminalServicesCollector)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A TerminalServicesCollector is a Prometheus collector for WMI
|
||||||
|
// Win32_PerfRawData_LocalSessionManager_TerminalServices & Win32_PerfRawData_TermService_TerminalServicesSession metrics
|
||||||
|
type TerminalServicesCollector struct {
|
||||||
|
Local_session_count *prometheus.Desc
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTerminalServicesCollector ...
|
||||||
|
func NewTerminalServicesCollector() (Collector, error) {
|
||||||
|
const subsystem = "terminal_services"
|
||||||
|
return &TerminalServicesCollector{
|
||||||
|
Local_session_count: prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(Namespace, subsystem, "local_session_count"),
|
||||||
|
"Number of Terminal Services sessions",
|
||||||
|
[]string{"session"},
|
||||||
|
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(ch); err != nil {
|
||||||
|
log.Error("failed collecting terminal services session count metrics:", desc, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Win32_PerfRawData_LocalSessionManager_TerminalServices struct {
|
||||||
|
ActiveSessions uint32
|
||||||
|
InactiveSessions uint32
|
||||||
|
TotalSessions uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TerminalServicesCollector) collectTSSessionCount(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||||
|
var dst []Win32_PerfRawData_LocalSessionManager_TerminalServices
|
||||||
|
q := queryAll(&dst)
|
||||||
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(dst) == 0 {
|
||||||
|
return nil, errors.New("WMI query returned empty result set")
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.Local_session_count,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(dst[0].ActiveSessions),
|
||||||
|
"active",
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.Local_session_count,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(dst[0].InactiveSessions),
|
||||||
|
"inactive",
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.Local_session_count,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(dst[0].TotalSessions),
|
||||||
|
"total",
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
@@ -5,29 +5,18 @@ The process collector exposes metrics about processes
|
|||||||
|||
|
|||
|
||||||
-|-
|
-|-
|
||||||
Metric name prefix | `process`
|
Metric name prefix | `process`
|
||||||
Data source | Perflib
|
Classes | [`Win32_PerfRawData_PerfProc_Process`](https://msdn.microsoft.com/en-us/library/aa394323(v=vs.85).aspx)
|
||||||
Counters | `Process`
|
|
||||||
Enabled by default? | No
|
Enabled by default? | No
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
### `--collector.process.whitelist`
|
### `--collector.process.processes-where`
|
||||||
|
|
||||||
Regexp of processes to include. Process name must both match whitelist and not
|
A WMI filter on which processes to include. Recommended to keep down number of returned metrics.
|
||||||
match blacklist to be included. Recommended to keep down number of returned
|
|
||||||
metrics.
|
|
||||||
|
|
||||||
### `--collector.process.blacklist`
|
`%` is a wildcard, and can be used to match on substrings.
|
||||||
|
|
||||||
Regexp of processes to exclude. Process name must both match whitelist and not
|
Example: `--collector.process.processes-where="Name LIKE 'firefox%'`
|
||||||
match blacklist to be included. Recommended to keep down number of returned
|
|
||||||
metrics.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
To match all firefox processes: `--collector.process.whitelist="firefox.+"`.
|
|
||||||
Note that multiple processes with the same name will be disambiguated by
|
|
||||||
Windows by adding a number suffix, such as `firefox#2`. Your regexp must take
|
|
||||||
these suffixes into consideration.
|
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
||||||
|
|||||||
33
exporter.go
33
exporter.go
@@ -265,10 +265,6 @@ func main() {
|
|||||||
"telemetry.path",
|
"telemetry.path",
|
||||||
"URL path for surfacing collected metrics.",
|
"URL path for surfacing collected metrics.",
|
||||||
).Default("/metrics").String()
|
).Default("/metrics").String()
|
||||||
maxRequests = kingpin.Flag(
|
|
||||||
"telemetry.max-requests",
|
|
||||||
"Maximum number of concurrent requests. 0 to disable.",
|
|
||||||
).Default("5").Int()
|
|
||||||
enabledCollectors = kingpin.Flag(
|
enabledCollectors = kingpin.Flag(
|
||||||
"collectors.enabled",
|
"collectors.enabled",
|
||||||
"Comma-separated list of collectors to use. Use '[defaults]' as a placeholder for all the collectors enabled by default.").
|
"Comma-separated list of collectors to use. Use '[defaults]' as a placeholder for all the collectors enabled by default.").
|
||||||
@@ -336,16 +332,10 @@ func main() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
http.HandleFunc(*metricsPath, withConcurrencyLimit(*maxRequests, h.ServeHTTP))
|
http.Handle(*metricsPath, h)
|
||||||
http.HandleFunc("/health", healthCheck)
|
http.HandleFunc("/health", healthCheck)
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
_, _ = w.Write([]byte(`<html>
|
http.Redirect(w, r, *metricsPath, http.StatusMovedPermanently)
|
||||||
<head><title>WMI Exporter</title></head>
|
|
||||||
<body>
|
|
||||||
<h1>WMI Exporter</h1>
|
|
||||||
<p><a href="` + *metricsPath + `">Metrics</a></p>
|
|
||||||
</body>
|
|
||||||
</html>`))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
log.Infoln("Starting WMI exporter", version.Info())
|
log.Infoln("Starting WMI exporter", version.Info())
|
||||||
@@ -380,25 +370,6 @@ func keys(m map[string]collector.Collector) []string {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func withConcurrencyLimit(n int, next http.HandlerFunc) http.HandlerFunc {
|
|
||||||
if n <= 0 {
|
|
||||||
return next
|
|
||||||
}
|
|
||||||
|
|
||||||
sem := make(chan struct{}, n)
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
select {
|
|
||||||
case sem <- struct{}{}:
|
|
||||||
defer func() { <-sem }()
|
|
||||||
default:
|
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
|
||||||
_, _ = w.Write([]byte("Too many concurrent requests"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
next(w, r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type wmiExporterService struct {
|
type wmiExporterService struct {
|
||||||
stopCh chan<- bool
|
stopCh chan<- bool
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user