Compare commits

..

21 Commits

Author SHA1 Message Date
Teriand
6b98771187 Add MSMQ collector (#159)
Add MSMQ collector
2018-02-14 12:24:52 +01:00
Jorrit Salverda
a52df7696a Add TCP collector (#142)
add tcp collector to get tcp connection usage stats from Win32_PerfRawData_Tcpip_TCPv4
2017-12-20 14:26:30 +01:00
Yuriy Revich
105a1c866b fix: IIS Collector fails, when Application has more than one worker processes (#132)
* fix collecting error with multiple IIS application worker processes
2017-11-13 10:41:35 +01:00
Calle Pettersson
69c1d0faad Merge pull request #128 from gboucher90/master
Add .Net Performance counters
2017-11-07 07:46:47 +01:00
Guillaume Boucher
809fe9becf Add .Net Performance counters 2017-11-06 23:04:13 -05:00
Calle Pettersson
7b6974e595 Merge pull request #120 from martinlindhe/promu-binary-name
Add build.binary to promu config
2017-09-08 11:15:37 +02:00
Calle Pettersson
caf8742dcd Fix promu build 2017-09-08 09:38:33 +01:00
Martin Lindhe
94caf8ee61 correct help message, fixes #118. typo was introduced in a66f0b5475 2017-09-07 14:28:27 +02:00
Calle Pettersson
2f7a372429 Fix "no where-clause" warning in service collector 2017-08-11 17:38:06 +02:00
Calle Pettersson
e547c13716 Merge pull request #107 from martinlindhe/doc-process
README: add an example for -collector.process.processes-where, fixes #105
2017-08-11 12:55:34 +02:00
vbeausoleil
44c39405c7 Added flag to filter services (like the one for processes). Added example for said flag in README.md (#109) 2017-08-11 00:31:39 +02:00
Martin Lindhe
96faedf481 process,iis: fix log call 2017-08-10 03:50:21 +02:00
Martin Lindhe
3cfc11c6d2 ad: fix log call 2017-08-10 03:36:28 +02:00
Martin Lindhe
80f1cf0546 README: update build instructions (#106) 2017-08-10 02:14:06 +02:00
Calle Pettersson
691b672a1e Add DisplayName and Description to Windows service (#100) 2017-08-10 02:13:32 +02:00
Martin Lindhe
7206f020cb README: add an example for -collector.process.processes-where 2017-08-10 02:07:52 +02:00
Martin Lindhe
2e0842573d Makefile: add build command 2017-08-10 01:32:54 +02:00
Calle Pettersson
7537c9896e Add hint in usage about quoting flags in powershell (#95) 2017-07-18 13:18:36 +02:00
Calle Pettersson
88271ddf14 Merge pull request #86 from martinlindhe/iis-wp-and-cache
Implement IIS worker process and server cache classes
2017-07-18 12:52:09 +02:00
Calle Pettersson
f4195aa435 Conditional query for wmi fields added in IIS 8 2017-07-15 13:59:33 +01:00
Calle Pettersson
e8cfeef26c Implement IIS worker process and server cache classes 2017-06-30 20:55:45 +01:00
21 changed files with 2878 additions and 27 deletions

View File

@@ -1,6 +1,8 @@
repository:
path: github.com/martinlindhe/wmi_exporter
build:
binaries:
- name: wmi_exporter
ldflags: |
-X {{repoPath}}/vendor/github.com/prometheus/common/version.Version={{.Version}}
-X {{repoPath}}/vendor/github.com/prometheus/common/version.Revision={{.Revision}}

View File

@@ -1,2 +1,5 @@
fmt:
gofmt -l -w -s .
build:
promu build -v

View File

@@ -16,10 +16,12 @@ dns | [Win32_PerfRawData_DNS_DNS](https://technet.microsoft.com/en-us/library/cc
iis | [Win32_PerfRawData_W3SVC_WebService](https://msdn.microsoft.com/en-us/library/aa394345) IIS metrics |
logical_disk | [Win32_PerfRawData_PerfDisk_LogicalDisk](https://msdn.microsoft.com/en-us/windows/hardware/aa394307(v=vs.71)) metrics (disk I/O) | ✓
net | [Win32_PerfRawData_Tcpip_NetworkInterface](https://technet.microsoft.com/en-us/security/aa394340(v=vs.80)) metrics (network interface I/O) | ✓
msmq | [Win32_PerfRawData_MSMQ_MSMQQueue](http://wutils.com/wmi/root/cimv2/win32_perfrawdata_msmq_msmqqueue/) metrics (MSMQ/journal count) |
os | [Win32_OperatingSystem](https://msdn.microsoft.com/en-us/library/aa394239) metrics (memory, processes, users) | ✓
process | [Win32_PerfRawData_PerfProc_Process](https://msdn.microsoft.com/en-us/library/aa394323(v=vs.85).aspx) metrics (per-process stats) |
service | [Win32_Service](https://msdn.microsoft.com/en-us/library/aa394418(v=vs.85).aspx) metrics (service states) | ✓
system | Win32_PerfRawData_PerfOS_System metrics (system calls) | ✓
tcp | [Win32_PerfRawData_Tcpip_TCPv4](https://msdn.microsoft.com/en-us/library/aa394341(v=vs.85).aspx) metrics (tcp connections) |
vmware | Performance counters installed by the Vmware Guest agent |
The HELP texts shows the WMI data source, please see MSDN documentation for details.
@@ -52,13 +54,30 @@ See [open issues](https://github.com/martinlindhe/wmi_exporter/issues)
## Usage
go get -u github.com/kardianos/govendor
go get -u github.com/prometheus/promu
go get -u github.com/martinlindhe/wmi_exporter
cd $env:GOPATH/src/github.com/martinlindhe/wmi_exporter
govendor build +local
promu build -v .
.\wmi_exporter.exe
The prometheus metrics will be exposed on [localhost:9182](http://localhost:9182)
## Examples
Please note: The quotes in the parameter names are required because of how Powershell parses command line arguments.
### Enable only service collector and specify a custom query
.\wmi_exporter.exe "-collectors.enabled" "service" "-collector.service.services-where" "Name='wmi_exporter'"
## Examples
Please note: The quotes in the parameter names are required because of how Powershell parses command line arguments.
### Enable only process collector and specify a custom query
.\wmi_exporter.exe "-collectors.enabled" "process" "-collector.process.processes-where" "Name='firefox'"
## License

View File

@@ -22,7 +22,7 @@ install:
build_script:
- ps: gitversion /output json /showvariable FullSemVer | Set-Content VERSION -PassThru
- govendor test -v +local
- promu build -v .
- promu build -v
- ps: |
$ErrorActionPreference = "Stop"
if($env:APPVEYOR_REPO_TAG -eq "True") {

View File

@@ -3,9 +3,10 @@
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
)
func init() {
@@ -454,7 +455,7 @@ func NewADCollector() (Collector, error) {
// to the provided prometheus Metric channel.
func (c *ADCollector) Collect(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Errorf("[ERROR] failed collecting ad metrics:", desc, err)
log.Println("[ERROR] failed collecting ad metrics:", desc, err)
return err
}
return nil

File diff suppressed because it is too large Load Diff

132
collector/msmq.go Normal file
View File

@@ -0,0 +1,132 @@
// returns data points from Win32_PerfRawData_MSMQ_MSMQQueue
// <add link to documentation here> - Win32_PerfRawData_MSMQ_MSMQQueue class
package collector
import (
"log"
"flag"
"bytes"
"strings"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["msmq"] = NewMSMQCollector
}
var (
msmqWhereClause = flag.String("collector.msmq.msmq-where", "", "WQL 'where' clause to use in WMI metrics query. Limits the response to the msmqs you specify and reduces the size of the response.")
)
// A Win32_PerfRawData_MSMQ_MSMQQueueCollector is a Prometheus collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics
type Win32_PerfRawData_MSMQ_MSMQQueueCollector struct {
BytesinJournalQueue *prometheus.Desc
BytesinQueue *prometheus.Desc
MessagesinJournalQueue *prometheus.Desc
MessagesinQueue *prometheus.Desc
queryWhereClause string
}
// NewWin32_PerfRawData_MSMQ_MSMQQueueCollector ...
func NewMSMQCollector() (Collector, error) {
const subsystem = "msmq"
var wc bytes.Buffer
if *msmqWhereClause != "" {
wc.WriteString("WHERE ")
wc.WriteString(*msmqWhereClause)
log.Println("warning: No where-clause specified for msmq collector. This will generate a very large number of metrics!")
}
// else {
// log.Println("warning: No where-clause specified for msmq collector. This will generate a very large number of metrics!")
// }
return &Win32_PerfRawData_MSMQ_MSMQQueueCollector{
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: wc.String(),
}, nil
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Win32_PerfRawData_MSMQ_MSMQQueueCollector) Collect(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting msmq metrics:", desc, 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 := wmi.CreateQuery(&dst, c.queryWhereClause)
if err := wmi.Query(q, &dst); err != nil {
return nil, err
}
for _, msmq := range dst {
if msmq.Name == "Computer Queues" {
continue
}
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
}

View File

@@ -0,0 +1,118 @@
// returns data points from Win32_PerfRawData_NETFramework_NETCLRExceptions
// <add link to documentation here> - Win32_PerfRawData_NETFramework_NETCLRExceptions class
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["netframework_clrexceptions"] = NewNETFramework_NETCLRExceptionsCollector
}
// A NETFramework_NETCLRExceptionsCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRExceptions metrics
type NETFramework_NETCLRExceptionsCollector struct {
NumberofExcepsThrown *prometheus.Desc
NumberofFilters *prometheus.Desc
NumberofFinallys *prometheus.Desc
ThrowToCatchDepth *prometheus.Desc
}
// NewNETFramework_NETCLRExceptionsCollector ...
func NewNETFramework_NETCLRExceptionsCollector() (Collector, error) {
const subsystem = "netframework_clrexceptions"
return &NETFramework_NETCLRExceptionsCollector{
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(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting win32_perfrawdata_netframework_netclrexceptions metrics:", desc, 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 := wmi.CreateQuery(&dst, "")
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
}

View File

@@ -0,0 +1,104 @@
// returns data points from Win32_PerfRawData_NETFramework_NETCLRInterop
// <add link to documentation here> - Win32_PerfRawData_NETFramework_NETCLRInterop class
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["netframework_clrinterop"] = NewNETFramework_NETCLRInteropCollector
}
// A NETFramework_NETCLRInteropCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRInterop metrics
type NETFramework_NETCLRInteropCollector struct {
NumberofCCWs *prometheus.Desc
Numberofmarshalling *prometheus.Desc
NumberofStubs *prometheus.Desc
}
// NewNETFramework_NETCLRInteropCollector ...
func NewNETFramework_NETCLRInteropCollector() (Collector, error) {
const subsystem = "netframework_clrinterop"
return &NETFramework_NETCLRInteropCollector{
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(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting win32_perfrawdata_netframework_netclrinterop metrics:", desc, 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 := wmi.CreateQuery(&dst, "")
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
}

View File

@@ -0,0 +1,120 @@
// returns data points from Win32_PerfRawData_NETFramework_NETCLRJit
// <add link to documentation here> - Win32_PerfRawData_NETFramework_NETCLRJit class
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["netframework_clrjit"] = NewNETFramework_NETCLRJitCollector
}
// A NETFramework_NETCLRJitCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRJit metrics
type NETFramework_NETCLRJitCollector struct {
NumberofMethodsJitted *prometheus.Desc
TimeinJit *prometheus.Desc
StandardJitFailures *prometheus.Desc
TotalNumberofILBytesJitted *prometheus.Desc
}
// NewNETFramework_NETCLRJitCollector ...
func NewNETFramework_NETCLRJitCollector() (Collector, error) {
const subsystem = "netframework_clrjit"
return &NETFramework_NETCLRJitCollector{
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(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting win32_perfrawdata_netframework_netclrjit metrics:", desc, 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 := wmi.CreateQuery(&dst, "")
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
}

View File

@@ -0,0 +1,199 @@
// returns data points from Win32_PerfRawData_NETFramework_NETCLRLoading
// <add link to documentation here> - Win32_PerfRawData_NETFramework_NETCLRLoading class
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["netframework_clrloading"] = NewNETFramework_NETCLRLoadingCollector
}
// A NETFramework_NETCLRLoadingCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRLoading metrics
type NETFramework_NETCLRLoadingCollector struct {
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() (Collector, error) {
const subsystem = "netframework_clrloading"
return &NETFramework_NETCLRLoadingCollector{
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(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting win32_perfrawdata_netframework_netclrloading metrics:", desc, 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 := wmi.CreateQuery(&dst, "")
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
}

View File

@@ -0,0 +1,165 @@
// returns data points from Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads
// <add link to documentation here> - Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads class
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["netframework_clrlocksandthreads"] = NewNETFramework_NETCLRLocksAndThreadsCollector
}
// A NETFramework_NETCLRLocksAndThreadsCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads metrics
type NETFramework_NETCLRLocksAndThreadsCollector struct {
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() (Collector, error) {
const subsystem = "netframework_clrlocksandthreads"
return &NETFramework_NETCLRLocksAndThreadsCollector{
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(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting win32_perfrawdata_netframework_netclrlocksandthreads metrics:", desc, 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 := wmi.CreateQuery(&dst, "")
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
}

View File

@@ -0,0 +1,303 @@
// returns data points from Win32_PerfRawData_NETFramework_NETCLRMemory
// <add link to documentation here> - Win32_PerfRawData_NETFramework_NETCLRMemory class
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["netframework_clrmemory"] = NewNETFramework_NETCLRMemoryCollector
}
// A NETFramework_NETCLRMemoryCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRMemory metrics
type NETFramework_NETCLRMemoryCollector struct {
AllocatedBytes *prometheus.Desc
FinalizationSurvivors *prometheus.Desc
HeapSize *prometheus.Desc
PromotedBytes *prometheus.Desc
NumberGCHandles *prometheus.Desc
NumberCollections *prometheus.Desc
NumberInducedGC *prometheus.Desc
NumberofPinnedObjects *prometheus.Desc
NumberofSinkBlocksinuse *prometheus.Desc
NumberTotalCommittedBytes *prometheus.Desc
NumberTotalreservedBytes *prometheus.Desc
TimeinGC *prometheus.Desc
PromotedFinalizationMemoryfromGen0 *prometheus.Desc
PromotedMemoryfromGen0 *prometheus.Desc
PromotedMemoryfromGen1 *prometheus.Desc
}
// NewNETFramework_NETCLRMemoryCollector ...
func NewNETFramework_NETCLRMemoryCollector() (Collector, error) {
const subsystem = "netframework_clrmemory"
return &NETFramework_NETCLRMemoryCollector{
AllocatedBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "allocated_bytes_total"),
"Displays the total number of bytes allocated on the garbage collection heap.",
[]string{"process"},
nil,
),
FinalizationSurvivors: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "finalization_survivors"),
"Displays the number of garbage-collected objects that survive a collection because they are waiting to be finalized.",
[]string{"process"},
nil,
),
HeapSize: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "heap_size_bytes"),
"Displays the maximum bytes that can be allocated; it does not indicate the current number of bytes allocated.",
[]string{"process", "area"},
nil,
),
PromotedBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "promoted_bytes"),
"Displays the bytes that were promoted from the generation to the next one during the last GC. Memory is promoted when it survives a garbage collection.",
[]string{"process", "area"},
nil,
),
NumberGCHandles: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "number_gc_handles"),
"Displays the current number of garbage collection handles in use. Garbage collection handles are handles to resources external to the common language runtime and the managed environment.",
[]string{"process"},
nil,
),
NumberCollections: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "collections_total"),
"Displays the number of times the generation objects are garbage collected since the application started.",
[]string{"process", "area"},
nil,
),
NumberInducedGC: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "induced_gc_total"),
"Displays the peak number of times garbage collection was performed because of an explicit call to GC.Collect.",
[]string{"process"},
nil,
),
NumberofPinnedObjects: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "number_pinned_objects"),
"Displays the number of pinned objects encountered in the last garbage collection.",
[]string{"process"},
nil,
),
NumberofSinkBlocksinuse: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "number_sink_blocksinuse"),
"Displays the current number of synchronization blocks in use. Synchronization blocks are per-object data structures allocated for storing synchronization information. They hold weak references to managed objects and must be scanned by the garbage collector.",
[]string{"process"},
nil,
),
NumberTotalCommittedBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "committed_bytes"),
"Displays the amount of virtual memory, in bytes, currently committed by the garbage collector. Committed memory is the physical memory for which space has been reserved in the disk paging file.",
[]string{"process"},
nil,
),
NumberTotalreservedBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "reserved_bytes"),
"Displays the amount of virtual memory, in bytes, currently reserved by the garbage collector. Reserved memory is the virtual memory space reserved for the application when no disk or main memory pages have been used.",
[]string{"process"},
nil,
),
TimeinGC: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "gc_time_percent"),
"Displays the percentage of time that was spent performing a garbage collection in the last sample.",
[]string{"process"},
nil,
),
}, nil
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *NETFramework_NETCLRMemoryCollector) Collect(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting win32_perfrawdata_netframework_netclrmemory metrics:", desc, err)
return err
}
return nil
}
type Win32_PerfRawData_NETFramework_NETCLRMemory struct {
Name string
AllocatedBytesPersec uint64
FinalizationSurvivors uint64
Frequency_PerfTime uint64
Gen0heapsize uint64
Gen0PromotedBytesPerSec uint64
Gen1heapsize uint64
Gen1PromotedBytesPerSec uint64
Gen2heapsize uint64
LargeObjectHeapsize uint64
NumberBytesinallHeaps uint64
NumberGCHandles uint64
NumberGen0Collections uint64
NumberGen1Collections uint64
NumberGen2Collections uint64
NumberInducedGC uint64
NumberofPinnedObjects uint64
NumberofSinkBlocksinuse uint64
NumberTotalcommittedBytes uint64
NumberTotalreservedBytes uint64
PercentTimeinGC uint32
ProcessID uint64
PromotedFinalizationMemoryfromGen0 uint64
PromotedMemoryfromGen0 uint64
PromotedMemoryfromGen1 uint64
}
func (c *NETFramework_NETCLRMemoryCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
var dst []Win32_PerfRawData_NETFramework_NETCLRMemory
q := wmi.CreateQuery(&dst, "")
if err := wmi.Query(q, &dst); err != nil {
return nil, err
}
for _, process := range dst {
if process.Name == "_Global_" {
continue
}
ch <- prometheus.MustNewConstMetric(
c.AllocatedBytes,
prometheus.CounterValue,
float64(process.AllocatedBytesPersec),
process.Name,
)
ch <- prometheus.MustNewConstMetric(
c.FinalizationSurvivors,
prometheus.GaugeValue,
float64(process.FinalizationSurvivors),
process.Name,
)
ch <- prometheus.MustNewConstMetric(
c.HeapSize,
prometheus.GaugeValue,
float64(process.Gen0heapsize),
process.Name,
"Gen0",
)
ch <- prometheus.MustNewConstMetric(
c.PromotedBytes,
prometheus.GaugeValue,
float64(process.Gen0PromotedBytesPerSec),
process.Name,
"Gen0",
)
ch <- prometheus.MustNewConstMetric(
c.HeapSize,
prometheus.GaugeValue,
float64(process.Gen1heapsize),
process.Name,
"Gen1",
)
ch <- prometheus.MustNewConstMetric(
c.PromotedBytes,
prometheus.GaugeValue,
float64(process.Gen1PromotedBytesPerSec),
process.Name,
"Gen1",
)
ch <- prometheus.MustNewConstMetric(
c.HeapSize,
prometheus.GaugeValue,
float64(process.Gen2heapsize),
process.Name,
"Gen2",
)
ch <- prometheus.MustNewConstMetric(
c.HeapSize,
prometheus.GaugeValue,
float64(process.LargeObjectHeapsize),
process.Name,
"LOH",
)
ch <- prometheus.MustNewConstMetric(
c.NumberGCHandles,
prometheus.GaugeValue,
float64(process.NumberGCHandles),
process.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NumberCollections,
prometheus.CounterValue,
float64(process.NumberGen0Collections),
process.Name,
"Gen0",
)
ch <- prometheus.MustNewConstMetric(
c.NumberCollections,
prometheus.CounterValue,
float64(process.NumberGen1Collections),
process.Name,
"Gen1",
)
ch <- prometheus.MustNewConstMetric(
c.NumberCollections,
prometheus.CounterValue,
float64(process.NumberGen2Collections),
process.Name,
"Gen2",
)
ch <- prometheus.MustNewConstMetric(
c.NumberInducedGC,
prometheus.CounterValue,
float64(process.NumberInducedGC),
process.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NumberofPinnedObjects,
prometheus.GaugeValue,
float64(process.NumberofPinnedObjects),
process.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NumberofSinkBlocksinuse,
prometheus.GaugeValue,
float64(process.NumberofSinkBlocksinuse),
process.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NumberTotalCommittedBytes,
prometheus.GaugeValue,
float64(process.NumberTotalcommittedBytes),
process.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NumberTotalreservedBytes,
prometheus.GaugeValue,
float64(process.NumberTotalreservedBytes),
process.Name,
)
ch <- prometheus.MustNewConstMetric(
c.TimeinGC,
prometheus.GaugeValue,
float64(process.PercentTimeinGC)/float64(process.Frequency_PerfTime),
process.Name,
)
}
return nil, nil
}

View File

@@ -0,0 +1,148 @@
// returns data points from Win32_PerfRawData_NETFramework_NETCLRRemoting
// <add link to documentation here> - Win32_PerfRawData_NETFramework_NETCLRRemoting class
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["netframework_clrremoting"] = NewNETFramework_NETCLRRemotingCollector
}
// A NETFramework_NETCLRRemotingCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRRemoting metrics
type NETFramework_NETCLRRemotingCollector struct {
Channels *prometheus.Desc
ContextBoundClassesLoaded *prometheus.Desc
ContextBoundObjects *prometheus.Desc
ContextProxies *prometheus.Desc
Contexts *prometheus.Desc
TotalRemoteCalls *prometheus.Desc
}
// NewNETFramework_NETCLRRemotingCollector ...
func NewNETFramework_NETCLRRemotingCollector() (Collector, error) {
const subsystem = "netframework_clrremoting"
return &NETFramework_NETCLRRemotingCollector{
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(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting win32_perfrawdata_netframework_netclrremoting metrics:", desc, 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 := wmi.CreateQuery(&dst, "")
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
}

View File

@@ -0,0 +1,119 @@
// returns data points from Win32_PerfRawData_NETFramework_NETCLRSecurity
// <add link to documentation here> - Win32_PerfRawData_NETFramework_NETCLRSecurity class
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["netframework_clrsecurity"] = NewNETFramework_NETCLRSecurityCollector
}
// A NETFramework_NETCLRSecurityCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRSecurity metrics
type NETFramework_NETCLRSecurityCollector struct {
NumberLinkTimeChecks *prometheus.Desc
TimeinRTchecks *prometheus.Desc
StackWalkDepth *prometheus.Desc
TotalRuntimeChecks *prometheus.Desc
}
// NewNETFramework_NETCLRSecurityCollector ...
func NewNETFramework_NETCLRSecurityCollector() (Collector, error) {
const subsystem = "netframework_clrsecurity"
return &NETFramework_NETCLRSecurityCollector{
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(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting win32_perfrawdata_netframework_netclrsecurity metrics:", desc, 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 := wmi.CreateQuery(&dst, "")
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
}

View File

@@ -5,12 +5,12 @@ package collector
import (
"bytes"
"flag"
"log"
"strconv"
"strings"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
)
func init() {
@@ -49,7 +49,7 @@ func NewProcessCollector() (Collector, error) {
wc.WriteString("WHERE ")
wc.WriteString(*processWhereClause)
} else {
log.Warn("No where-clause specified for process collector. This will generate a very large number of metrics!")
log.Println("warning: No where-clause specified for process collector. This will generate a very large number of metrics!")
}
return &ProcessCollector{
@@ -139,7 +139,7 @@ func NewProcessCollector() (Collector, error) {
// to the provided prometheus Metric channel.
func (c *ProcessCollector) Collect(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Errorln("[ERROR] failed collecting process metrics:", desc, err)
log.Println("[ERROR] failed collecting process metrics:", desc, err)
return err
}
return nil

View File

@@ -3,6 +3,8 @@
package collector
import (
"bytes"
"flag"
"log"
"strings"
@@ -14,15 +16,30 @@ func init() {
Factories["service"] = NewserviceCollector
}
var (
serviceWhereClause = flag.String("collector.service.services-where", "", "WQL 'where' clause to use in WMI metrics query. Limits the response to the services you specify and reduces the size of the response.")
)
// A serviceCollector is a Prometheus collector for WMI Win32_Service metrics
type serviceCollector struct {
State *prometheus.Desc
StartMode *prometheus.Desc
queryWhereClause string
}
// NewserviceCollector ...
func NewserviceCollector() (Collector, error) {
const subsystem = "service"
var wc bytes.Buffer
if *serviceWhereClause != "" {
wc.WriteString("WHERE ")
wc.WriteString(*serviceWhereClause)
} else {
log.Println("warning: No where-clause specified for service collector. This will generate a very large number of metrics!")
}
return &serviceCollector{
State: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "state"),
@@ -36,6 +53,7 @@ func NewserviceCollector() (Collector, error) {
[]string{"name", "start_mode"},
nil,
),
queryWhereClause: wc.String(),
}, nil
}
@@ -77,7 +95,7 @@ var (
func (c *serviceCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
var dst []Win32_Service
q := wmi.CreateQuery(&dst, "")
q := wmi.CreateQuery(&dst, c.queryWhereClause)
if err := wmi.Query(q, &dst); err != nil {
return nil, err
}

171
collector/tcp.go Normal file
View File

@@ -0,0 +1,171 @@
// returns data points from Win32_PerfRawData_Tcpip_TCPv4
// https://msdn.microsoft.com/en-us/library/aa394341(v=vs.85).aspx (Win32_PerfRawData_Tcpip_TCPv4 class)
package collector
import (
"log"
"github.com/StackExchange/wmi"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
Factories["tcp"] = NewTCPCollector
}
// A TCPCollector is a Prometheus collector for WMI Win32_PerfRawData_Tcpip_TCPv4 metrics
type TCPCollector struct {
ConnectionFailures *prometheus.Desc
ConnectionsActive *prometheus.Desc
ConnectionsEstablished *prometheus.Desc
ConnectionsPassive *prometheus.Desc
ConnectionsReset *prometheus.Desc
SegmentsTotal *prometheus.Desc
SegmentsReceivedTotal *prometheus.Desc
SegmentsRetransmittedTotal *prometheus.Desc
SegmentsSentTotal *prometheus.Desc
}
// NewTCPCollector ...
func NewTCPCollector() (Collector, error) {
const subsystem = "tcp"
return &TCPCollector{
ConnectionFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "connection_failures"),
"(TCP.ConnectionFailures)",
nil,
nil,
),
ConnectionsActive: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "connections_active"),
"(TCP.ConnectionsActive)",
nil,
nil,
),
ConnectionsEstablished: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "connections_established"),
"(TCP.ConnectionsEstablished)",
nil,
nil,
),
ConnectionsPassive: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "connections_passive"),
"(TCP.ConnectionsPassive)",
nil,
nil,
),
ConnectionsReset: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "connections_reset"),
"(TCP.ConnectionsReset)",
nil,
nil,
),
SegmentsTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "segments_total"),
"(TCP.SegmentsTotal)",
nil,
nil,
),
SegmentsReceivedTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "segments_received_total"),
"(TCP.SegmentsReceivedTotal)",
nil,
nil,
),
SegmentsRetransmittedTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "segments_retransmitted_total"),
"(TCP.SegmentsRetransmittedTotal)",
nil,
nil,
),
SegmentsSentTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "segments_sent_total"),
"(TCP.SegmentsSentTotal)",
nil,
nil,
),
}, nil
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *TCPCollector) Collect(ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Println("[ERROR] failed collecting tcp metrics:", desc, err)
return err
}
return nil
}
type Win32_PerfRawData_Tcpip_TCPv4 struct {
ConnectionFailures uint64
ConnectionsActive uint64
ConnectionsEstablished uint64
ConnectionsPassive uint64
ConnectionsReset uint64
SegmentsPersec uint64
SegmentsReceivedPersec uint64
SegmentsRetransmittedPersec uint64
SegmentsSentPersec uint64
}
func (c *TCPCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
var dst []Win32_PerfRawData_Tcpip_TCPv4
q := wmi.CreateQuery(&dst, "")
if err := wmi.Query(q, &dst); err != nil {
return nil, err
}
// Counters
ch <- prometheus.MustNewConstMetric(
c.ConnectionFailures,
prometheus.CounterValue,
float64(dst[0].ConnectionFailures),
)
ch <- prometheus.MustNewConstMetric(
c.ConnectionsActive,
prometheus.CounterValue,
float64(dst[0].ConnectionsActive),
)
ch <- prometheus.MustNewConstMetric(
c.ConnectionsEstablished,
prometheus.CounterValue,
float64(dst[0].ConnectionsEstablished),
)
ch <- prometheus.MustNewConstMetric(
c.ConnectionsPassive,
prometheus.CounterValue,
float64(dst[0].ConnectionsPassive),
)
ch <- prometheus.MustNewConstMetric(
c.ConnectionsReset,
prometheus.CounterValue,
float64(dst[0].ConnectionsReset),
)
ch <- prometheus.MustNewConstMetric(
c.SegmentsTotal,
prometheus.CounterValue,
float64(dst[0].SegmentsPersec),
)
ch <- prometheus.MustNewConstMetric(
c.SegmentsReceivedTotal,
prometheus.CounterValue,
float64(dst[0].SegmentsReceivedPersec),
)
ch <- prometheus.MustNewConstMetric(
c.SegmentsRetransmittedTotal,
prometheus.CounterValue,
float64(dst[0].SegmentsRetransmittedPersec),
)
ch <- prometheus.MustNewConstMetric(
c.SegmentsSentTotal,
prometheus.CounterValue,
float64(dst[0].SegmentsSentPersec),
)
return nil, nil
}

View File

@@ -1,6 +1,12 @@
package collector
import "github.com/prometheus/client_golang/prometheus"
import (
"bytes"
"reflect"
"strings"
"github.com/prometheus/client_golang/prometheus"
)
// ...
const (
@@ -18,3 +24,30 @@ type Collector interface {
// Get new metrics and expose them via prometheus registry.
Collect(ch chan<- prometheus.Metric) (err error)
}
// This is adapted from StackExchange/wmi/wmi.go, and lets us change the class
// name being queried for:
// CreateQuery returns a WQL query string that queries all columns of src. where
// is an optional string that is appended to the query, to be used with WHERE
// clauses. In such a case, the "WHERE" string should appear at the beginning.
func createQuery(src interface{}, class, where string) string {
var b bytes.Buffer
b.WriteString("SELECT ")
s := reflect.Indirect(reflect.ValueOf(src))
t := s.Type()
if s.Kind() == reflect.Slice {
t = t.Elem()
}
if t.Kind() != reflect.Struct {
return ""
}
var fields []string
for i := 0; i < t.NumField(); i++ {
fields = append(fields, t.Field(i).Name)
}
b.WriteString(strings.Join(fields, ", "))
b.WriteString(" FROM ")
b.WriteString(class)
b.WriteString(" " + where)
return b.String()
}

View File

@@ -157,14 +157,22 @@ func initWbem() {
wmi.DefaultClient.SWbemServicesClient = s
}
func usage() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
flag.PrintDefaults()
fmt.Fprintf(os.Stderr, "\nNote: If executing from Powershell, the flags need to quoted. For example:\n%s\n",
"\twmi_exporter \"-collectors.enabled\" iis")
}
func main() {
var (
showVersion = flag.Bool("version", false, "Print version information.")
listenAddress = flag.String("telemetry.addr", ":9182", "host:port for WMI exporter.")
metricsPath = flag.String("telemetry.path", "/metrics", "URL path for surfacing collected metrics.")
enabledCollectors = flag.String("collectors.enabled", filterAvailableCollectors(defaultCollectors), "Comma-separated list of collectors to use. Use '[default]' as a placeholder for all the collectors enabled by default")
enabledCollectors = flag.String("collectors.enabled", filterAvailableCollectors(defaultCollectors), "Comma-separated list of collectors to use. Use '[defaults]' as a placeholder for all the collectors enabled by default")
printCollectors = flag.Bool("collectors.print", false, "If true, print available collectors and exit.")
)
flag.Usage = usage
flag.Parse()
if *showVersion {

View File

@@ -36,7 +36,7 @@
<File Id="wmi_exporter.exe" Name="wmi_exporter.exe" Source="Work\wmi_exporter.exe" KeyPath="yes">
<fw:FirewallException Id="MetricsEndpoint" Name="WMI Exporter (HTTP [LISTEN_PORT])" Description="WMI Exporter HTTP endpoint" Port="[LISTEN_PORT]" Protocol="tcp" Scope="any" IgnoreFailure="yes" />
</File>
<ServiceInstall Id="InstallExporterService" Name="wmi_exporter" ErrorControl="normal" Start="auto" Type="ownProcess" Arguments="-log.format logger:eventlog?name=wmi_exporter [CollectorsFlag] [ListenFlag] [MetricsPathFlag]" />
<ServiceInstall Id="InstallExporterService" Name="wmi_exporter" DisplayName="WMI exporter" Description="Exports Prometheus metrics from WMI queries" ErrorControl="normal" Start="auto" Type="ownProcess" Arguments="-log.format logger:eventlog?name=wmi_exporter [CollectorsFlag] [ListenFlag] [MetricsPathFlag]" />
<ServiceControl Id="ServiceStateControl" Name="wmi_exporter" Remove="uninstall" Start="install" Stop="both" />
</Component>
</ComponentGroup>