mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-12 07:56:38 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7890c9ce91 | ||
|
|
bcb6f2b218 | ||
|
|
91a64fecb8 | ||
|
|
9148728b87 | ||
|
|
2290969596 | ||
|
|
1d7747b4d1 | ||
|
|
cba42d24c1 | ||
|
|
58d259a2b6 | ||
|
|
4f89133893 | ||
|
|
df954ddf9d | ||
|
|
34996b206a |
@@ -97,11 +97,9 @@ The prometheus metrics will be exposed on [localhost:9182](http://localhost:9182
|
|||||||
|
|
||||||
### Enable only process collector and specify a custom query
|
### Enable only process collector and specify a custom query
|
||||||
|
|
||||||
.\wmi_exporter.exe --collectors.enabled "process" --collector.process.processes-where "Name LIKE 'firefox%'"
|
.\wmi_exporter.exe --collectors.enabled "process" --collector.process.whitelist="firefox.+"
|
||||||
|
|
||||||
When there are multiple processes with the same name, WMI represents those after the first instance as `process-name#index`. So to get them all, rather than just the first one, the query needs to be a wildcard search using a `%` character.
|
When there are multiple processes with the same name, WMI represents those after the first instance as `process-name#index`. So to get them all, rather than just the first one, the [regular expression](https://en.wikipedia.org/wiki/Regular_expression) must use `.+`. See [process](docs/collector.process.md) for more information.
|
||||||
|
|
||||||
Please note that in Windows batch scripts (and when using the `cmd` command prompt), the `%` character is reserved, so it has to be escaped with another `%`. For example, the wildcard syntax for searching for all firefox processes is `firefox%%`.
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerCollector("adfs", newADFSCollector)
|
registerCollector("adfs", newADFSCollector, "AD FS")
|
||||||
}
|
}
|
||||||
|
|
||||||
type adfsCollector struct {
|
type adfsCollector struct {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -13,18 +15,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerCollector("process", NewProcessCollector)
|
registerCollector("process", newProcessCollector, "Process")
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
processWhereClause = kingpin.Flag(
|
processWhitelist = kingpin.Flag(
|
||||||
"collector.process.processes-where",
|
"collector.process.whitelist",
|
||||||
"WQL 'where' clause to use in WMI metrics query. Limits the response to the processes you specify and reduces the size of the response.",
|
"Regexp of processes to include. Process name must both match whitelist and not match blacklist to be included.",
|
||||||
|
).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()
|
||||||
)
|
)
|
||||||
|
|
||||||
// A ProcessCollector is a Prometheus collector for WMI Win32_PerfRawData_PerfProc_Process metrics
|
type processCollector struct {
|
||||||
type ProcessCollector struct {
|
|
||||||
StartTime *prometheus.Desc
|
StartTime *prometheus.Desc
|
||||||
CPUTimeTotal *prometheus.Desc
|
CPUTimeTotal *prometheus.Desc
|
||||||
HandleCount *prometheus.Desc
|
HandleCount *prometheus.Desc
|
||||||
@@ -39,18 +44,19 @@ type ProcessCollector struct {
|
|||||||
VirtualBytes *prometheus.Desc
|
VirtualBytes *prometheus.Desc
|
||||||
WorkingSet *prometheus.Desc
|
WorkingSet *prometheus.Desc
|
||||||
|
|
||||||
queryWhereClause string
|
processWhitelistPattern *regexp.Regexp
|
||||||
|
processBlacklistPattern *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProcessCollector ...
|
// NewProcessCollector ...
|
||||||
func NewProcessCollector() (Collector, error) {
|
func newProcessCollector() (Collector, error) {
|
||||||
const subsystem = "process"
|
const subsystem = "process"
|
||||||
|
|
||||||
if *processWhereClause == "" {
|
if *processWhitelist == ".*" && *processBlacklist == "" {
|
||||||
log.Warn("No where-clause specified for process collector. This will generate a very large number of metrics!")
|
log.Warn("No filters 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.",
|
||||||
@@ -129,66 +135,53 @@ func NewProcessCollector() (Collector, error) {
|
|||||||
[]string{"process", "process_id", "creating_process_id"},
|
[]string{"process", "process_id", "creating_process_id"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
queryWhereClause: *processWhereClause,
|
processWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processWhitelist)),
|
||||||
|
processBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processBlacklist)),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect sends the metric values for each metric
|
type perflibProcess struct {
|
||||||
// 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
|
||||||
CreatingProcessID uint32
|
PercentProcessorTime float64 `perflib:"% Processor Time"`
|
||||||
ElapsedTime uint64
|
PercentPrivilegedTime float64 `perflib:"% Privileged Time"`
|
||||||
Frequency_Object uint64
|
PercentUserTime float64 `perflib:"% User Time"`
|
||||||
HandleCount uint32
|
CreatingProcessID float64 `perflib:"Creating Process ID"`
|
||||||
IDProcess uint32
|
ElapsedTime float64 `perflib:"Elapsed Time"`
|
||||||
IODataBytesPersec uint64
|
HandleCount float64 `perflib:"Handle Count"`
|
||||||
IODataOperationsPersec uint64
|
IDProcess float64 `perflib:"ID Process"`
|
||||||
IOOtherBytesPersec uint64
|
IODataBytesPerSec float64 `perflib:"IO Data Bytes/sec"`
|
||||||
IOOtherOperationsPersec uint64
|
IODataOperationsPerSec float64 `perflib:"IO Data Operations/sec"`
|
||||||
IOReadBytesPersec uint64
|
IOOtherBytesPerSec float64 `perflib:"IO Other Bytes/sec"`
|
||||||
IOReadOperationsPersec uint64
|
IOOtherOperationsPerSec float64 `perflib:"IO Other Operations/sec"`
|
||||||
IOWriteBytesPersec uint64
|
IOReadBytesPerSec float64 `perflib:"IO Read Bytes/sec"`
|
||||||
IOWriteOperationsPersec uint64
|
IOReadOperationsPerSec float64 `perflib:"IO Read Operations/sec"`
|
||||||
PageFaultsPersec uint32
|
IOWriteBytesPerSec float64 `perflib:"IO Write Bytes/sec"`
|
||||||
PageFileBytes uint64
|
IOWriteOperationsPerSec float64 `perflib:"IO Write Operations/sec"`
|
||||||
PageFileBytesPeak uint64
|
PageFaultsPerSec float64 `perflib:"Page Faults/sec"`
|
||||||
PercentPrivilegedTime uint64
|
PageFileBytesPeak float64 `perflib:"Page File Bytes Peak"`
|
||||||
PercentProcessorTime uint64
|
PageFileBytes float64 `perflib:"Page File Bytes"`
|
||||||
PercentUserTime uint64
|
PoolNonpagedBytes float64 `perflib:"Pool Nonpaged Bytes"`
|
||||||
PoolNonpagedBytes uint32
|
PoolPagedBytes float64 `perflib:"Pool Paged Bytes"`
|
||||||
PoolPagedBytes uint32
|
PriorityBase float64 `perflib:"Priority Base"`
|
||||||
PriorityBase uint32
|
PrivateBytes float64 `perflib:"Private Bytes"`
|
||||||
PrivateBytes uint64
|
ThreadCount float64 `perflib:"Thread Count"`
|
||||||
ThreadCount uint32
|
VirtualBytesPeak float64 `perflib:"Virtual Bytes Peak"`
|
||||||
Timestamp_Object uint64
|
VirtualBytes float64 `perflib:"Virtual Bytes"`
|
||||||
VirtualBytes uint64
|
WorkingSetPrivate float64 `perflib:"Working Set - Private"`
|
||||||
VirtualBytesPeak uint64
|
WorkingSetPeak float64 `perflib:"Working Set Peak"`
|
||||||
WorkingSet uint64
|
WorkingSet float64 `perflib:"Working Set"`
|
||||||
WorkingSetPeak uint64
|
|
||||||
WorkingSetPrivate uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type WorkerProcess struct {
|
type WorkerProcess struct {
|
||||||
AppPoolName string
|
AppPoolName string
|
||||||
ProcessId uint32
|
ProcessId uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_PerfProc_Process
|
data := make([]perflibProcess, 0)
|
||||||
q := queryAllWhere(&dst, c.queryWhereClause)
|
err := unmarshalObject(ctx.perfObjects["Process"], &data)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var dst_wp []WorkerProcess
|
var dst_wp []WorkerProcess
|
||||||
@@ -197,9 +190,10 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
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 dst {
|
for _, process := range data {
|
||||||
|
if process.Name == "_Total" ||
|
||||||
if process.Name == "_Total" {
|
c.processBlacklistPattern.MatchString(process.Name) ||
|
||||||
|
!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.
|
||||||
@@ -208,7 +202,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
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 == process.IDProcess {
|
if wp.ProcessId == uint64(process.IDProcess) {
|
||||||
processName = strings.Join([]string{processName, wp.AppPoolName}, "_")
|
processName = strings.Join([]string{processName, wp.AppPoolName}, "_")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -217,8 +211,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.StartTime,
|
c.StartTime,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
// convert from Windows timestamp (1 jan 1601) to unix timestamp (1 jan 1970)
|
process.ElapsedTime,
|
||||||
float64(process.ElapsedTime-116444736000000000)/float64(process.Frequency_Object),
|
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -227,7 +220,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.HandleCount,
|
c.HandleCount,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(process.HandleCount),
|
process.HandleCount,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -236,7 +229,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CPUTimeTotal,
|
c.CPUTimeTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(process.PercentPrivilegedTime)*ticksToSecondsScaleFactor,
|
process.PercentPrivilegedTime,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -246,7 +239,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CPUTimeTotal,
|
c.CPUTimeTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(process.PercentUserTime)*ticksToSecondsScaleFactor,
|
process.PercentUserTime,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -256,7 +249,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOBytesTotal,
|
c.IOBytesTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(process.IOOtherBytesPersec),
|
process.IOOtherBytesPerSec,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -266,7 +259,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOOperationsTotal,
|
c.IOOperationsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(process.IOOtherOperationsPersec),
|
process.IOOtherOperationsPerSec,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -276,7 +269,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOBytesTotal,
|
c.IOBytesTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(process.IOReadBytesPersec),
|
process.IOReadBytesPerSec,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -286,7 +279,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOOperationsTotal,
|
c.IOOperationsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(process.IOReadOperationsPersec),
|
process.IOReadOperationsPerSec,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -296,7 +289,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOBytesTotal,
|
c.IOBytesTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(process.IOWriteBytesPersec),
|
process.IOWriteBytesPerSec,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -306,7 +299,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOOperationsTotal,
|
c.IOOperationsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(process.IOWriteOperationsPersec),
|
process.IOWriteOperationsPerSec,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -316,7 +309,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PageFaultsTotal,
|
c.PageFaultsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
float64(process.PageFaultsPersec),
|
process.PageFaultsPerSec,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -325,7 +318,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PageFileBytes,
|
c.PageFileBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(process.PageFileBytes),
|
process.PageFileBytes,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -334,7 +327,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PoolBytes,
|
c.PoolBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(process.PoolNonpagedBytes),
|
process.PoolNonpagedBytes,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -344,7 +337,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PoolBytes,
|
c.PoolBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(process.PoolPagedBytes),
|
process.PoolPagedBytes,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -354,7 +347,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PriorityBase,
|
c.PriorityBase,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(process.PriorityBase),
|
process.PriorityBase,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -363,7 +356,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PrivateBytes,
|
c.PrivateBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(process.PrivateBytes),
|
process.PrivateBytes,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -372,7 +365,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.ThreadCount,
|
c.ThreadCount,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(process.ThreadCount),
|
process.ThreadCount,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -381,7 +374,7 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.VirtualBytes,
|
c.VirtualBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(process.VirtualBytes),
|
process.VirtualBytes,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
@@ -390,12 +383,12 @@ func (c *ProcessCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.WorkingSet,
|
c.WorkingSet,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(process.WorkingSet),
|
process.WorkingSet,
|
||||||
processName,
|
processName,
|
||||||
pid,
|
pid,
|
||||||
cpid,
|
cpid,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,37 @@ The process collector exposes metrics about processes
|
|||||||
|||
|
|||
|
||||||
-|-
|
-|-
|
||||||
Metric name prefix | `process`
|
Metric name prefix | `process`
|
||||||
Classes | [`Win32_PerfRawData_PerfProc_Process`](https://msdn.microsoft.com/en-us/library/aa394323(v=vs.85).aspx)
|
Data source | Perflib
|
||||||
|
Counters | `Process`
|
||||||
Enabled by default? | No
|
Enabled by default? | No
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
### `--collector.process.processes-where`
|
### `--collector.process.whitelist`
|
||||||
|
|
||||||
A WMI filter on which processes to include. Recommended to keep down number of returned metrics.
|
Regexp of processes to include. Process name must both match whitelist and not
|
||||||
|
match blacklist to be included. Recommended to keep down number of returned
|
||||||
|
metrics.
|
||||||
|
|
||||||
`%` is a wildcard, and can be used to match on substrings.
|
### `--collector.process.blacklist`
|
||||||
|
|
||||||
Example: `--collector.process.processes-where="Name LIKE 'firefox%'`
|
Regexp of processes to exclude. Process name must both match whitelist and not
|
||||||
|
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](https://en.wikipedia.org/wiki/Regular_expression) must take
|
||||||
|
these suffixes into consideration.
|
||||||
|
|
||||||
|
:warning: The regexp is case-sensitive, so `--collector.process.whitelist="FIREFOX.+"` will **NOT** match a process named `firefox` .
|
||||||
|
|
||||||
|
To specify multiple names, use the pipe `|` character:
|
||||||
|
```
|
||||||
|
--collector.process.whitelist="firefox.+|FIREFOX.+|chrome.+"
|
||||||
|
```
|
||||||
|
This will match all processes named `firefox`, `FIREFOX` or `chrome` .
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
||||||
|
|||||||
33
exporter.go
33
exporter.go
@@ -265,6 +265,10 @@ 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.").
|
||||||
@@ -332,10 +336,16 @@ func main() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Handle(*metricsPath, h)
|
http.HandleFunc(*metricsPath, withConcurrencyLimit(*maxRequests, h.ServeHTTP))
|
||||||
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) {
|
||||||
http.Redirect(w, r, *metricsPath, http.StatusMovedPermanently)
|
_, _ = w.Write([]byte(`<html>
|
||||||
|
<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())
|
||||||
@@ -370,6 +380,25 @@ 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