mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-08 05:56:37 +00:00
Compare commits
143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05091643c6 | ||
|
|
76e73487e4 | ||
|
|
9a2ec21278 | ||
|
|
44b435e7d4 | ||
|
|
f068cf4523 | ||
|
|
9adefdceeb | ||
|
|
be9d2872a5 | ||
|
|
89cb5439b8 | ||
|
|
b08ce0697c | ||
|
|
279a8fce89 | ||
|
|
11ec45e710 | ||
|
|
6797126e78 | ||
|
|
19794ad2e0 | ||
|
|
9e59bf920f | ||
|
|
11218a95d0 | ||
|
|
9b5bc37a42 | ||
|
|
9ef897e07b | ||
|
|
3a61935273 | ||
|
|
8b9c9a5bd2 | ||
|
|
976e055252 | ||
|
|
9e368d49e7 | ||
|
|
ad1ab35399 | ||
|
|
81745eeedf | ||
|
|
fff737998d | ||
|
|
4ea61a2641 | ||
|
|
750225775b | ||
|
|
80cf16efe8 | ||
|
|
f96c6654be | ||
|
|
10e42d3583 | ||
|
|
95f250ed39 | ||
|
|
7115c9dc22 | ||
|
|
478eaa91d9 | ||
|
|
217b670272 | ||
|
|
d5e8a0ed7e | ||
|
|
8b74c77663 | ||
|
|
4077290659 | ||
|
|
014153a503 | ||
|
|
cfb0111d8c | ||
|
|
5d96a42382 | ||
|
|
6890f391d4 | ||
|
|
4350587141 | ||
|
|
8509bc69a6 | ||
|
|
e0e31254e2 | ||
|
|
c633aadc71 | ||
|
|
809424f851 | ||
|
|
88d518378c | ||
|
|
8cfd6bbcf1 | ||
|
|
4ba2fe7f22 | ||
|
|
a49a0fc612 | ||
|
|
23722ae792 | ||
|
|
731b996767 | ||
|
|
2fe869f1db | ||
|
|
6ba0297aa9 | ||
|
|
dc3e172056 | ||
|
|
4327eb386a | ||
|
|
79f4cf5dec | ||
|
|
5aae5054e6 | ||
|
|
e81231d403 | ||
|
|
0e0d0f8fd8 | ||
|
|
c1e829dbd5 | ||
|
|
434788a90a | ||
|
|
6c06beca1d | ||
|
|
486b4319c7 | ||
|
|
88847204ff | ||
|
|
79781c6d75 | ||
|
|
4cd095798d | ||
|
|
1d3af58305 | ||
|
|
b431ff6ac3 | ||
|
|
579369dbf5 | ||
|
|
f19fa777c3 | ||
|
|
0db55044e8 | ||
|
|
352492ea97 | ||
|
|
76c435d12c | ||
|
|
fab77d9d31 | ||
|
|
3627520559 | ||
|
|
b033ff71ff | ||
|
|
8d781cf540 | ||
|
|
da6898afc4 | ||
|
|
a105e088b3 | ||
|
|
30955eae17 | ||
|
|
d7b08d7ce0 | ||
|
|
05abe04d90 | ||
|
|
bacd040b17 | ||
|
|
1df91ba769 | ||
|
|
4e02053f13 | ||
|
|
535f041423 | ||
|
|
49afc93d93 | ||
|
|
04257a1b25 | ||
|
|
9214a87d0d | ||
|
|
8132083892 | ||
|
|
890fac507e | ||
|
|
b29434c7c0 | ||
|
|
7e293a4230 | ||
|
|
e21407c112 | ||
|
|
bee042d9fa | ||
|
|
6efeace169 | ||
|
|
a5b3926063 | ||
|
|
6306973948 | ||
|
|
84b6f15505 | ||
|
|
0a75d72610 | ||
|
|
549c4d1098 | ||
|
|
ea2b446130 | ||
|
|
6129a528c6 | ||
|
|
13c5bc5c95 | ||
|
|
78b11f9dc0 | ||
|
|
0dc4acac00 | ||
|
|
931c3f78d9 | ||
|
|
6a26df8069 | ||
|
|
a4404fa77a | ||
|
|
e19f80e5c7 | ||
|
|
416ccf1228 | ||
|
|
edbccbdad4 | ||
|
|
aa66719b30 | ||
|
|
b1b8c34361 | ||
|
|
9c08c916e0 | ||
|
|
b6c91bfe8c | ||
|
|
7886cf9e37 | ||
|
|
8d4c38b48e | ||
|
|
0a26661b7d | ||
|
|
864687daed | ||
|
|
c8c3cefecc | ||
|
|
12e5422845 | ||
|
|
a7960872bb | ||
|
|
94aff9fe73 | ||
|
|
9044097f2c | ||
|
|
a52ce30089 | ||
|
|
846263afee | ||
|
|
ba3cffdc79 | ||
|
|
dde839b66d | ||
|
|
ca15e2c70d | ||
|
|
0ea3bfa5c9 | ||
|
|
5331909446 | ||
|
|
e8eb77363e | ||
|
|
da2707c594 | ||
|
|
b0844b9118 | ||
|
|
27977e3730 | ||
|
|
f2f9f624b5 | ||
|
|
586152a4ad | ||
|
|
9a2ef3fca8 | ||
|
|
6912c5b1e7 | ||
|
|
f24fc07ac4 | ||
|
|
653182a90c | ||
|
|
2958e0801d |
12
.github/workflows/lint.yml
vendored
12
.github/workflows/lint.yml
vendored
@@ -23,8 +23,8 @@ on:
|
||||
- master
|
||||
|
||||
env:
|
||||
PROMU_VER: '0.13.0'
|
||||
PROMTOOL_VER: '2.32.1'
|
||||
PROMU_VER: '0.14.0'
|
||||
PROMTOOL_VER: '2.43.0'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.17.5'
|
||||
go-version: '^1.20.2'
|
||||
|
||||
- name: Test
|
||||
run: make test
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.17.5'
|
||||
go-version: '^1.20.2'
|
||||
|
||||
- name: Install promtool
|
||||
run: |
|
||||
@@ -89,12 +89,12 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.17.5'
|
||||
go-version: '^1.20.2'
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: v1.45.2
|
||||
version: v1.51.2
|
||||
args: "--timeout=5m"
|
||||
|
||||
# golangci-lint action doesn't always provide helpful output, so re-run without the action for
|
||||
|
||||
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -12,7 +12,7 @@ permissions:
|
||||
packages: write
|
||||
|
||||
env:
|
||||
PROMU_VER: '0.13.0'
|
||||
PROMU_VER: '0.14.0'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.17.5'
|
||||
go-version: '^1.20.2'
|
||||
|
||||
- name: Install Build deps
|
||||
run: |
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: windows_exporter_binaries
|
||||
path: output\windows_exporter-*.exe
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
|
||||
- name: Login to GitHub container registry
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
|
||||
2
.github/workflows/spelling.yml
vendored
2
.github/workflows/spelling.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
- master
|
||||
|
||||
env:
|
||||
PROMU_VER: 'v0.13.0'
|
||||
PROMU_VER: 'v0.14.0'
|
||||
|
||||
jobs:
|
||||
codespell:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
go:
|
||||
version: 1.20
|
||||
repository:
|
||||
path: github.com/prometheus-community/windows_exporter
|
||||
build:
|
||||
@@ -14,5 +16,4 @@ tarball:
|
||||
- LICENSE
|
||||
crossbuild:
|
||||
platforms:
|
||||
- windows/amd64
|
||||
- windows/386
|
||||
- windows
|
||||
|
||||
23
README.md
23
README.md
@@ -51,10 +51,12 @@ Name | Description | Enabled by default
|
||||
[smtp](docs/collector.smtp.md) | IIS SMTP Server |
|
||||
[system](docs/collector.system.md) | System calls | ✓
|
||||
[tcp](docs/collector.tcp.md) | TCP connections |
|
||||
[teradici_pcoip](docs/collector.teradici_pcoip.md) | [Teradici PCoIP](https://www.teradici.com/web-help/pcoip_wmi_specs/) session metrics |
|
||||
[time](docs/collector.time.md) | Windows Time Service |
|
||||
[thermalzone](docs/collector.thermalzone.md) | Thermal information
|
||||
[terminal_services](docs/collector.terminal_services.md) | Terminal services (RDS)
|
||||
[textfile](docs/collector.textfile.md) | Read prometheus metrics from a text file | ✓
|
||||
[vmware_blast](docs/collector.vmware_blast.md) | VMware Blast session metrics |
|
||||
[vmware](docs/collector.vmware.md) | Performance counters installed by the Vmware Guest agent |
|
||||
|
||||
See the linked documentation on each collector for more information on reported metrics, configuration settings and usage examples.
|
||||
@@ -80,13 +82,15 @@ windows_exporter accepts flags to configure certain behaviours. The ones configu
|
||||
|
||||
Flag | Description | Default value
|
||||
---------|-------------|--------------------
|
||||
`--telemetry.addr` | host:port for exporter. | `:9182`
|
||||
`--web.listen-address` | host:port for exporter. | `:9182`
|
||||
`--telemetry.path` | URL path for surfacing collected metrics. | `/metrics`
|
||||
`--telemetry.max-requests` | Maximum number of concurrent requests. 0 to disable. | `5`
|
||||
`--collectors.enabled` | Comma-separated list of collectors to use. Use `[defaults]` as a placeholder which gets expanded containing all the collectors enabled by default." | `[defaults]`
|
||||
`--collectors.print` | If true, print available collectors and exit. |
|
||||
`--scrape.timeout-margin` | Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads. | `0.5`
|
||||
`--web.config.file` | A [web config][web_config] for setting up TLS and Auth | None
|
||||
`--config.file` | [Using a config file](#using-a-configuration-file) from path or URL | None
|
||||
`--config.file.insecure-skip-verify` | Skip TLS when loading config file from URL | false
|
||||
|
||||
## Installation
|
||||
The latest release can be downloaded from the [releases page](https://github.com/prometheus-community/windows_exporter/releases).
|
||||
@@ -102,7 +106,7 @@ Name | Description
|
||||
`LISTEN_PORT` | The port to bind to. Defaults to 9182.
|
||||
`METRICS_PATH` | The path at which to serve metrics. Defaults to `/metrics`
|
||||
`TEXTFILE_DIR` | As the `--collector.textfile.directory` flag, provide a directory to read text files with metrics from
|
||||
`REMOTE_ADDR` | Allows setting comma separated remote IP addresses for the Windows Firewall exception (whitelist). Defaults to an empty string (any remote address).
|
||||
`REMOTE_ADDR` | Allows setting comma separated remote IP addresses for the Windows Firewall exception (allow list). Defaults to an empty string (any remote address).
|
||||
`EXTRA_FLAGS` | Allows passing full CLI flags. Defaults to an empty string.
|
||||
|
||||
Parameters are sent to the installer via `msiexec`. Example invocations:
|
||||
@@ -121,6 +125,13 @@ On some older versions of Windows you may need to surround parameter values with
|
||||
msiexec /i C:\Users\Administrator\Downloads\windows_exporter.msi ENABLED_COLLECTORS="ad,iis,logon,memory,process,tcp,thermalzone" TEXTFILE_DIR="C:\custom_metrics\"
|
||||
```
|
||||
|
||||
Powershell versions 7.3 and above require [PSNativeCommandArgumentPassing](https://learn.microsoft.com/en-us/powershell/scripting/learn/experimental-features?view=powershell-7.3) to be set to `Legacy` when using `--% EXTRA_FLAGS`:
|
||||
|
||||
```powershell
|
||||
$PSNativeCommandArgumentPassing = 'Legacy'
|
||||
msiexec /i <path-to-msi-file> ENABLED_COLLECTORS=os,service --% EXTRA_FLAGS="--collector.service.services-where ""Name LIKE 'sql%'"""
|
||||
```
|
||||
|
||||
|
||||
## Kubernetes Implementation
|
||||
|
||||
@@ -148,7 +159,7 @@ The prometheus metrics will be exposed on [localhost:9182](http://localhost:9182
|
||||
|
||||
### Enable only process collector and specify a custom query
|
||||
|
||||
.\windows_exporter.exe --collectors.enabled "process" --collector.process.whitelist="firefox.+"
|
||||
.\windows_exporter.exe --collectors.enabled "process" --collector.process.include="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 [regular expression](https://en.wikipedia.org/wiki/Regular_expression) must use `.+`. See [process](docs/collector.process.md) for more information.
|
||||
|
||||
@@ -162,7 +173,11 @@ This enables the additional process and container collectors on top of the defau
|
||||
|
||||
### Using a configuration file
|
||||
|
||||
YAML configuration files can be specified with the `--config.file` flag. E.G. `.\windows_exporter.exe --config.file=config.yml`
|
||||
YAML configuration files can be specified with the `--config.file` flag. e.g. `.\windows_exporter.exe --config.file=config.yml`. If you are using the absolute path, make sure to quote the path, e.g. `.\windows_exporter.exe --config.file="C:\Program Files\windows_exporter\config.yml"`
|
||||
|
||||
It is also possible to load the configuration from a URL. e.g. `.\windows_exporter.exe --config.file="https://example.com/config.yml"`
|
||||
|
||||
If you need to skip TLS verification, you can use the `--config.file.insecure-skip-verify` flag. e.g. `.\windows_exporter.exe --config.file="https://example.com/config.yml" --config.file.insecure-skip-verify`
|
||||
|
||||
```yaml
|
||||
collectors:
|
||||
|
||||
@@ -6,17 +6,16 @@ package collector
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("ad", NewADCollector)
|
||||
}
|
||||
|
||||
// A ADCollector is a Prometheus collector for WMI Win32_PerfRawData_DirectoryServices_DirectoryServices metrics
|
||||
type ADCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AddressBookOperationsTotal *prometheus.Desc
|
||||
AddressBookClientSessions *prometheus.Desc
|
||||
ApproximateHighestDistinguishedNameTag *prometheus.Desc
|
||||
@@ -80,10 +79,12 @@ type ADCollector struct {
|
||||
TombstonedObjectsVisitedTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewADCollector ...
|
||||
func NewADCollector() (Collector, error) {
|
||||
// newADCollector ...
|
||||
func newADCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "ad"
|
||||
return &ADCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
AddressBookOperationsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "address_book_operations_total"),
|
||||
"",
|
||||
@@ -457,7 +458,7 @@ func NewADCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *ADCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting ad metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting ad metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -617,7 +618,7 @@ type Win32_PerfRawData_DirectoryServices_DirectoryServices struct {
|
||||
|
||||
func (c *ADCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_DirectoryServices_DirectoryServices
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkADCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "ad", NewADCollector)
|
||||
benchmarkCollector(b, "ad", newADCollector)
|
||||
}
|
||||
|
||||
@@ -5,16 +5,16 @@ package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("adcs", adcsCollectorMethod, "Certification Authority")
|
||||
}
|
||||
|
||||
type adcsCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
RequestsPerSecond *prometheus.Desc
|
||||
RequestProcessingTime *prometheus.Desc
|
||||
RetrievalsPerSecond *prometheus.Desc
|
||||
@@ -31,9 +31,11 @@ type adcsCollector struct {
|
||||
}
|
||||
|
||||
// ADCSCollectorMethod ...
|
||||
func adcsCollectorMethod() (Collector, error) {
|
||||
func adcsCollectorMethod(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "adcs"
|
||||
return &adcsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
RequestsPerSecond: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "requests_total"),
|
||||
"Total certificate requests processed",
|
||||
@@ -117,7 +119,7 @@ func adcsCollectorMethod() (Collector, error) {
|
||||
|
||||
func (c *adcsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collectADCSCounters(ctx, ch); err != nil {
|
||||
log.Error("Failed collecting ADCS Metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting ADCS metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -145,7 +147,7 @@ func (c *adcsCollector) collectADCSCounters(ctx *ScrapeContext, ch chan<- promet
|
||||
if _, ok := ctx.perfObjects["Certification Authority"]; !ok {
|
||||
return nil, errors.New("Perflib did not contain an entry for Certification Authority")
|
||||
}
|
||||
err := unmarshalObject(ctx.perfObjects["Certification Authority"], &dst)
|
||||
err := unmarshalObject(ctx.perfObjects["Certification Authority"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"math"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("adfs", newADFSCollector, "AD FS")
|
||||
}
|
||||
|
||||
type adfsCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
adLoginConnectionFailures *prometheus.Desc
|
||||
certificateAuthentications *prometheus.Desc
|
||||
deviceAuthentications *prometheus.Desc
|
||||
@@ -59,10 +59,12 @@ type adfsCollector struct {
|
||||
}
|
||||
|
||||
// newADFSCollector constructs a new adfsCollector
|
||||
func newADFSCollector() (Collector, error) {
|
||||
func newADFSCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "adfs"
|
||||
|
||||
return &adfsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
adLoginConnectionFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ad_login_connection_failures_total"),
|
||||
"Total number of connection failures to an Active Directory domain controller",
|
||||
@@ -160,7 +162,7 @@ func newADFSCollector() (Collector, error) {
|
||||
nil,
|
||||
),
|
||||
oAuthClientPrivateKeyJwtAuthenticationFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_privkey_jtw_authentication_failure_total"),
|
||||
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_privkey_jwt_authentication_failure_total"),
|
||||
"Total number of failed OAuth Client Private Key Jwt Authentications",
|
||||
nil,
|
||||
nil,
|
||||
@@ -372,7 +374,7 @@ type perflibADFS struct {
|
||||
|
||||
func (c *adfsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var adfsData []perflibADFS
|
||||
err := unmarshalObject(ctx.perfObjects["AD FS"], &adfsData)
|
||||
err := unmarshalObject(ctx.perfObjects["AD FS"], &adfsData, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -4,16 +4,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("cache", newCacheCollector, "Cache")
|
||||
}
|
||||
|
||||
// A CacheCollector is a Prometheus collector for Perflib Cache metrics
|
||||
type CacheCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AsyncCopyReadsTotal *prometheus.Desc
|
||||
AsyncDataMapsTotal *prometheus.Desc
|
||||
AsyncFastReadsTotal *prometheus.Desc
|
||||
@@ -46,9 +45,11 @@ type CacheCollector struct {
|
||||
}
|
||||
|
||||
// NewCacheCollector ...
|
||||
func newCacheCollector() (Collector, error) {
|
||||
func newCacheCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "cache"
|
||||
return &CacheCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
AsyncCopyReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "async_copy_reads_total"),
|
||||
"(AsyncCopyReadsTotal)",
|
||||
@@ -229,7 +230,7 @@ func newCacheCollector() (Collector, error) {
|
||||
// Collect implements the Collector interface
|
||||
func (c *CacheCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
log.Error("failed collecting cache metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting cache metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -271,7 +272,7 @@ type perflibCache struct {
|
||||
|
||||
func (c *CacheCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []perflibCache // Single-instance class, array is required but will have single entry.
|
||||
if err := unmarshalObject(ctx.perfObjects["Cache"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["Cache"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,11 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/leoluk/perflib_exporter/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/prometheus-community/windows_exporter/perflib"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
@@ -24,33 +27,35 @@ const (
|
||||
|
||||
// getWindowsVersion reads the version number of the OS from the Registry
|
||||
// See https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version
|
||||
func getWindowsVersion() float64 {
|
||||
func getWindowsVersion(logger log.Logger) float64 {
|
||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
log.Warn("Couldn't open registry", err)
|
||||
_ = level.Warn(logger).Log("msg", "Couldn't open registry", "err", err)
|
||||
return 0
|
||||
}
|
||||
defer func() {
|
||||
err = k.Close()
|
||||
if err != nil {
|
||||
log.Warnf("Failed to close registry key: %v", err)
|
||||
_ = level.Warn(logger).Log("msg", "Failed to close registry key", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
currentv, _, err := k.GetStringValue("CurrentVersion")
|
||||
if err != nil {
|
||||
log.Warn("Couldn't open registry to determine current Windows version:", err)
|
||||
_ = level.Warn(logger).Log("msg", "Couldn't open registry to determine current Windows version", "err", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
currentv_flt, err := strconv.ParseFloat(currentv, 64)
|
||||
|
||||
log.Debugf("Detected Windows version %f\n", currentv_flt)
|
||||
_ = level.Debug(logger).Log("msg", fmt.Sprintf("Detected Windows version %f\n", currentv_flt))
|
||||
|
||||
return currentv_flt
|
||||
}
|
||||
|
||||
type collectorBuilder func() (Collector, error)
|
||||
type collectorBuilder func(log.Logger) (Collector, error)
|
||||
type flagsBuilder func(*kingpin.Application)
|
||||
type perfCounterNamesBuilder func(log.Logger) []string
|
||||
|
||||
var (
|
||||
builders = make(map[string]collectorBuilder)
|
||||
@@ -77,12 +82,12 @@ func Available() []string {
|
||||
}
|
||||
return cs
|
||||
}
|
||||
func Build(collector string) (Collector, error) {
|
||||
func Build(collector string, logger log.Logger) (Collector, error) {
|
||||
builder, exists := builders[collector]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("Unknown collector %q", collector)
|
||||
}
|
||||
return builder()
|
||||
return builder(logger)
|
||||
}
|
||||
func getPerfQuery(collectors []string) string {
|
||||
parts := make([]string, 0, len(collectors))
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -35,14 +36,14 @@ func TestExpandChildCollectors(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkCollector(b *testing.B, name string, collectFunc func() (Collector, error)) {
|
||||
func benchmarkCollector(b *testing.B, name string, collectFunc func(logger log.Logger) (Collector, error)) {
|
||||
// Create perflib scrape context. Some perflib collectors required a correct context,
|
||||
// or will fail during benchmark.
|
||||
scrapeContext, err := PrepareScrapeContext([]string{name})
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
c, err := collectFunc()
|
||||
c, err := collectFunc(log.NewNopLogger())
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
@@ -4,17 +4,19 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("container", NewContainerMetricsCollector)
|
||||
}
|
||||
|
||||
// A ContainerMetricsCollector is a Prometheus collector for containers metrics
|
||||
type ContainerMetricsCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
// Presence
|
||||
ContainerAvailable *prometheus.Desc
|
||||
|
||||
@@ -45,10 +47,12 @@ type ContainerMetricsCollector struct {
|
||||
WriteSizeBytes *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewContainerMetricsCollector constructs a new ContainerMetricsCollector
|
||||
func NewContainerMetricsCollector() (Collector, error) {
|
||||
// newContainerMetricsCollector constructs a new ContainerMetricsCollector
|
||||
func newContainerMetricsCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "container"
|
||||
return &ContainerMetricsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
ContainerAvailable: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "available"),
|
||||
"Available",
|
||||
@@ -164,17 +168,17 @@ func NewContainerMetricsCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *ContainerMetricsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting ContainerMetricsCollector metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting ContainerMetricsCollector metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// containerClose closes the container resource
|
||||
func containerClose(c hcsshim.Container) {
|
||||
err := c.Close()
|
||||
func (c *ContainerMetricsCollector) containerClose(container hcsshim.Container) {
|
||||
err := container.Close()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
_ = level.Error(c.logger).Log("err", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +187,7 @@ func (c *ContainerMetricsCollector) collect(ch chan<- prometheus.Metric) (*prome
|
||||
// Types Container is passed to get the containers compute systems only
|
||||
containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
|
||||
if err != nil {
|
||||
log.Error("Err in Getting containers:", err)
|
||||
_ = level.Error(c.logger).Log("msg", "Err in Getting containers", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -198,22 +202,26 @@ func (c *ContainerMetricsCollector) collect(ch chan<- prometheus.Metric) (*prome
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
containerPrefixes := make(map[string]string)
|
||||
|
||||
for _, containerDetails := range containers {
|
||||
container, err := hcsshim.OpenContainer(containerDetails.ID)
|
||||
if container != nil {
|
||||
defer containerClose(container)
|
||||
defer c.containerClose(container)
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("err in opening container: ", containerDetails.ID, err)
|
||||
_ = level.Error(c.logger).Log("msg", "err in opening container", "containerId", containerDetails.ID, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
cstats, err := container.Statistics()
|
||||
if err != nil {
|
||||
log.Error("err in fetching container Statistics: ", containerDetails.ID, err)
|
||||
_ = level.Error(c.logger).Log("msg", "err in fetching container Statistics", "containerId", containerDetails.ID, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
containerIdWithPrefix := getContainerIdWithPrefix(containerDetails)
|
||||
containerPrefixes[containerDetails.ID] = containerIdWithPrefix
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ContainerAvailable,
|
||||
@@ -257,54 +265,6 @@ func (c *ContainerMetricsCollector) collect(ch chan<- prometheus.Metric) (*prome
|
||||
float64(cstats.Processor.RuntimeKernel100ns)*ticksToSecondsScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
|
||||
if len(cstats.Network) == 0 {
|
||||
log.Info("No Network Stats for container: ", containerDetails.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
networkStats := cstats.Network
|
||||
|
||||
for _, networkInterface := range networkStats {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(networkInterface.BytesReceived),
|
||||
containerIdWithPrefix, networkInterface.EndpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesSent,
|
||||
prometheus.CounterValue,
|
||||
float64(networkInterface.BytesSent),
|
||||
containerIdWithPrefix, networkInterface.EndpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(networkInterface.PacketsReceived),
|
||||
containerIdWithPrefix, networkInterface.EndpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(networkInterface.PacketsSent),
|
||||
containerIdWithPrefix, networkInterface.EndpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DroppedPacketsIncoming,
|
||||
prometheus.CounterValue,
|
||||
float64(networkInterface.DroppedPacketsIncoming),
|
||||
containerIdWithPrefix, networkInterface.EndpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DroppedPacketsOutgoing,
|
||||
prometheus.CounterValue,
|
||||
float64(networkInterface.DroppedPacketsOutgoing),
|
||||
containerIdWithPrefix, networkInterface.EndpointId,
|
||||
)
|
||||
break
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadCountNormalized,
|
||||
prometheus.CounterValue,
|
||||
@@ -331,6 +291,73 @@ func (c *ContainerMetricsCollector) collect(ch chan<- prometheus.Metric) (*prome
|
||||
)
|
||||
}
|
||||
|
||||
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for containers")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if len(hnsEndpoints) == 0 {
|
||||
_ = level.Info(c.logger).Log("msg", fmt.Sprintf("No network stats for containers to collect"))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, endpoint := range hnsEndpoints {
|
||||
endpointStats, err := hcsshim.GetHNSEndpointStats(endpoint.Id)
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Failed to collect network stats for interface %s", endpoint.Id), "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, containerId := range endpoint.SharedContainers {
|
||||
containerIdWithPrefix, ok := containerPrefixes[containerId]
|
||||
endpointId := strings.ToUpper(endpoint.Id)
|
||||
|
||||
if !ok {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Failed to collect network stats for container %s", containerId))
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.BytesReceived),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesSent,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.BytesSent),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.PacketsReceived),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.PacketsSent),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DroppedPacketsIncoming,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.DroppedPacketsIncoming),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DroppedPacketsOutgoing,
|
||||
prometheus.CounterValue,
|
||||
float64(endpointStats.DroppedPacketsOutgoing),
|
||||
containerIdWithPrefix, endpointId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkContainerCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "container", NewContainerMetricsCollector)
|
||||
benchmarkCollector(b, "container", newContainerMetricsCollector)
|
||||
}
|
||||
|
||||
@@ -6,27 +6,21 @@ package collector
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
var deps string
|
||||
// See below for 6.05 magic value
|
||||
if getWindowsVersion() > 6.05 {
|
||||
deps = "Processor Information"
|
||||
} else {
|
||||
deps = "Processor"
|
||||
}
|
||||
registerCollector("cpu", newCPUCollector, deps)
|
||||
}
|
||||
|
||||
type cpuCollectorBasic struct {
|
||||
logger log.Logger
|
||||
|
||||
CStateSecondsTotal *prometheus.Desc
|
||||
TimeTotal *prometheus.Desc
|
||||
InterruptsTotal *prometheus.Desc
|
||||
DPCsTotal *prometheus.Desc
|
||||
}
|
||||
type cpuCollectorFull struct {
|
||||
logger log.Logger
|
||||
|
||||
CStateSecondsTotal *prometheus.Desc
|
||||
TimeTotal *prometheus.Desc
|
||||
InterruptsTotal *prometheus.Desc
|
||||
@@ -44,10 +38,11 @@ type cpuCollectorFull struct {
|
||||
}
|
||||
|
||||
// newCPUCollector constructs a new cpuCollector, appropriate for the running OS
|
||||
func newCPUCollector() (Collector, error) {
|
||||
func newCPUCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "cpu"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
version := getWindowsVersion()
|
||||
version := getWindowsVersion(logger)
|
||||
// For Windows 2008 (version 6.0) or earlier we only have the "Processor"
|
||||
// class. As of Windows 2008 R2 (version 6.1) the more detailed
|
||||
// "Processor Information" set is available (although some of the counters
|
||||
@@ -56,6 +51,7 @@ func newCPUCollector() (Collector, error) {
|
||||
// Value 6.05 was selected to split between Windows versions.
|
||||
if version < 6.05 {
|
||||
return &cpuCollectorBasic{
|
||||
logger: logger,
|
||||
CStateSecondsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cstate_seconds_total"),
|
||||
"Time spent in low-power idle state",
|
||||
@@ -84,6 +80,7 @@ func newCPUCollector() (Collector, error) {
|
||||
}
|
||||
|
||||
return &cpuCollectorFull{
|
||||
logger: logger,
|
||||
CStateSecondsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "cstate_seconds_total"),
|
||||
"Time spent in low-power idle state",
|
||||
@@ -186,7 +183,7 @@ type perflibProcessor struct {
|
||||
|
||||
func (c *cpuCollectorBasic) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
data := make([]perflibProcessor, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Processor"], &data)
|
||||
err := unmarshalObject(ctx.perfObjects["Processor"], &data, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -295,7 +292,7 @@ type perflibProcessorInformation struct {
|
||||
|
||||
func (c *cpuCollectorFull) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
data := make([]perflibProcessorInformation, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Processor Information"], &data)
|
||||
err := unmarshalObject(ctx.perfObjects["Processor Information"], &data, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -8,15 +8,12 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("cpu_info", newCpuInfoCollector)
|
||||
}
|
||||
|
||||
// If you are adding additional labels to the metric, make sure that they get added in here as well. See below for explanation.
|
||||
const (
|
||||
win32ProcessorQuery = "SELECT Architecture, DeviceId, Description, Family, L2CacheSize, L3CacheSize, Name FROM Win32_Processor"
|
||||
@@ -24,13 +21,18 @@ const (
|
||||
|
||||
// A CpuInfoCollector is a Prometheus collector for a few WMI metrics in Win32_Processor
|
||||
type CpuInfoCollector struct {
|
||||
logger log.Logger
|
||||
CpuInfo *prometheus.Desc
|
||||
}
|
||||
|
||||
func newCpuInfoCollector() (Collector, error) {
|
||||
func newCpuInfoCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "cpu_info"
|
||||
|
||||
return &CpuInfoCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
CpuInfo: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, "", "cpu_info"),
|
||||
prometheus.BuildFQName(Namespace, "", subsystem),
|
||||
"Labeled CPU information as provided provided by Win32_Processor",
|
||||
[]string{
|
||||
"architecture",
|
||||
@@ -59,7 +61,7 @@ type win32_Processor struct {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *CpuInfoCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting cpu_info metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting cpu_info metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -4,28 +4,28 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/headers/sysinfoapi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("cs", NewCSCollector)
|
||||
}
|
||||
|
||||
// A CSCollector is a Prometheus collector for WMI metrics
|
||||
type CSCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
PhysicalMemoryBytes *prometheus.Desc
|
||||
LogicalProcessors *prometheus.Desc
|
||||
Hostname *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewCSCollector ...
|
||||
func NewCSCollector() (Collector, error) {
|
||||
// newCSCollector ...
|
||||
func newCSCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "cs"
|
||||
|
||||
return &CSCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
LogicalProcessors: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "logical_processors"),
|
||||
"ComputerSystem.NumberOfLogicalProcessors",
|
||||
@@ -54,7 +54,7 @@ func NewCSCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *CSCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting cs metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting cs metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkCsCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "cs", NewCSCollector)
|
||||
benchmarkCollector(b, "cs", newCSCollector)
|
||||
}
|
||||
|
||||
@@ -4,25 +4,22 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
var dfsrEnabledCollectors = kingpin.Flag("collectors.dfsr.sources-enabled", "Comma-seperated list of DFSR Perflib sources to use.").Default("connection,folder,volume").String()
|
||||
const (
|
||||
FlagDfsrEnabledCollectors = "collectors.dfsr.sources-enabled"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Perflib sources are dynamic, depending on the enabled child collectors
|
||||
var perflibDependencies []string
|
||||
for _, source := range expandEnabledChildCollectors(*dfsrEnabledCollectors) {
|
||||
perflibDependencies = append(perflibDependencies, dfsrGetPerfObjectName(source))
|
||||
}
|
||||
|
||||
registerCollector("dfsr", NewDFSRCollector, perflibDependencies...)
|
||||
}
|
||||
var dfsrEnabledCollectors *string
|
||||
|
||||
// DFSRCollector contains the metric and state data of the DFSR collectors.
|
||||
type DFSRCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
// Connection source
|
||||
ConnectionBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc
|
||||
ConnectionBytesReceivedTotal *prometheus.Desc
|
||||
@@ -92,10 +89,16 @@ func dfsrGetPerfObjectName(collector string) string {
|
||||
return (prefix + suffix)
|
||||
}
|
||||
|
||||
// NewDFSRCollector is registered
|
||||
func NewDFSRCollector() (Collector, error) {
|
||||
log.Info("dfsr collector is in an experimental state! Metrics for this collector have not been tested.")
|
||||
// newDFSRCollectorFlags is registered
|
||||
func newDFSRCollectorFlags(app *kingpin.Application) {
|
||||
dfsrEnabledCollectors = app.Flag(FlagDfsrEnabledCollectors, "Comma-seperated list of DFSR Perflib sources to use.").Default("connection,folder,volume").String()
|
||||
}
|
||||
|
||||
// newDFSRCollector is registered
|
||||
func newDFSRCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "dfsr"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
_ = level.Info(logger).Log("msg", "dfsr collector is in an experimental state! Metrics for this collector have not been tested.")
|
||||
|
||||
enabled := expandEnabledChildCollectors(*dfsrEnabledCollectors)
|
||||
perfCounters := make([]string, 0, len(enabled))
|
||||
@@ -105,6 +108,8 @@ func NewDFSRCollector() (Collector, error) {
|
||||
addPerfCounterDependencies(subsystem, perfCounters)
|
||||
|
||||
dfsrCollector := DFSRCollector{
|
||||
logger: logger,
|
||||
|
||||
// Connection
|
||||
ConnectionBandwidthSavingsUsingDFSReplicationTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_bandwidth_savings_using_dfs_replication_bytes_total"),
|
||||
@@ -448,7 +453,7 @@ type PerflibDFSRConnection struct {
|
||||
|
||||
func (c *DFSRCollector) collectConnection(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []PerflibDFSRConnection
|
||||
if err := unmarshalObject(ctx.perfObjects["DFS Replication Connections"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["DFS Replication Connections"], &dst, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -555,7 +560,7 @@ type PerflibDFSRFolder struct {
|
||||
|
||||
func (c *DFSRCollector) collectFolder(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []PerflibDFSRFolder
|
||||
if err := unmarshalObject(ctx.perfObjects["DFS Replicated Folders"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["DFS Replicated Folders"], &dst, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -765,7 +770,7 @@ type PerflibDFSRVolume struct {
|
||||
|
||||
func (c *DFSRCollector) collectVolume(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []PerflibDFSRVolume
|
||||
if err := unmarshalObject(ctx.perfObjects["DFS Replication Service Volumes"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["DFS Replication Service Volumes"], &dst, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkDFSRCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "dfsr", NewDFSRCollector)
|
||||
benchmarkCollector(b, "dfsr", newDFSRCollector)
|
||||
}
|
||||
|
||||
@@ -4,15 +4,14 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("dhcp", NewDhcpCollector, "DHCP Server")
|
||||
}
|
||||
|
||||
// A DhcpCollector is a Prometheus collector perflib DHCP metrics
|
||||
type DhcpCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
PacketsReceivedTotal *prometheus.Desc
|
||||
DuplicatesDroppedTotal *prometheus.Desc
|
||||
PacketsExpiredTotal *prometheus.Desc
|
||||
@@ -40,10 +39,12 @@ type DhcpCollector struct {
|
||||
FailoverBndupdDropped *prometheus.Desc
|
||||
}
|
||||
|
||||
func NewDhcpCollector() (Collector, error) {
|
||||
func newDhcpCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "dhcp"
|
||||
|
||||
return &DhcpCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
PacketsReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "packets_received_total"),
|
||||
"Total number of packets received by the DHCP server (PacketsReceivedTotal)",
|
||||
@@ -230,7 +231,7 @@ type dhcpPerf struct {
|
||||
|
||||
func (c *DhcpCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var perflib []dhcpPerf
|
||||
if err := unmarshalObject(ctx.perfObjects["DHCP Server"], &perflib); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["DHCP Server"], &perflib, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkDHCPCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "dhcp", NewDhcpCollector)
|
||||
benchmarkCollector(b, "dhcp", newDhcpCollector)
|
||||
}
|
||||
|
||||
209
collector/diskdrive.go
Normal file
209
collector/diskdrive.go
Normal file
@@ -0,0 +1,209 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const (
|
||||
win32DiskQuery = "SELECT DeviceID, Model, Caption, Name, Partitions, Size, Status, Availability FROM WIN32_DiskDrive"
|
||||
)
|
||||
|
||||
// A DiskDriveInfoCollector is a Prometheus collector for a few WMI metrics in Win32_DiskDrive
|
||||
type DiskDriveInfoCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
DiskInfo *prometheus.Desc
|
||||
Status *prometheus.Desc
|
||||
Size *prometheus.Desc
|
||||
Partitions *prometheus.Desc
|
||||
Availability *prometheus.Desc
|
||||
}
|
||||
|
||||
func newDiskDriveInfoCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "diskdrive"
|
||||
|
||||
return &DiskDriveInfoCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
DiskInfo: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "info"),
|
||||
"General drive information",
|
||||
[]string{
|
||||
"device_id",
|
||||
"model",
|
||||
"caption",
|
||||
"name",
|
||||
},
|
||||
nil,
|
||||
),
|
||||
|
||||
Status: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "status"),
|
||||
"Status of the drive",
|
||||
[]string{
|
||||
"name", "status"},
|
||||
nil,
|
||||
),
|
||||
|
||||
Size: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "size"),
|
||||
"Size of the disk drive. It is calculated by multiplying the total number of cylinders, tracks in each cylinder, sectors in each track, and bytes in each sector.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
Partitions: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "partitions"),
|
||||
"Number of partitions",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
),
|
||||
|
||||
Availability: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "availability"),
|
||||
"Availability Status",
|
||||
[]string{
|
||||
"name", "availability"},
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Win32_DiskDrive struct {
|
||||
DeviceID string
|
||||
Model string
|
||||
Size uint64
|
||||
Name string
|
||||
Caption string
|
||||
Partitions uint32
|
||||
Status string
|
||||
Availability uint16
|
||||
}
|
||||
|
||||
var (
|
||||
allDiskStatus = []string{
|
||||
"OK",
|
||||
"Error",
|
||||
"Degraded",
|
||||
"Unknown",
|
||||
"Pred fail",
|
||||
"Starting",
|
||||
"Stopping",
|
||||
"Service",
|
||||
"Stressed",
|
||||
"Nonrecover",
|
||||
"No Contact",
|
||||
"Lost Comm",
|
||||
}
|
||||
|
||||
availMap = map[int]string{
|
||||
|
||||
1: "Other",
|
||||
2: "Unknown",
|
||||
3: "Running / Full Power",
|
||||
4: "Warning",
|
||||
5: "In Test",
|
||||
6: "Not Applicable",
|
||||
7: "Power Off",
|
||||
8: "Off line",
|
||||
9: "Off Duty",
|
||||
10: "Degraded",
|
||||
11: "Not Installed",
|
||||
12: "Install Error",
|
||||
13: "Power Save - Unknown",
|
||||
14: "Power Save - Low Power Mode",
|
||||
15: "Power Save - Standby",
|
||||
16: "Power Cycle",
|
||||
17: "Power Save - Warning",
|
||||
18: "Paused",
|
||||
19: "Not Ready",
|
||||
20: "Not Configured",
|
||||
21: "Quiesced",
|
||||
}
|
||||
)
|
||||
|
||||
// Collect sends the metric values for each metric to the provided prometheus Metric channel.
|
||||
func (c *DiskDriveInfoCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting disk_drive_info metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *DiskDriveInfoCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_DiskDrive
|
||||
|
||||
if err := wmi.Query(win32DiskQuery, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dst) == 0 {
|
||||
return nil, errors.New("WMI query returned empty result set")
|
||||
}
|
||||
|
||||
for _, disk := range dst {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.DiskInfo,
|
||||
prometheus.GaugeValue,
|
||||
1.0,
|
||||
strings.Trim(disk.DeviceID, "\\.\\"),
|
||||
strings.TrimRight(disk.Model, " "),
|
||||
strings.TrimRight(disk.Caption, " "),
|
||||
strings.TrimRight(disk.Name, "\\.\\"),
|
||||
)
|
||||
|
||||
for _, status := range allDiskStatus {
|
||||
isCurrentState := 0.0
|
||||
if status == disk.Status {
|
||||
isCurrentState = 1.0
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Status,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
strings.Trim(disk.Name, "\\.\\"),
|
||||
status,
|
||||
)
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Size,
|
||||
prometheus.GaugeValue,
|
||||
float64(disk.Size),
|
||||
strings.Trim(disk.Name, "\\.\\"),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Partitions,
|
||||
prometheus.GaugeValue,
|
||||
float64(disk.Partitions),
|
||||
strings.Trim(disk.Name, "\\.\\"),
|
||||
)
|
||||
|
||||
for availNum, val := range availMap {
|
||||
isCurrentState := 0.0
|
||||
if availNum == int(disk.Availability) {
|
||||
isCurrentState = 1.0
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.Availability,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
strings.Trim(disk.Name, "\\.\\"),
|
||||
val,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
9
collector/diskdrive_test.go
Normal file
9
collector/diskdrive_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkDiskDriveCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "disk_drive", newDiskDriveInfoCollector)
|
||||
}
|
||||
@@ -6,17 +6,16 @@ package collector
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("dns", NewDNSCollector)
|
||||
}
|
||||
|
||||
// A DNSCollector is a Prometheus collector for WMI Win32_PerfRawData_DNS_DNS metrics
|
||||
type DNSCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
ZoneTransferRequestsReceived *prometheus.Desc
|
||||
ZoneTransferRequestsSent *prometheus.Desc
|
||||
ZoneTransferResponsesReceived *prometheus.Desc
|
||||
@@ -41,10 +40,12 @@ type DNSCollector struct {
|
||||
UnmatchedResponsesReceived *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewDNSCollector ...
|
||||
func NewDNSCollector() (Collector, error) {
|
||||
// newDNSCollector ...
|
||||
func newDNSCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "dns"
|
||||
return &DNSCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
ZoneTransferRequestsReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "zone_transfer_requests_received_total"),
|
||||
"Number of zone transfer requests (AXFR/IXFR) received by the master DNS server",
|
||||
@@ -184,7 +185,7 @@ func NewDNSCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *DNSCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting dns metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting dns metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -238,7 +239,7 @@ type Win32_PerfRawData_DNS_DNS struct {
|
||||
|
||||
func (c *DNSCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_DNS_DNS
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkDNSCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "dns", NewDNSCollector)
|
||||
benchmarkCollector(b, "dns", newDNSCollector)
|
||||
}
|
||||
|
||||
@@ -8,26 +8,20 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("exchange", newExchangeCollector,
|
||||
"MSExchange ADAccess Processes",
|
||||
"MSExchangeTransport Queues",
|
||||
"MSExchange HttpProxy",
|
||||
"MSExchange ActiveSync",
|
||||
"MSExchange Availability Service",
|
||||
"MSExchange OWA",
|
||||
"MSExchangeAutodiscover",
|
||||
"MSExchange WorkloadManagement Workloads",
|
||||
"MSExchange RpcClientAccess",
|
||||
)
|
||||
}
|
||||
const (
|
||||
FlagExchangeListAllCollectors = "collectors.exchange.list"
|
||||
FlagExchangeCollectorsEnabled = "collectors.exchange.enabled"
|
||||
)
|
||||
|
||||
type exchangeCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
LDAPReadTime *prometheus.Desc
|
||||
LDAPSearchTime *prometheus.Desc
|
||||
LDAPWriteTime *prometheus.Desc
|
||||
@@ -83,19 +77,27 @@ var (
|
||||
"RpcClientAccess",
|
||||
}
|
||||
|
||||
argExchangeListAllCollectors = kingpin.Flag(
|
||||
"collectors.exchange.list",
|
||||
argExchangeListAllCollectors *bool
|
||||
|
||||
argExchangeCollectorsEnabled *string
|
||||
)
|
||||
|
||||
// newExchangeCollectorFlags ...
|
||||
func newExchangeCollectorFlags(app *kingpin.Application) {
|
||||
argExchangeListAllCollectors = app.Flag(
|
||||
FlagExchangeListAllCollectors,
|
||||
"List the collectors along with their perflib object name/ids",
|
||||
).Bool()
|
||||
|
||||
argExchangeCollectorsEnabled = kingpin.Flag(
|
||||
"collectors.exchange.enabled",
|
||||
argExchangeCollectorsEnabled = app.Flag(
|
||||
FlagExchangeCollectorsEnabled,
|
||||
"Comma-separated list of collectors to use. Defaults to all, if not specified.",
|
||||
).Default("").String()
|
||||
)
|
||||
}
|
||||
|
||||
// newExchangeCollector returns a new Collector
|
||||
func newExchangeCollector() (Collector, error) {
|
||||
func newExchangeCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "exchange"
|
||||
|
||||
// desc creates a new prometheus description
|
||||
desc := func(metricName string, description string, labels ...string) *prometheus.Desc {
|
||||
@@ -108,6 +110,8 @@ func newExchangeCollector() (Collector, error) {
|
||||
}
|
||||
|
||||
c := exchangeCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
RPCAveragedLatency: desc("rpc_avg_latency_sec", "The latency (sec), averaged for the past 1024 packets"),
|
||||
RPCRequests: desc("rpc_requests", "Number of client requests currently being processed by the RPC Client Access service"),
|
||||
ActiveUserCount: desc("rpc_active_user_count", "Number of unique users that have shown some kind of activity in the last 2 minutes"),
|
||||
@@ -203,7 +207,7 @@ func (c *exchangeCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Met
|
||||
|
||||
for _, collectorName := range c.enabledCollectors {
|
||||
if err := collectorFuncs[collectorName](ctx, ch); err != nil {
|
||||
log.Errorf("Error in %s: %s", collectorName, err)
|
||||
_ = level.Error(c.logger).Log("msg", "Error in "+collectorName, "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -223,7 +227,7 @@ type perflibADAccessProcesses struct {
|
||||
|
||||
func (c *exchangeCollector) collectADAccessProcesses(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibADAccessProcesses
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange ADAccess Processes"], &data); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange ADAccess Processes"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -281,7 +285,7 @@ type perflibAvailabilityService struct {
|
||||
|
||||
func (c *exchangeCollector) collectAvailabilityService(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibAvailabilityService
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange Availability Service"], &data); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange Availability Service"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -309,7 +313,7 @@ type perflibHTTPProxy struct {
|
||||
|
||||
func (c *exchangeCollector) collectHTTPProxy(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibHTTPProxy
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange HttpProxy"], &data); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange HttpProxy"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -363,7 +367,7 @@ type perflibOWA struct {
|
||||
|
||||
func (c *exchangeCollector) collectOWA(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibOWA
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange OWA"], &data); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange OWA"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -391,7 +395,7 @@ type perflibActiveSync struct {
|
||||
|
||||
func (c *exchangeCollector) collectActiveSync(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibActiveSync
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange ActiveSync"], &data); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange ActiveSync"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -427,7 +431,7 @@ type perflibRPCClientAccess struct {
|
||||
|
||||
func (c *exchangeCollector) collectRPC(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibRPCClientAccess
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange RpcClientAccess"], &data); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange RpcClientAccess"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -483,7 +487,7 @@ type perflibTransportQueues struct {
|
||||
|
||||
func (c *exchangeCollector) collectTransportQueues(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibTransportQueues
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchangeTransport Queues"], &data); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchangeTransport Queues"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -557,7 +561,7 @@ type perflibWorkloadManagementWorkloads struct {
|
||||
|
||||
func (c *exchangeCollector) collectWorkloadManagementWorkloads(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibWorkloadManagementWorkloads
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange WorkloadManagement Workloads"], &data); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchange WorkloadManagement Workloads"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -608,7 +612,7 @@ type perflibAutodiscover struct {
|
||||
|
||||
func (c *exchangeCollector) collectAutoDiscover(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibAutodiscover
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchangeAutodiscover"], &data); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["MSExchangeAutodiscover"], &data, c.logger); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, autodisc := range data {
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("fsrmquota", newFSRMQuotaCollector)
|
||||
}
|
||||
|
||||
type FSRMQuotaCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
QuotasCount *prometheus.Desc
|
||||
Path *prometheus.Desc
|
||||
PeakUsage *prometheus.Desc
|
||||
@@ -24,9 +23,11 @@ type FSRMQuotaCollector struct {
|
||||
Template *prometheus.Desc
|
||||
}
|
||||
|
||||
func newFSRMQuotaCollector() (Collector, error) {
|
||||
func newFSRMQuotaCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "fsrmquota"
|
||||
return &FSRMQuotaCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
QuotasCount: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "count"),
|
||||
"Number of Quotas",
|
||||
@@ -88,7 +89,7 @@ func newFSRMQuotaCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *FSRMQuotaCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting fsrmquota metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting fsrmquota metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -113,7 +114,7 @@ type MSFT_FSRMQuota struct {
|
||||
|
||||
func (c *FSRMQuotaCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []MSFT_FSRMQuota
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
|
||||
var count int
|
||||
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("hyperv", NewHyperVCollector)
|
||||
}
|
||||
|
||||
// HyperVCollector is a Prometheus collector for hyper-v
|
||||
type HyperVCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
// Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
|
||||
HealthCritical *prometheus.Desc
|
||||
HealthOk *prometheus.Desc
|
||||
@@ -130,10 +130,13 @@ type HyperVCollector struct {
|
||||
VMMemoryRemovedMemory *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewHyperVCollector ...
|
||||
func NewHyperVCollector() (Collector, error) {
|
||||
// newHyperVCollector ...
|
||||
func newHyperVCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "hyperv"
|
||||
buildSubsystemName := func(component string) string { return "hyperv_" + component }
|
||||
return &HyperVCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
HealthCritical: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, buildSubsystemName("health"), "critical"),
|
||||
"This counter represents the number of virtual machines with critical health",
|
||||
@@ -701,62 +704,62 @@ func NewHyperVCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *HyperVCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collectVmHealth(ch); err != nil {
|
||||
log.Error("failed collecting hyperV health status metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV health status metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectVmVid(ch); err != nil {
|
||||
log.Error("failed collecting hyperV pages metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV pages metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectVmHv(ch); err != nil {
|
||||
log.Error("failed collecting hyperV hv status metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV hv status metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectVmProcessor(ch); err != nil {
|
||||
log.Error("failed collecting hyperV processor metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV processor metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectHostLPUsage(ch); err != nil {
|
||||
log.Error("failed collecting hyperV host logical processors metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV host logical processors metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectHostCpuUsage(ch); err != nil {
|
||||
log.Error("failed collecting hyperV host CPU metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV host CPU metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectVmCpuUsage(ch); err != nil {
|
||||
log.Error("failed collecting hyperV VM CPU metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV VM CPU metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectVmSwitch(ch); err != nil {
|
||||
log.Error("failed collecting hyperV switch metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV switch metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectVmEthernet(ch); err != nil {
|
||||
log.Error("failed collecting hyperV ethernet metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV ethernet metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectVmStorage(ch); err != nil {
|
||||
log.Error("failed collecting hyperV virtual storage metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual storage metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectVmNetwork(ch); err != nil {
|
||||
log.Error("failed collecting hyperV virtual network metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual network metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectVmMemory(ch); err != nil {
|
||||
log.Error("failed collecting hyperV virtual memory metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual memory metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -771,7 +774,7 @@ type Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
|
||||
|
||||
func (c *HyperVCollector) collectVmHealth(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -804,7 +807,7 @@ type Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition struct {
|
||||
|
||||
func (c *HyperVCollector) collectVmVid(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -868,7 +871,7 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition struct {
|
||||
|
||||
func (c *HyperVCollector) collectVmHv(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1006,7 +1009,7 @@ type Win32_PerfRawData_HvStats_HyperVHypervisor struct {
|
||||
|
||||
func (c *HyperVCollector) collectVmProcessor(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisor
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1040,7 +1043,7 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor struct {
|
||||
|
||||
func (c *HyperVCollector) collectHostLPUsage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1052,7 +1055,7 @@ func (c *HyperVCollector) collectHostLPUsage(ch chan<- prometheus.Metric) (*prom
|
||||
// The name format is Hv LP <core id>
|
||||
parts := strings.Split(obj.Name, " ")
|
||||
if len(parts) != 3 {
|
||||
log.Warnf("Unexpected format of Name in collectHostLPUsage: %q", obj.Name)
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Unexpected format of Name in collectHostLPUsage: %q", obj.Name))
|
||||
continue
|
||||
}
|
||||
coreId := parts[2]
|
||||
@@ -1094,7 +1097,7 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor struct {
|
||||
|
||||
func (c *HyperVCollector) collectHostCpuUsage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1106,7 +1109,7 @@ func (c *HyperVCollector) collectHostCpuUsage(ch chan<- prometheus.Metric) (*pro
|
||||
// The name format is Root VP <core id>
|
||||
parts := strings.Split(obj.Name, " ")
|
||||
if len(parts) != 3 {
|
||||
log.Warnf("Unexpected format of Name in collectHostCpuUsage: %q", obj.Name)
|
||||
_ = level.Warn(c.logger).Log("msg", "Unexpected format of Name in collectHostCpuUsage: "+obj.Name)
|
||||
continue
|
||||
}
|
||||
coreId := parts[2]
|
||||
@@ -1155,7 +1158,7 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor struct {
|
||||
|
||||
func (c *HyperVCollector) collectVmCpuUsage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1167,12 +1170,12 @@ func (c *HyperVCollector) collectVmCpuUsage(ch chan<- prometheus.Metric) (*prome
|
||||
// The name format is <VM Name>:Hv VP <vcore id>
|
||||
parts := strings.Split(obj.Name, ":")
|
||||
if len(parts) != 2 {
|
||||
log.Warnf("Unexpected format of Name in collectVmCpuUsage: %q, expected %q. Skipping.", obj.Name, "<VM Name>:Hv VP <vcore id>")
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Unexpected format of Name in collectVmCpuUsage: %q, expected %q. Skipping.", obj.Name, "<VM Name>:Hv VP <vcore id>"))
|
||||
continue
|
||||
}
|
||||
coreParts := strings.Split(parts[1], " ")
|
||||
if len(coreParts) != 3 {
|
||||
log.Warnf("Unexpected format of core identifier in collectVmCpuUsage: %q, expected %q. Skipping.", parts[1], "Hv VP <vcore id>")
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Unexpected format of core identifier in collectVmCpuUsage: %q, expected %q. Skipping.", parts[1], "Hv VP <vcore id>"))
|
||||
continue
|
||||
}
|
||||
vmName := parts[0]
|
||||
@@ -1242,7 +1245,7 @@ type Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch struct {
|
||||
|
||||
func (c *HyperVCollector) collectVmSwitch(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1377,6 +1380,12 @@ func (c *HyperVCollector) collectVmSwitch(ch chan<- prometheus.Metric) (*prometh
|
||||
float64(obj.PacketsReceivedPersec),
|
||||
obj.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(obj.PacketsSentPersec),
|
||||
obj.Name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PurgedMacAddresses,
|
||||
prometheus.CounterValue,
|
||||
@@ -1401,7 +1410,7 @@ type Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter struct {
|
||||
|
||||
func (c *HyperVCollector) collectVmEthernet(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1471,7 +1480,7 @@ type Win32_PerfRawData_Counters_HyperVVirtualStorageDevice struct {
|
||||
|
||||
func (c *HyperVCollector) collectVmStorage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_Counters_HyperVVirtualStorageDevice
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1540,7 +1549,7 @@ type Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter struct {
|
||||
|
||||
func (c *HyperVCollector) collectVmNetwork(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1613,7 +1622,7 @@ type Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM struct {
|
||||
|
||||
func (c *HyperVCollector) collectVmMemory(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkHypervCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "hyperv", NewHyperVCollector)
|
||||
benchmarkCollector(b, "hyperv", newHyperVCollector)
|
||||
}
|
||||
|
||||
361
collector/iis.go
361
collector/iis.go
@@ -4,24 +4,46 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("iis", NewIISCollector, "Web Service", "APP_POOL_WAS", "Web Service Cache", "W3SVC_W3WP")
|
||||
}
|
||||
const (
|
||||
FlagIISSiteOldExclude = "collector.iis.site-blacklist"
|
||||
FlagIISSiteOldInclude = "collector.iis.site-whitelist"
|
||||
FlagIISAppOldExclude = "collector.iis.app-blacklist"
|
||||
FlagIISAppOldInclude = "collector.iis.app-whitelist"
|
||||
|
||||
FlagIISSiteExclude = "collector.iis.site-exclude"
|
||||
FlagIISSiteInclude = "collector.iis.site-include"
|
||||
FlagIISAppExclude = "collector.iis.app-exclude"
|
||||
FlagIISAppInclude = "collector.iis.app-include"
|
||||
)
|
||||
|
||||
var (
|
||||
siteWhitelist = kingpin.Flag("collector.iis.site-whitelist", "Regexp of sites to whitelist. Site name must both match whitelist and not match blacklist to be included.").Default(".+").String()
|
||||
siteBlacklist = kingpin.Flag("collector.iis.site-blacklist", "Regexp of sites to blacklist. Site name must both match whitelist and not match blacklist to be included.").String()
|
||||
appWhitelist = kingpin.Flag("collector.iis.app-whitelist", "Regexp of apps to whitelist. App name must both match whitelist and not match blacklist to be included.").Default(".+").String()
|
||||
appBlacklist = kingpin.Flag("collector.iis.app-blacklist", "Regexp of apps to blacklist. App name must both match whitelist and not match blacklist to be included.").String()
|
||||
oldSiteInclude *string
|
||||
oldSiteExclude *string
|
||||
oldAppInclude *string
|
||||
oldAppExclude *string
|
||||
|
||||
siteInclude *string
|
||||
siteExclude *string
|
||||
appInclude *string
|
||||
appExclude *string
|
||||
|
||||
siteIncludeSet bool
|
||||
siteExcludeSet bool
|
||||
appIncludeSet bool
|
||||
appExcludeSet bool
|
||||
)
|
||||
|
||||
type simple_version struct {
|
||||
@@ -29,31 +51,31 @@ type simple_version struct {
|
||||
minor uint64
|
||||
}
|
||||
|
||||
func getIISVersion() simple_version {
|
||||
func getIISVersion(logger log.Logger) simple_version {
|
||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\InetStp\`, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
log.Warn("Couldn't open registry to determine IIS version:", err)
|
||||
_ = level.Warn(logger).Log("msg", "Couldn't open registry to determine IIS version", "err", err)
|
||||
return simple_version{}
|
||||
}
|
||||
defer func() {
|
||||
err = k.Close()
|
||||
if err != nil {
|
||||
log.Warnf("Failed to close registry key: %v", err)
|
||||
_ = level.Warn(logger).Log("msg", fmt.Sprintf("Failed to close registry key"), "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
major, _, err := k.GetIntegerValue("MajorVersion")
|
||||
if err != nil {
|
||||
log.Warn("Couldn't open registry to determine IIS version:", err)
|
||||
_ = level.Warn(logger).Log("msg", "Couldn't open registry to determine IIS version", "err", err)
|
||||
return simple_version{}
|
||||
}
|
||||
minor, _, err := k.GetIntegerValue("MinorVersion")
|
||||
if err != nil {
|
||||
log.Warn("Couldn't open registry to determine IIS version:", err)
|
||||
_ = level.Warn(logger).Log("msg", "Couldn't open registry to determine IIS version", "err", err)
|
||||
return simple_version{}
|
||||
}
|
||||
|
||||
log.Debugf("Detected IIS %d.%d\n", major, minor)
|
||||
_ = level.Debug(logger).Log("msg", fmt.Sprintf("Detected IIS %d.%d\n", major, minor))
|
||||
|
||||
return simple_version{
|
||||
major: major,
|
||||
@@ -62,6 +84,8 @@ func getIISVersion() simple_version {
|
||||
}
|
||||
|
||||
type IISCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
// Web Service
|
||||
CurrentAnonymousUsers *prometheus.Desc
|
||||
CurrentBlockedAsyncIORequests *prometheus.Desc
|
||||
@@ -86,8 +110,8 @@ type IISCollector struct {
|
||||
TotalNotFoundErrors *prometheus.Desc
|
||||
TotalRejectedAsyncIORequests *prometheus.Desc
|
||||
|
||||
siteWhitelistPattern *regexp.Regexp
|
||||
siteBlacklistPattern *regexp.Regexp
|
||||
siteIncludePattern *regexp.Regexp
|
||||
siteExcludePattern *regexp.Regexp
|
||||
|
||||
// APP_POOL_WAS
|
||||
CurrentApplicationPoolState *prometheus.Desc
|
||||
@@ -189,22 +213,97 @@ type IISCollector struct {
|
||||
ServiceCache_OutputCacheFlushedItemsTotal *prometheus.Desc
|
||||
ServiceCache_OutputCacheFlushesTotal *prometheus.Desc
|
||||
|
||||
appWhitelistPattern *regexp.Regexp
|
||||
appBlacklistPattern *regexp.Regexp
|
||||
appIncludePattern *regexp.Regexp
|
||||
appExcludePattern *regexp.Regexp
|
||||
|
||||
iis_version simple_version
|
||||
}
|
||||
|
||||
func NewIISCollector() (Collector, error) {
|
||||
func newIISCollectorFlags(app *kingpin.Application) {
|
||||
oldSiteInclude = app.Flag(FlagIISSiteOldInclude, "DEPRECATED: Use --collector.iis.site-include").Default(".+").Hidden().String()
|
||||
oldSiteExclude = app.Flag(FlagIISSiteOldExclude, "DEPRECATED: Use --collector.iis.site-exclude").Hidden().String()
|
||||
oldAppInclude = app.Flag(FlagIISAppOldInclude, "DEPRECATED: Use --collector.iis.app-include").Hidden().String()
|
||||
oldAppExclude = app.Flag(FlagIISAppOldExclude, "DEPRECATED: Use --collector.iis.app-exclude").Hidden().String()
|
||||
|
||||
siteInclude = app.Flag(
|
||||
FlagIISSiteInclude,
|
||||
"Regexp of sites to include. Site name must both match include and not match exclude to be included.",
|
||||
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
|
||||
siteIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
siteExclude = app.Flag(
|
||||
FlagIISSiteExclude,
|
||||
"Regexp of sites to exclude. Site name must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
siteExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
appInclude = app.Flag(
|
||||
FlagIISAppInclude,
|
||||
"Regexp of apps to include. App name must both match include and not match exclude to be included.",
|
||||
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
|
||||
appIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
appExclude = app.Flag(
|
||||
FlagIISAppExclude,
|
||||
"Regexp of apps to include. App name must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
siteExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
}
|
||||
|
||||
func newIISCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "iis"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *oldSiteExclude != "" {
|
||||
if !siteExcludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.iis.site-blacklist is DEPRECATED and will be removed in a future release, use --collector.iis.site-exclude")
|
||||
*siteExclude = *oldSiteExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.iis.site-blacklist and --collector.iis.site-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
if *oldSiteInclude != "" {
|
||||
if !siteIncludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.iis.site-whitelist is DEPRECATED and will be removed in a future release, use --collector.iis.site-include")
|
||||
*siteInclude = *oldSiteInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.iis.site-whitelist and --collector.iis.site-include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
if *oldAppExclude != "" {
|
||||
if !appExcludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.iis.app-blacklist is DEPRECATED and will be removed in a future release, use --collector.iis.app-exclude")
|
||||
*appExclude = *oldAppExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.iis.app-blacklist and --collector.iis.app-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
if *oldAppInclude != "" {
|
||||
if !appIncludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.iis.app-whitelist is DEPRECATED and will be removed in a future release, use --collector.iis.app-include")
|
||||
*appInclude = *oldAppInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.iis.app-whitelist and --collector.iis.app-include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
return &IISCollector{
|
||||
iis_version: getIISVersion(),
|
||||
logger: logger,
|
||||
iis_version: getIISVersion(logger),
|
||||
|
||||
siteWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteWhitelist)),
|
||||
siteBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteBlacklist)),
|
||||
appWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *appWhitelist)),
|
||||
appBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *appBlacklist)),
|
||||
siteIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteInclude)),
|
||||
siteExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteExclude)),
|
||||
appIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *appInclude)),
|
||||
appExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *appExclude)),
|
||||
|
||||
// Web Service
|
||||
CurrentAnonymousUsers: prometheus.NewDesc(
|
||||
@@ -821,22 +920,22 @@ func NewIISCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *IISCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collectWebService(ctx, ch); err != nil {
|
||||
log.Error("failed collecting iis metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectAPP_POOL_WAS(ctx, ch); err != nil {
|
||||
log.Error("failed collecting iis metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectW3SVC_W3WP(ctx, ch); err != nil {
|
||||
log.Error("failed collecting iis metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if desc, err := c.collectWebServiceCache(ctx, ch); err != nil {
|
||||
log.Error("failed collecting iis metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -886,14 +985,63 @@ type perflibWebService struct {
|
||||
TotalUnlockRequests float64 `perflib:"Total Unlock Requests"`
|
||||
}
|
||||
|
||||
// Fulfill the hasGetIISName interface
|
||||
func (p perflibWebService) getIISName() string {
|
||||
return p.Name
|
||||
}
|
||||
|
||||
// Fulfill the hasGetIISName interface
|
||||
func (p perflibAPP_POOL_WAS) getIISName() string {
|
||||
return p.Name
|
||||
}
|
||||
|
||||
// Fulfill the hasGetIISName interface
|
||||
func (p perflibW3SVC_W3WP) getIISName() string {
|
||||
return p.Name
|
||||
}
|
||||
|
||||
// Fulfill the hasGetIISName interface
|
||||
func (p perflibW3SVC_W3WP_IIS8) getIISName() string {
|
||||
return p.Name
|
||||
}
|
||||
|
||||
// Required as Golang doesn't allow access to struct fields in generic functions. That restriction may be removed in a future release.
|
||||
type hasGetIISName interface {
|
||||
getIISName() string
|
||||
}
|
||||
|
||||
// Deduplicate IIS site names from various IIS perflib objects.
|
||||
//
|
||||
// E.G. Given the following list of site names, "Site_B" would be
|
||||
// discarded, and "Site_B#2" would be kept and presented as "Site_B" in the
|
||||
// collector metrics.
|
||||
// [ "Site_A", "Site_B", "Site_C", "Site_B#2" ]
|
||||
func dedupIISNames[V hasGetIISName](services []V) map[string]V {
|
||||
// Ensure IIS entry with the highest suffix occurs last
|
||||
sort.SliceStable(services, func(i, j int) bool {
|
||||
return services[i].getIISName() < services[j].getIISName()
|
||||
})
|
||||
|
||||
var webServiceDeDuplicated = make(map[string]V)
|
||||
|
||||
// Use map to deduplicate IIS entries
|
||||
for _, entry := range services {
|
||||
name := strings.Split(entry.getIISName(), "#")[0]
|
||||
webServiceDeDuplicated[name] = entry
|
||||
}
|
||||
return webServiceDeDuplicated
|
||||
}
|
||||
|
||||
func (c *IISCollector) collectWebService(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var WebService []perflibWebService
|
||||
if err := unmarshalObject(ctx.perfObjects["Web Service"], &WebService); err != nil {
|
||||
var webService []perflibWebService
|
||||
if err := unmarshalObject(ctx.perfObjects["Web Service"], &webService, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, app := range WebService {
|
||||
if app.Name == "_Total" || c.siteBlacklistPattern.MatchString(app.Name) || !c.siteWhitelistPattern.MatchString(app.Name) {
|
||||
webServiceDeDuplicated := dedupIISNames(webService)
|
||||
|
||||
for name, app := range webServiceDeDuplicated {
|
||||
if name == "_Total" || c.siteExcludePattern.MatchString(name) || !c.siteIncludePattern.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -901,238 +1049,238 @@ func (c *IISCollector) collectWebService(ctx *ScrapeContext, ch chan<- prometheu
|
||||
c.CurrentAnonymousUsers,
|
||||
prometheus.GaugeValue,
|
||||
app.CurrentAnonymousUsers,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CurrentBlockedAsyncIORequests,
|
||||
prometheus.GaugeValue,
|
||||
app.CurrentBlockedAsyncIORequests,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CurrentCGIRequests,
|
||||
prometheus.GaugeValue,
|
||||
app.CurrentCGIRequests,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CurrentConnections,
|
||||
prometheus.GaugeValue,
|
||||
app.CurrentConnections,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CurrentISAPIExtensionRequests,
|
||||
prometheus.GaugeValue,
|
||||
app.CurrentISAPIExtensionRequests,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CurrentNonAnonymousUsers,
|
||||
prometheus.GaugeValue,
|
||||
app.CurrentNonAnonymousUsers,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ServiceUptime,
|
||||
prometheus.GaugeValue,
|
||||
app.ServiceUptime,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalBytesReceived,
|
||||
prometheus.CounterValue,
|
||||
app.TotalBytesReceived,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalBytesSent,
|
||||
prometheus.CounterValue,
|
||||
app.TotalBytesSent,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalAnonymousUsers,
|
||||
prometheus.CounterValue,
|
||||
app.TotalAnonymousUsers,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalBlockedAsyncIORequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalBlockedAsyncIORequests,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalCGIRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalCGIRequests,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalConnectionAttemptsAllInstances,
|
||||
prometheus.CounterValue,
|
||||
app.TotalConnectionAttemptsAllInstances,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalFilesReceived,
|
||||
prometheus.CounterValue,
|
||||
app.TotalFilesReceived,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalFilesSent,
|
||||
prometheus.CounterValue,
|
||||
app.TotalFilesSent,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalISAPIExtensionRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalISAPIExtensionRequests,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalLockedErrors,
|
||||
prometheus.CounterValue,
|
||||
app.TotalLockedErrors,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalLogonAttempts,
|
||||
prometheus.CounterValue,
|
||||
app.TotalLogonAttempts,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalNonAnonymousUsers,
|
||||
prometheus.CounterValue,
|
||||
app.TotalNonAnonymousUsers,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalNotFoundErrors,
|
||||
prometheus.CounterValue,
|
||||
app.TotalNotFoundErrors,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRejectedAsyncIORequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalRejectedAsyncIORequests,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalOtherRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"other",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalCopyRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"COPY",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalDeleteRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"DELETE",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalGetRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"GET",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalHeadRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"HEAD",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalLockRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"LOCK",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalMkcolRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"MKCOL",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalMoveRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"MOVE",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalOptionsRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"OPTIONS",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalPostRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"POST",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalPropfindRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"PROPFIND",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalProppatchRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"PROPPATCH",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalPutRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"PUT",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalSearchRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"SEARCH",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalTraceRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"TRACE",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalRequests,
|
||||
prometheus.CounterValue,
|
||||
app.TotalUnlockRequests,
|
||||
app.Name,
|
||||
name,
|
||||
"UNLOCK",
|
||||
)
|
||||
}
|
||||
@@ -1172,14 +1320,16 @@ var applicationStates = map[uint32]string{
|
||||
|
||||
func (c *IISCollector) collectAPP_POOL_WAS(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var APP_POOL_WAS []perflibAPP_POOL_WAS
|
||||
if err := unmarshalObject(ctx.perfObjects["APP_POOL_WAS"], &APP_POOL_WAS); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["APP_POOL_WAS"], &APP_POOL_WAS, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, app := range APP_POOL_WAS {
|
||||
if app.Name == "_Total" ||
|
||||
c.appBlacklistPattern.MatchString(app.Name) ||
|
||||
!c.appWhitelistPattern.MatchString(app.Name) {
|
||||
appPoolDeDuplicated := dedupIISNames(APP_POOL_WAS)
|
||||
|
||||
for name, app := range appPoolDeDuplicated {
|
||||
if name == "_Total" ||
|
||||
c.appExcludePattern.MatchString(name) ||
|
||||
!c.appIncludePattern.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1192,7 +1342,7 @@ func (c *IISCollector) collectAPP_POOL_WAS(ctx *ScrapeContext, ch chan<- prometh
|
||||
c.CurrentApplicationPoolState,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
app.Name,
|
||||
name,
|
||||
label,
|
||||
)
|
||||
}
|
||||
@@ -1201,73 +1351,73 @@ func (c *IISCollector) collectAPP_POOL_WAS(ctx *ScrapeContext, ch chan<- prometh
|
||||
c.CurrentApplicationPoolUptime,
|
||||
prometheus.GaugeValue,
|
||||
app.CurrentApplicationPoolUptime,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.CurrentWorkerProcesses,
|
||||
prometheus.GaugeValue,
|
||||
app.CurrentWorkerProcesses,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.MaximumWorkerProcesses,
|
||||
prometheus.GaugeValue,
|
||||
app.MaximumWorkerProcesses,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RecentWorkerProcessFailures,
|
||||
prometheus.GaugeValue,
|
||||
app.RecentWorkerProcessFailures,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TimeSinceLastWorkerProcessFailure,
|
||||
prometheus.GaugeValue,
|
||||
app.TimeSinceLastWorkerProcessFailure,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalApplicationPoolRecycles,
|
||||
prometheus.CounterValue,
|
||||
app.TotalApplicationPoolRecycles,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalApplicationPoolUptime,
|
||||
prometheus.CounterValue,
|
||||
app.TotalApplicationPoolUptime,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalWorkerProcessesCreated,
|
||||
prometheus.CounterValue,
|
||||
app.TotalWorkerProcessesCreated,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalWorkerProcessFailures,
|
||||
prometheus.CounterValue,
|
||||
app.TotalWorkerProcessFailures,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalWorkerProcessPingFailures,
|
||||
prometheus.CounterValue,
|
||||
app.TotalWorkerProcessPingFailures,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalWorkerProcessShutdownFailures,
|
||||
prometheus.CounterValue,
|
||||
app.TotalWorkerProcessShutdownFailures,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TotalWorkerProcessStartupFailures,
|
||||
prometheus.CounterValue,
|
||||
app.TotalWorkerProcessStartupFailures,
|
||||
app.Name,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1347,17 +1497,24 @@ type perflibW3SVC_W3WP_IIS8 struct {
|
||||
|
||||
func (c *IISCollector) collectW3SVC_W3WP(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var W3SVC_W3WP []perflibW3SVC_W3WP
|
||||
if err := unmarshalObject(ctx.perfObjects["W3SVC_W3WP"], &W3SVC_W3WP); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["W3SVC_W3WP"], &W3SVC_W3WP, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, app := range W3SVC_W3WP {
|
||||
w3svcW3WPDeduplicated := dedupIISNames(W3SVC_W3WP)
|
||||
|
||||
for w3Name, app := range w3svcW3WPDeduplicated {
|
||||
// Extract the apppool name from the format <PID>_<NAME>
|
||||
pid := workerProcessNameExtractor.ReplaceAllString(app.Name, "$1")
|
||||
name := workerProcessNameExtractor.ReplaceAllString(app.Name, "$2")
|
||||
pid := workerProcessNameExtractor.ReplaceAllString(w3Name, "$1")
|
||||
name := workerProcessNameExtractor.ReplaceAllString(w3Name, "$2")
|
||||
if name == "" || name == "_Total" ||
|
||||
c.appBlacklistPattern.MatchString(name) ||
|
||||
!c.appWhitelistPattern.MatchString(name) {
|
||||
c.appExcludePattern.MatchString(name) ||
|
||||
!c.appIncludePattern.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Duplicate instances are suffixed # with an index number. These should be ignored
|
||||
if strings.Contains(app.Name, "#") {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1599,17 +1756,19 @@ func (c *IISCollector) collectW3SVC_W3WP(ctx *ScrapeContext, ch chan<- prometheu
|
||||
|
||||
if c.iis_version.major >= 8 {
|
||||
var W3SVC_W3WP_IIS8 []perflibW3SVC_W3WP_IIS8
|
||||
if err := unmarshalObject(ctx.perfObjects["W3SVC_W3WP"], &W3SVC_W3WP_IIS8); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["W3SVC_W3WP"], &W3SVC_W3WP_IIS8, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, app := range W3SVC_W3WP_IIS8 {
|
||||
w3svcW3WPIIS8Deduplicated := dedupIISNames(W3SVC_W3WP_IIS8)
|
||||
|
||||
for w3Name, app := range w3svcW3WPIIS8Deduplicated {
|
||||
// Extract the apppool name from the format <PID>_<NAME>
|
||||
pid := workerProcessNameExtractor.ReplaceAllString(app.Name, "$1")
|
||||
name := workerProcessNameExtractor.ReplaceAllString(app.Name, "$2")
|
||||
pid := workerProcessNameExtractor.ReplaceAllString(w3Name, "$1")
|
||||
name := workerProcessNameExtractor.ReplaceAllString(w3Name, "$2")
|
||||
if name == "" || name == "_Total" ||
|
||||
c.appBlacklistPattern.MatchString(name) ||
|
||||
!c.appWhitelistPattern.MatchString(name) {
|
||||
c.appExcludePattern.MatchString(name) ||
|
||||
!c.appIncludePattern.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1736,7 +1895,7 @@ type perflibWebServiceCache struct {
|
||||
|
||||
func (c *IISCollector) collectWebServiceCache(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var WebServiceCache []perflibWebServiceCache
|
||||
if err := unmarshalObject(ctx.perfObjects["Web Service Cache"], &WebServiceCache); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["Web Service Cache"], &WebServiceCache, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,49 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkIISCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "iis", NewIISCollector)
|
||||
benchmarkCollector(b, "iis", newIISCollector)
|
||||
}
|
||||
|
||||
func TestIISDeduplication(t *testing.T) {
|
||||
start := []perflibAPP_POOL_WAS{
|
||||
{
|
||||
Name: "foo",
|
||||
Frequency_Object: 1,
|
||||
},
|
||||
{
|
||||
Name: "foo1#999",
|
||||
Frequency_Object: 2,
|
||||
},
|
||||
{
|
||||
Name: "foo#2",
|
||||
Frequency_Object: 3,
|
||||
},
|
||||
{
|
||||
Name: "bar$2",
|
||||
Frequency_Object: 4,
|
||||
},
|
||||
{
|
||||
Name: "bar_2",
|
||||
Frequency_Object: 5,
|
||||
},
|
||||
}
|
||||
var expected = make(map[string]perflibAPP_POOL_WAS)
|
||||
// Should be deduplicated from "foo#2"
|
||||
expected["foo"] = perflibAPP_POOL_WAS{Name: "foo#2", Frequency_Object: 3}
|
||||
// Map key should have suffix stripped, but struct name field should be unchanged
|
||||
expected["foo1"] = perflibAPP_POOL_WAS{Name: "foo1#999", Frequency_Object: 2}
|
||||
// Map key and Name should be identical, as there is no suffix starting with "#"
|
||||
expected["bar$2"] = perflibAPP_POOL_WAS{Name: "bar$2", Frequency_Object: 4}
|
||||
// Map key and Name should be identical, as there is no suffix starting with "#"
|
||||
expected["bar_2"] = perflibAPP_POOL_WAS{Name: "bar_2", Frequency_Object: 5}
|
||||
|
||||
deduplicated := dedupIISNames(start)
|
||||
if !reflect.DeepEqual(expected, deduplicated) {
|
||||
t.Errorf("Flattened values do not match!\nExpected result: %+v\nActual result: %+v", expected, deduplicated)
|
||||
}
|
||||
}
|
||||
|
||||
415
collector/init.go
Normal file
415
collector/init.go
Normal file
@@ -0,0 +1,415 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
)
|
||||
|
||||
// collectorInit represents the required initialisation config for a collector.
|
||||
type collectorInit struct {
|
||||
// Name of collector to be initialised
|
||||
name string
|
||||
// Builder function for the collector
|
||||
flags flagsBuilder
|
||||
// Builder function for the collector
|
||||
builder collectorBuilder
|
||||
// Perflib counter names for the collector.
|
||||
// These will be included in the Perflib scrape scope by the exporter.
|
||||
perfCounterFunc perfCounterNamesBuilder
|
||||
}
|
||||
|
||||
func getDFSRCollectorDeps(_ log.Logger) []string {
|
||||
// Perflib sources are dynamic, depending on the enabled child collectors
|
||||
var perflibDependencies []string
|
||||
for _, source := range expandEnabledChildCollectors(*dfsrEnabledCollectors) {
|
||||
perflibDependencies = append(perflibDependencies, dfsrGetPerfObjectName(source))
|
||||
}
|
||||
|
||||
return perflibDependencies
|
||||
}
|
||||
|
||||
var collectors = []collectorInit{
|
||||
{
|
||||
name: "ad",
|
||||
flags: nil,
|
||||
builder: newADCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "adcs",
|
||||
flags: nil,
|
||||
builder: adcsCollectorMethod,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Certification Authority"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "adfs",
|
||||
flags: nil,
|
||||
builder: newADFSCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"AD FS"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cache",
|
||||
flags: nil,
|
||||
builder: newCacheCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Cache"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "container",
|
||||
flags: nil,
|
||||
builder: newContainerMetricsCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "cpu",
|
||||
flags: nil,
|
||||
builder: newCPUCollector,
|
||||
perfCounterFunc: func(logger log.Logger) []string {
|
||||
if getWindowsVersion(logger) > 6.05 {
|
||||
return []string{"Processor Information"}
|
||||
}
|
||||
return []string{"Processor"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cpu_info",
|
||||
flags: nil,
|
||||
builder: newCpuInfoCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "cs",
|
||||
flags: nil,
|
||||
builder: newCSCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "dfsr",
|
||||
flags: newDFSRCollectorFlags,
|
||||
builder: newDFSRCollector,
|
||||
perfCounterFunc: getDFSRCollectorDeps,
|
||||
},
|
||||
{
|
||||
name: "dhcp",
|
||||
flags: nil,
|
||||
builder: newDhcpCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "diskdrive",
|
||||
flags: nil,
|
||||
builder: newDiskDriveInfoCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "dns",
|
||||
flags: nil,
|
||||
builder: newDNSCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "exchange",
|
||||
flags: newExchangeCollectorFlags,
|
||||
builder: newExchangeCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{
|
||||
"MSExchange ADAccess Processes",
|
||||
"MSExchangeTransport Queues",
|
||||
"MSExchange HttpProxy",
|
||||
"MSExchange ActiveSync",
|
||||
"MSExchange Availability Service",
|
||||
"MSExchange OWA",
|
||||
"MSExchangeAutodiscover",
|
||||
"MSExchange WorkloadManagement Workloads",
|
||||
"MSExchange RpcClientAccess",
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "fsrmquota",
|
||||
flags: nil,
|
||||
builder: newFSRMQuotaCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "hyperv",
|
||||
flags: nil,
|
||||
builder: newHyperVCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "iis",
|
||||
flags: newIISCollectorFlags,
|
||||
builder: newIISCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{
|
||||
"Web Service",
|
||||
"APP_POOL_WAS",
|
||||
"Web Service Cache",
|
||||
"W3SVC_W3WP",
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "logical_disk",
|
||||
flags: newLogicalDiskCollectorFlags,
|
||||
builder: newLogicalDiskCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"LogicalDisk"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "logon",
|
||||
flags: nil,
|
||||
builder: newLogonCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "memory",
|
||||
flags: nil,
|
||||
builder: newMemoryCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Memory"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "mscluster_cluster",
|
||||
flags: nil,
|
||||
builder: newMSCluster_ClusterCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mscluster_network",
|
||||
flags: nil,
|
||||
builder: newMSCluster_NetworkCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mscluster_node",
|
||||
flags: nil,
|
||||
builder: newMSCluster_NodeCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mscluster_resource",
|
||||
flags: nil,
|
||||
builder: newMSCluster_ResourceCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mscluster_resourcegroup",
|
||||
flags: nil,
|
||||
builder: newMSCluster_ResourceGroupCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "msmq",
|
||||
flags: newMSMQCollectorFlags,
|
||||
builder: newMSMQCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "mssql",
|
||||
flags: newMSSQLCollectorFlags,
|
||||
builder: newMSSQLCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "net",
|
||||
flags: newNetworkCollectorFlags,
|
||||
builder: newNetworkCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Network Interface"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "netframework_clrexceptions",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRExceptionsCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrinterop",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRInteropCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrjit",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRJitCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrloading",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRLoadingCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrlocksandthreads",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRLocksAndThreadsCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrmemory",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRMemoryCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrremoting",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRRemotingCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "netframework_clrsecurity",
|
||||
flags: nil,
|
||||
builder: newNETFramework_NETCLRSecurityCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "nps",
|
||||
builder: newNPSCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "os",
|
||||
flags: nil,
|
||||
builder: newOSCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Paging File"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "process",
|
||||
flags: newProcessCollectorFlags,
|
||||
builder: newProcessCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Process"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remote_fx",
|
||||
flags: nil,
|
||||
builder: newRemoteFx,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"RemoteFX Network"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scheduled_task",
|
||||
flags: newScheduledTaskFlags,
|
||||
builder: newScheduledTask,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "service",
|
||||
flags: newServiceCollectorFlags,
|
||||
builder: newserviceCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "smtp",
|
||||
flags: newSMTPCollectorFlags,
|
||||
builder: newSMTPCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"SMTP Server"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "system",
|
||||
flags: nil,
|
||||
builder: newSystemCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"System"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "teradici_pcoip",
|
||||
flags: nil,
|
||||
builder: newTeradiciPcoipCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "tcp",
|
||||
flags: nil,
|
||||
builder: newTCPCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"TCPv4"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "terminal_services",
|
||||
flags: nil,
|
||||
builder: newTerminalServicesCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{
|
||||
"Terminal Services",
|
||||
"Terminal Services Session",
|
||||
"Remote Desktop Connection Broker Counterset",
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "textfile",
|
||||
flags: newTextFileCollectorFlags,
|
||||
builder: newTextFileCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "thermalzone",
|
||||
flags: nil,
|
||||
builder: newThermalZoneCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "time",
|
||||
flags: nil,
|
||||
builder: newTimeCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"Windows Time Service"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "vmware",
|
||||
flags: nil,
|
||||
builder: newVmwareCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
{
|
||||
name: "vmware_blast",
|
||||
flags: nil,
|
||||
builder: newVmwareBlastCollector,
|
||||
perfCounterFunc: nil,
|
||||
},
|
||||
}
|
||||
|
||||
// RegisterCollectorsFlags To be called by the exporter for collector initialisation before running app.Parse
|
||||
func RegisterCollectorsFlags(app *kingpin.Application) {
|
||||
for _, v := range collectors {
|
||||
if v.flags != nil {
|
||||
v.flags(app)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterCollectors To be called by the exporter for collector initialisation
|
||||
func RegisterCollectors(logger log.Logger) {
|
||||
for _, v := range collectors {
|
||||
var perfCounterNames []string
|
||||
|
||||
if v.perfCounterFunc != nil {
|
||||
perfCounterNames = v.perfCounterFunc(logger)
|
||||
}
|
||||
|
||||
registerCollector(v.name, v.builder, perfCounterNames...)
|
||||
}
|
||||
}
|
||||
@@ -4,31 +4,39 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("logical_disk", NewLogicalDiskCollector, "LogicalDisk")
|
||||
}
|
||||
const (
|
||||
FlagLogicalDiskVolumeOldExclude = "collector.logical_disk.volume-blacklist"
|
||||
FlagLogicalDiskVolumeOldInclude = "collector.logical_disk.volume-whitelist"
|
||||
|
||||
FlagLogicalDiskVolumeExclude = "collector.logical_disk.volume-exclude"
|
||||
FlagLogicalDiskVolumeInclude = "collector.logical_disk.volume-include"
|
||||
)
|
||||
|
||||
var (
|
||||
volumeWhitelist = kingpin.Flag(
|
||||
"collector.logical_disk.volume-whitelist",
|
||||
"Regexp of volumes to whitelist. Volume name must both match whitelist and not match blacklist to be included.",
|
||||
).Default(".+").String()
|
||||
volumeBlacklist = kingpin.Flag(
|
||||
"collector.logical_disk.volume-blacklist",
|
||||
"Regexp of volumes to blacklist. Volume name must both match whitelist and not match blacklist to be included.",
|
||||
).Default("").String()
|
||||
volumeOldInclude *string
|
||||
volumeOldExclude *string
|
||||
|
||||
volumeInclude *string
|
||||
volumeExclude *string
|
||||
|
||||
volumeIncludeSet bool
|
||||
volumeExcludeSet bool
|
||||
)
|
||||
|
||||
// A LogicalDiskCollector is a Prometheus collector for perflib logicalDisk metrics
|
||||
type LogicalDiskCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
RequestsQueued *prometheus.Desc
|
||||
AvgReadQueue *prometheus.Desc
|
||||
AvgWriteQueue *prometheus.Desc
|
||||
@@ -46,15 +54,63 @@ type LogicalDiskCollector struct {
|
||||
WriteLatency *prometheus.Desc
|
||||
ReadWriteLatency *prometheus.Desc
|
||||
|
||||
volumeWhitelistPattern *regexp.Regexp
|
||||
volumeBlacklistPattern *regexp.Regexp
|
||||
volumeIncludePattern *regexp.Regexp
|
||||
volumeExcludePattern *regexp.Regexp
|
||||
}
|
||||
|
||||
// NewLogicalDiskCollector ...
|
||||
func NewLogicalDiskCollector() (Collector, error) {
|
||||
// newLogicalDiskCollectorFlags ...
|
||||
func newLogicalDiskCollectorFlags(app *kingpin.Application) {
|
||||
volumeInclude = app.Flag(
|
||||
FlagLogicalDiskVolumeInclude,
|
||||
"Regexp of volumes to include. Volume name must both match include and not match exclude to be included.",
|
||||
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
|
||||
volumeIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
volumeExclude = app.Flag(
|
||||
FlagLogicalDiskVolumeExclude,
|
||||
"Regexp of volumes to exclude. Volume name must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
volumeExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
volumeOldInclude = app.Flag(
|
||||
FlagLogicalDiskVolumeOldInclude,
|
||||
"DEPRECATED: Use --collector.logical_disk.volume-include",
|
||||
).Hidden().String()
|
||||
volumeOldExclude = app.Flag(
|
||||
FlagLogicalDiskVolumeOldExclude,
|
||||
"DEPRECATED: Use --collector.logical_disk.volume-exclude",
|
||||
).Hidden().String()
|
||||
}
|
||||
|
||||
// newLogicalDiskCollector ...
|
||||
func newLogicalDiskCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "logical_disk"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *volumeOldExclude != "" {
|
||||
if !volumeExcludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.logical_disk.volume-blacklist is DEPRECATED and will be removed in a future release, use --collector.logical_disk.volume-exclude")
|
||||
*volumeExclude = *volumeOldExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.logical_disk.volume-blacklist and --collector.logical_disk.volume-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
if *volumeOldInclude != "" {
|
||||
if !volumeIncludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.logical_disk.volume-whitelist is DEPRECATED and will be removed in a future release, use --collector.logical_disk.volume-include")
|
||||
*volumeInclude = *volumeOldInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.logical_disk.volume-whitelist and --collector.logical_disk.volume-include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
return &LogicalDiskCollector{
|
||||
logger: logger,
|
||||
|
||||
RequestsQueued: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "requests_queued"),
|
||||
"The number of requests queued to the disk (LogicalDisk.CurrentDiskQueueLength)",
|
||||
@@ -167,8 +223,8 @@ func NewLogicalDiskCollector() (Collector, error) {
|
||||
nil,
|
||||
),
|
||||
|
||||
volumeWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeWhitelist)),
|
||||
volumeBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeBlacklist)),
|
||||
volumeIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeInclude)),
|
||||
volumeExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeExclude)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -176,7 +232,7 @@ func NewLogicalDiskCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *LogicalDiskCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
log.Error("failed collecting logical_disk metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting logical_disk metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -207,14 +263,14 @@ type logicalDisk struct {
|
||||
|
||||
func (c *LogicalDiskCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []logicalDisk
|
||||
if err := unmarshalObject(ctx.perfObjects["LogicalDisk"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["LogicalDisk"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, volume := range dst {
|
||||
if volume.Name == "_Total" ||
|
||||
c.volumeBlacklistPattern.MatchString(volume.Name) ||
|
||||
!c.volumeWhitelistPattern.MatchString(volume.Name) {
|
||||
c.volumeExcludePattern.MatchString(volume.Name) ||
|
||||
!c.volumeIncludePattern.MatchString(volume.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
|
||||
func BenchmarkLogicalDiskCollector(b *testing.B) {
|
||||
// Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all disks.
|
||||
localVolumeWhitelist := ".+"
|
||||
volumeWhitelist = &localVolumeWhitelist
|
||||
localVolumeInclude := ".+"
|
||||
volumeInclude = &localVolumeInclude
|
||||
|
||||
benchmarkCollector(b, "logical_disk", NewLogicalDiskCollector)
|
||||
benchmarkCollector(b, "logical_disk", newLogicalDiskCollector)
|
||||
}
|
||||
|
||||
@@ -6,25 +6,25 @@ package collector
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("logon", NewLogonCollector)
|
||||
}
|
||||
|
||||
// A LogonCollector is a Prometheus collector for WMI metrics
|
||||
type LogonCollector struct {
|
||||
logger log.Logger
|
||||
LogonType *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewLogonCollector ...
|
||||
func NewLogonCollector() (Collector, error) {
|
||||
// newLogonCollector ...
|
||||
func newLogonCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "logon"
|
||||
|
||||
return &LogonCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
LogonType: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "logon_type"),
|
||||
"Number of active logon sessions (LogonSession.LogonType)",
|
||||
@@ -38,7 +38,7 @@ func NewLogonCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *LogonCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting user metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting user metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -52,7 +52,7 @@ type Win32_LogonSession struct {
|
||||
|
||||
func (c *LogonCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_LogonSession
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkLogonCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewLogonCollector)
|
||||
benchmarkCollector(b, "", newLogonCollector)
|
||||
}
|
||||
|
||||
@@ -7,16 +7,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("memory", NewMemoryCollector, "Memory")
|
||||
}
|
||||
|
||||
// A MemoryCollector is a Prometheus collector for perflib Memory metrics
|
||||
type MemoryCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AvailableBytes *prometheus.Desc
|
||||
CacheBytes *prometheus.Desc
|
||||
CacheBytesPeak *prometheus.Desc
|
||||
@@ -51,11 +50,13 @@ type MemoryCollector struct {
|
||||
WriteCopiesTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewMemoryCollector ...
|
||||
func NewMemoryCollector() (Collector, error) {
|
||||
// newMemoryCollector ...
|
||||
func newMemoryCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "memory"
|
||||
|
||||
return &MemoryCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
AvailableBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "available_bytes"),
|
||||
"The amount of physical memory immediately available for allocation to a process or for system use. It is equal to the sum of memory assigned to"+
|
||||
@@ -267,7 +268,7 @@ func NewMemoryCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MemoryCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
log.Error("failed collecting memory metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting memory metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -312,7 +313,7 @@ type memory struct {
|
||||
|
||||
func (c *MemoryCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []memory
|
||||
if err := unmarshalObject(ctx.perfObjects["Memory"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["Memory"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkMemoryCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "memory", NewMemoryCollector)
|
||||
benchmarkCollector(b, "memory", newMemoryCollector)
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("mscluster_cluster", newMSCluster_ClusterCollector)
|
||||
}
|
||||
|
||||
// A MSCluster_ClusterCollector is a Prometheus collector for WMI MSCluster_Cluster metrics
|
||||
type MSCluster_ClusterCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AddEvictDelay *prometheus.Desc
|
||||
AdminAccessPoint *prometheus.Desc
|
||||
AutoAssignNodeSite *prometheus.Desc
|
||||
@@ -90,9 +89,11 @@ type MSCluster_ClusterCollector struct {
|
||||
WitnessRestartInterval *prometheus.Desc
|
||||
}
|
||||
|
||||
func newMSCluster_ClusterCollector() (Collector, error) {
|
||||
func newMSCluster_ClusterCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mscluster_cluster"
|
||||
return &MSCluster_ClusterCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
AddEvictDelay: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "add_evict_delay"),
|
||||
"Provides access to the cluster's AddEvictDelay property, which is the number a seconds that a new node is delayed after an eviction of another node.",
|
||||
@@ -560,7 +561,6 @@ func newMSCluster_ClusterCollector() (Collector, error) {
|
||||
|
||||
// MSCluster_Cluster docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-cluster
|
||||
//
|
||||
type MSCluster_Cluster struct {
|
||||
Name string
|
||||
|
||||
@@ -647,7 +647,7 @@ type MSCluster_Cluster struct {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MSCluster_ClusterCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []MSCluster_Cluster
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("mscluster_network", newMSCluster_NetworkCollector)
|
||||
}
|
||||
|
||||
// A MSCluster_NetworkCollector is a Prometheus collector for WMI MSCluster_Network metrics
|
||||
type MSCluster_NetworkCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
Characteristics *prometheus.Desc
|
||||
Flags *prometheus.Desc
|
||||
Metric *prometheus.Desc
|
||||
@@ -18,9 +17,11 @@ type MSCluster_NetworkCollector struct {
|
||||
State *prometheus.Desc
|
||||
}
|
||||
|
||||
func newMSCluster_NetworkCollector() (Collector, error) {
|
||||
func newMSCluster_NetworkCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mscluster_network"
|
||||
return &MSCluster_NetworkCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
Characteristics: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
|
||||
"Provides the characteristics of the network.",
|
||||
@@ -56,7 +57,6 @@ func newMSCluster_NetworkCollector() (Collector, error) {
|
||||
|
||||
// MSCluster_Network docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-network
|
||||
//
|
||||
type MSCluster_Network struct {
|
||||
Name string
|
||||
|
||||
@@ -71,7 +71,7 @@ type MSCluster_Network struct {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MSCluster_NetworkCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []MSCluster_Network
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("mscluster_node", newMSCluster_NodeCollector)
|
||||
}
|
||||
|
||||
// A MSCluster_NodeCollector is a Prometheus collector for WMI MSCluster_Node metrics
|
||||
type MSCluster_NodeCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
BuildNumber *prometheus.Desc
|
||||
Characteristics *prometheus.Desc
|
||||
DetectedCloudPlatform *prometheus.Desc
|
||||
@@ -27,9 +26,10 @@ type MSCluster_NodeCollector struct {
|
||||
StatusInformation *prometheus.Desc
|
||||
}
|
||||
|
||||
func newMSCluster_NodeCollector() (Collector, error) {
|
||||
func newMSCluster_NodeCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mscluster_node"
|
||||
return &MSCluster_NodeCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
BuildNumber: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "build_number"),
|
||||
"Provides access to the node's BuildNumber property.",
|
||||
@@ -119,7 +119,6 @@ func newMSCluster_NodeCollector() (Collector, error) {
|
||||
|
||||
// MSCluster_Node docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-node
|
||||
//
|
||||
type MSCluster_Node struct {
|
||||
Name string
|
||||
|
||||
@@ -143,7 +142,7 @@ type MSCluster_Node struct {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MSCluster_NodeCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []MSCluster_Node
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("mscluster_resource", newMSCluster_ResourceCollector)
|
||||
}
|
||||
|
||||
// A MSCluster_ResourceCollector is a Prometheus collector for WMI MSCluster_Resource metrics
|
||||
type MSCluster_ResourceCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
Characteristics *prometheus.Desc
|
||||
DeadlockTimeout *prometheus.Desc
|
||||
EmbeddedFailureAction *prometheus.Desc
|
||||
@@ -29,9 +28,10 @@ type MSCluster_ResourceCollector struct {
|
||||
Subclass *prometheus.Desc
|
||||
}
|
||||
|
||||
func newMSCluster_ResourceCollector() (Collector, error) {
|
||||
func newMSCluster_ResourceCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mscluster_resource"
|
||||
return &MSCluster_ResourceCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
Characteristics: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
|
||||
"Provides the characteristics of the object.",
|
||||
@@ -133,7 +133,6 @@ func newMSCluster_ResourceCollector() (Collector, error) {
|
||||
|
||||
// MSCluster_Resource docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resource
|
||||
//
|
||||
type MSCluster_Resource struct {
|
||||
Name string
|
||||
Type string
|
||||
@@ -161,7 +160,7 @@ type MSCluster_Resource struct {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MSCluster_ResourceCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []MSCluster_Resource
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("mscluster_resourcegroup", newMSCluster_ResourceGroupCollector)
|
||||
}
|
||||
|
||||
// A MSCluster_ResourceGroupCollector is a Prometheus collector for WMI MSCluster_ResourceGroup metrics
|
||||
type MSCluster_ResourceGroupCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AutoFailbackType *prometheus.Desc
|
||||
Characteristics *prometheus.Desc
|
||||
ColdStartSetting *prometheus.Desc
|
||||
@@ -28,9 +27,10 @@ type MSCluster_ResourceGroupCollector struct {
|
||||
State *prometheus.Desc
|
||||
}
|
||||
|
||||
func newMSCluster_ResourceGroupCollector() (Collector, error) {
|
||||
func newMSCluster_ResourceGroupCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mscluster_resourcegroup"
|
||||
return &MSCluster_ResourceGroupCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
AutoFailbackType: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "auto_failback_type"),
|
||||
"Provides access to the group's AutoFailbackType property.",
|
||||
@@ -114,7 +114,6 @@ func newMSCluster_ResourceGroupCollector() (Collector, error) {
|
||||
|
||||
// MSCluster_ResourceGroup docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resourcegroup
|
||||
//
|
||||
type MSCluster_ResourceGroup struct {
|
||||
Name string
|
||||
|
||||
@@ -137,7 +136,7 @@ type MSCluster_ResourceGroup struct {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *MSCluster_ResourceGroupCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
var dst []MSCluster_ResourceGroup
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,22 +6,25 @@ package collector
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("msmq", NewMSMQCollector)
|
||||
}
|
||||
const (
|
||||
FlagMsmqWhereClause = "collector.msmq.msmq-where"
|
||||
)
|
||||
|
||||
var (
|
||||
msmqWhereClause = kingpin.Flag("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.").String()
|
||||
msmqWhereClause *string
|
||||
)
|
||||
|
||||
// A Win32_PerfRawData_MSMQ_MSMQQueueCollector is a Prometheus collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics
|
||||
type Win32_PerfRawData_MSMQ_MSMQQueueCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
BytesinJournalQueue *prometheus.Desc
|
||||
BytesinQueue *prometheus.Desc
|
||||
MessagesinJournalQueue *prometheus.Desc
|
||||
@@ -30,15 +33,23 @@ type Win32_PerfRawData_MSMQ_MSMQQueueCollector struct {
|
||||
queryWhereClause string
|
||||
}
|
||||
|
||||
// newMSMQCollectorFlags ..
|
||||
func newMSMQCollectorFlags(app *kingpin.Application) {
|
||||
msmqWhereClause = app.Flag(FlagMsmqWhereClause, "WQL 'where' clause to use in WMI metrics query. Limits the response to the msmqs you specify and reduces the size of the response.").String()
|
||||
}
|
||||
|
||||
// NewWin32_PerfRawData_MSMQ_MSMQQueueCollector ...
|
||||
func NewMSMQCollector() (Collector, error) {
|
||||
func newMSMQCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "msmq"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *msmqWhereClause == "" {
|
||||
log.Warn("No where-clause specified for msmq collector. This will generate a very large number of metrics!")
|
||||
_ = level.Warn(logger).Log("msg", "No where-clause specified for msmq collector. This will generate a very large number of metrics!")
|
||||
}
|
||||
|
||||
return &Win32_PerfRawData_MSMQ_MSMQQueueCollector{
|
||||
logger: logger,
|
||||
|
||||
BytesinJournalQueue: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "bytes_in_journal_queue"),
|
||||
"Size of queue journal in bytes",
|
||||
@@ -71,7 +82,7 @@ func NewMSMQCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Win32_PerfRawData_MSMQ_MSMQQueueCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting msmq metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting msmq metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -88,7 +99,7 @@ type Win32_PerfRawData_MSMQ_MSMQQueue struct {
|
||||
|
||||
func (c *Win32_PerfRawData_MSMQ_MSMQQueueCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_MSMQ_MSMQQueue
|
||||
q := queryAllWhere(&dst, c.queryWhereClause)
|
||||
q := queryAllWhere(&dst, c.queryWhereClause, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkMsmqCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewMSMQCollector)
|
||||
benchmarkCollector(b, "", newMSMQCollector)
|
||||
}
|
||||
|
||||
@@ -11,27 +11,27 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagMssqlEnabledCollectors = "collectors.mssql.classes-enabled"
|
||||
FlagMssqlPrintCollectors = "collectors.mssql.class-print"
|
||||
)
|
||||
|
||||
var (
|
||||
mssqlEnabledCollectors = kingpin.Flag(
|
||||
"collectors.mssql.classes-enabled",
|
||||
"Comma-separated list of mssql WMI classes to use.").
|
||||
Default(mssqlAvailableClassCollectors()).String()
|
||||
mssqlEnabledCollectors *string
|
||||
|
||||
mssqlPrintCollectors = kingpin.Flag(
|
||||
"collectors.mssql.class-print",
|
||||
"If true, print available mssql WMI classes and exit. Only displays if the mssql collector is enabled.",
|
||||
).Bool()
|
||||
mssqlPrintCollectors *bool
|
||||
)
|
||||
|
||||
type mssqlInstancesType map[string]string
|
||||
|
||||
func getMSSQLInstances() mssqlInstancesType {
|
||||
func getMSSQLInstances(logger log.Logger) mssqlInstancesType {
|
||||
sqlInstances := make(mssqlInstancesType)
|
||||
|
||||
// in case querying the registry fails, return the default instance
|
||||
@@ -41,19 +41,19 @@ func getMSSQLInstances() mssqlInstancesType {
|
||||
regkey := `Software\Microsoft\Microsoft SQL Server\Instance Names\SQL`
|
||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, regkey, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
log.Warn("Couldn't open registry to determine SQL instances:", err)
|
||||
_ = level.Warn(logger).Log("msg", "Couldn't open registry to determine SQL instances", "err", err)
|
||||
return sqlDefaultInstance
|
||||
}
|
||||
defer func() {
|
||||
err = k.Close()
|
||||
if err != nil {
|
||||
log.Warnf("Failed to close registry key: %v", err)
|
||||
_ = level.Warn(logger).Log("msg", "Failed to close registry key", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
instanceNames, err := k.ReadValueNames(0)
|
||||
if err != nil {
|
||||
log.Warnf("Can't ReadSubKeyNames %#v", err)
|
||||
_ = level.Warn(logger).Log("msg", "Can't ReadSubKeyNames", "err", err)
|
||||
return sqlDefaultInstance
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func getMSSQLInstances() mssqlInstancesType {
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("Detected MSSQL Instances: %#v\n", sqlInstances)
|
||||
_ = level.Debug(logger).Log("msg", fmt.Sprintf("Detected MSSQL Instances: %#v\n", sqlInstances))
|
||||
|
||||
return sqlInstances
|
||||
}
|
||||
@@ -129,12 +129,10 @@ func mssqlGetPerfObjectName(sqlInstance string, collector string) string {
|
||||
return (prefix + suffix)
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerCollector("mssql", NewMSSQLCollector)
|
||||
}
|
||||
|
||||
// A MSSQLCollector is a Prometheus collector for various WMI Win32_PerfRawData_MSSQLSERVER_* metrics
|
||||
type MSSQLCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
// meta
|
||||
mssqlScrapeDurationDesc *prometheus.Desc
|
||||
mssqlScrapeSuccessDesc *prometheus.Desc
|
||||
@@ -405,13 +403,26 @@ type MSSQLCollector struct {
|
||||
mssqlChildCollectorFailure int
|
||||
}
|
||||
|
||||
// NewMSSQLCollector ...
|
||||
func NewMSSQLCollector() (Collector, error) {
|
||||
// newMSSQLCollectorFlags ...
|
||||
func newMSSQLCollectorFlags(app *kingpin.Application) {
|
||||
mssqlEnabledCollectors = app.Flag(
|
||||
FlagMssqlEnabledCollectors,
|
||||
"Comma-separated list of mssql WMI classes to use.").
|
||||
Default(mssqlAvailableClassCollectors()).String()
|
||||
|
||||
mssqlPrintCollectors = app.Flag(
|
||||
FlagMssqlPrintCollectors,
|
||||
"If true, print available mssql WMI classes and exit. Only displays if the mssql collector is enabled.",
|
||||
).Bool()
|
||||
}
|
||||
|
||||
// newMSSQLCollector ...
|
||||
func newMSSQLCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "mssql"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
enabled := expandEnabledChildCollectors(*mssqlEnabledCollectors)
|
||||
mssqlInstances := getMSSQLInstances()
|
||||
mssqlInstances := getMSSQLInstances(logger)
|
||||
perfCounters := make([]string, 0, len(mssqlInstances)*len(enabled))
|
||||
for instance := range mssqlInstances {
|
||||
for _, c := range enabled {
|
||||
@@ -421,6 +432,7 @@ func NewMSSQLCollector() (Collector, error) {
|
||||
addPerfCounterDependencies(subsystem, perfCounters)
|
||||
|
||||
mssqlCollector := MSSQLCollector{
|
||||
logger: logger,
|
||||
// meta
|
||||
mssqlScrapeDurationDesc: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "collector_duration_seconds"),
|
||||
@@ -1921,11 +1933,11 @@ func (c *MSSQLCollector) execute(ctx *ScrapeContext, name string, fn mssqlCollec
|
||||
var success float64
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("mssql class collector %s failed after %fs: %s", name, duration.Seconds(), err)
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("mssql class collector %s failed after %fs", name, duration.Seconds()), "err", err)
|
||||
success = 0
|
||||
c.mssqlChildCollectorFailure++
|
||||
} else {
|
||||
log.Debugf("mssql class collector %s succeeded after %fs.", name, duration.Seconds())
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql class collector %s succeeded after %fs.", name, duration.Seconds()))
|
||||
success = 1
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
@@ -2016,9 +2028,9 @@ type mssqlAccessMethods struct {
|
||||
|
||||
func (c *MSSQLCollector) collectAccessMethods(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlAccessMethods
|
||||
log.Debugf("mssql_accessmethods collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_accessmethods collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "accessmethods")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "accessmethods")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2351,9 +2363,9 @@ type mssqlAvailabilityReplica struct {
|
||||
|
||||
func (c *MSSQLCollector) collectAvailabilityReplica(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlAvailabilityReplica
|
||||
log.Debugf("mssql_availreplica collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_availreplica collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "availreplica")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "availreplica")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2459,9 +2471,9 @@ type mssqlBufferManager struct {
|
||||
|
||||
func (c *MSSQLCollector) collectBufferManager(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlBufferManager
|
||||
log.Debugf("mssql_bufman collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_bufman collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "bufman")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "bufman")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2663,9 +2675,9 @@ type mssqlDatabaseReplica struct {
|
||||
|
||||
func (c *MSSQLCollector) collectDatabaseReplica(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlDatabaseReplica
|
||||
log.Debugf("mssql_dbreplica collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_dbreplica collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "dbreplica")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "dbreplica")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2902,9 +2914,9 @@ type mssqlDatabases struct {
|
||||
|
||||
func (c *MSSQLCollector) collectDatabases(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlDatabases
|
||||
log.Debugf("mssql_databases collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_databases collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "databases")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "databases")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -3284,9 +3296,9 @@ type mssqlGeneralStatistics struct {
|
||||
|
||||
func (c *MSSQLCollector) collectGeneralStatistics(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlGeneralStatistics
|
||||
log.Debugf("mssql_genstats collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_genstats collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "genstats")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "genstats")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -3479,9 +3491,9 @@ type mssqlLocks struct {
|
||||
|
||||
func (c *MSSQLCollector) collectLocks(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlLocks
|
||||
log.Debugf("mssql_locks collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_locks collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "locks")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "locks")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -3577,9 +3589,9 @@ type mssqlMemoryManager struct {
|
||||
|
||||
func (c *MSSQLCollector) collectMemoryManager(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlMemoryManager
|
||||
log.Debugf("mssql_memmgr collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_memmgr collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "memmgr")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "memmgr")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -3746,9 +3758,9 @@ type mssqlSQLStatistics struct {
|
||||
|
||||
func (c *MSSQLCollector) collectSQLStats(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlSQLStatistics
|
||||
log.Debugf("mssql_sqlstats collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_sqlstats collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlstats")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlstats")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -3854,9 +3866,9 @@ type mssqlWaitStatistics struct {
|
||||
|
||||
func (c *MSSQLCollector) collectWaitStats(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlWaitStatistics
|
||||
log.Debugf("mssql_waitstats collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_waitstats collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "waitstats")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "waitstats")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -3960,9 +3972,9 @@ type mssqlSQLErrors struct {
|
||||
// - https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-sql-errors-object
|
||||
func (c *MSSQLCollector) collectSQLErrors(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlSQLErrors
|
||||
log.Debugf("mssql_sqlerrors collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_sqlerrors collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlerrors")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlerrors")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -4003,9 +4015,9 @@ type mssqlTransactions struct {
|
||||
// - https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-transactions-object
|
||||
func (c *MSSQLCollector) collectTransactions(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
||||
var dst []mssqlTransactions
|
||||
log.Debugf("mssql_transactions collector iterating sql instance %s.", sqlInstance)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_transactions collector iterating sql instance %s.", sqlInstance))
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "transactions")], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects[mssqlGetPerfObjectName(sqlInstance, "transactions")], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkMSSQLCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "mssql", NewMSSQLCollector)
|
||||
benchmarkCollector(b, "mssql", newMSSQLCollector)
|
||||
}
|
||||
|
||||
117
collector/net.go
117
collector/net.go
@@ -4,35 +4,45 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("net", NewNetworkCollector, "Network Interface")
|
||||
}
|
||||
const (
|
||||
FlagNicOldExclude = "collector.net.nic-blacklist"
|
||||
FlagNicOldInclude = "collector.net.nic-whitelist"
|
||||
|
||||
FlagNicExclude = "collector.net.nic-exclude"
|
||||
FlagNicInclude = "collector.net.nic-include"
|
||||
)
|
||||
|
||||
var (
|
||||
nicWhitelist = kingpin.Flag(
|
||||
"collector.net.nic-whitelist",
|
||||
"Regexp of NIC:s to whitelist. NIC name must both match whitelist and not match blacklist to be included.",
|
||||
).Default(".+").String()
|
||||
nicBlacklist = kingpin.Flag(
|
||||
"collector.net.nic-blacklist",
|
||||
"Regexp of NIC:s to blacklist. NIC name must both match whitelist and not match blacklist to be included.",
|
||||
).Default("").String()
|
||||
nicOldInclude *string
|
||||
nicOldExclude *string
|
||||
|
||||
nicInclude *string
|
||||
nicExclude *string
|
||||
|
||||
nicIncludeSet bool
|
||||
nicExcludeSet bool
|
||||
|
||||
nicNameToUnderscore = regexp.MustCompile("[^a-zA-Z0-9]")
|
||||
)
|
||||
|
||||
// A NetworkCollector is a Prometheus collector for Perflib Network Interface metrics
|
||||
type NetworkCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
BytesReceivedTotal *prometheus.Desc
|
||||
BytesSentTotal *prometheus.Desc
|
||||
BytesTotal *prometheus.Desc
|
||||
OutputQueueLength *prometheus.Desc
|
||||
PacketsOutboundDiscarded *prometheus.Desc
|
||||
PacketsOutboundErrors *prometheus.Desc
|
||||
PacketsTotal *prometheus.Desc
|
||||
@@ -43,15 +53,63 @@ type NetworkCollector struct {
|
||||
PacketsSentTotal *prometheus.Desc
|
||||
CurrentBandwidth *prometheus.Desc
|
||||
|
||||
nicWhitelistPattern *regexp.Regexp
|
||||
nicBlacklistPattern *regexp.Regexp
|
||||
nicIncludePattern *regexp.Regexp
|
||||
nicExcludePattern *regexp.Regexp
|
||||
}
|
||||
|
||||
// NewNetworkCollector ...
|
||||
func NewNetworkCollector() (Collector, error) {
|
||||
// newNetworkCollectorFlags ...
|
||||
func newNetworkCollectorFlags(app *kingpin.Application) {
|
||||
nicInclude = app.Flag(
|
||||
FlagNicInclude,
|
||||
"Regexp of NIC:s to include. NIC name must both match include and not match exclude to be included.",
|
||||
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
|
||||
nicIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
nicExclude = app.Flag(
|
||||
FlagNicExclude,
|
||||
"Regexp of NIC:s to exclude. NIC name must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
nicExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
nicOldInclude = app.Flag(
|
||||
FlagNicOldInclude,
|
||||
"DEPRECATED: Use --collector.net.nic-include",
|
||||
).Hidden().String()
|
||||
nicOldExclude = app.Flag(
|
||||
FlagNicOldExclude,
|
||||
"DEPRECATED: Use --collector.net.nic-exclude",
|
||||
).Hidden().String()
|
||||
|
||||
}
|
||||
|
||||
// newNetworkCollector ...
|
||||
func newNetworkCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "net"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *nicOldExclude != "" {
|
||||
if !nicExcludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.net.nic-blacklist is DEPRECATED and will be removed in a future release, use --collector.net.nic-exclude")
|
||||
*nicExclude = *nicOldExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.net.nic-blacklist and --collector.net.nic-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
if *nicOldInclude != "" {
|
||||
if !nicIncludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.net.nic-whitelist is DEPRECATED and will be removed in a future release, use --collector.net.nic-include")
|
||||
*nicInclude = *nicOldInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.net.nic-whitelist and --collector.net.nic-include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
return &NetworkCollector{
|
||||
logger: logger,
|
||||
BytesReceivedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "bytes_received_total"),
|
||||
"(Network.BytesReceivedPerSec)",
|
||||
@@ -70,6 +128,12 @@ func NewNetworkCollector() (Collector, error) {
|
||||
[]string{"nic"},
|
||||
nil,
|
||||
),
|
||||
OutputQueueLength: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "output_queue_length_packets"),
|
||||
"(Network.OutputQueueLength)",
|
||||
[]string{"nic"},
|
||||
nil,
|
||||
),
|
||||
PacketsOutboundDiscarded: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "packets_outbound_discarded_total"),
|
||||
"(Network.PacketsOutboundDiscarded)",
|
||||
@@ -125,8 +189,8 @@ func NewNetworkCollector() (Collector, error) {
|
||||
nil,
|
||||
),
|
||||
|
||||
nicWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *nicWhitelist)),
|
||||
nicBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *nicBlacklist)),
|
||||
nicIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *nicInclude)),
|
||||
nicExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *nicExclude)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -134,7 +198,7 @@ func NewNetworkCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NetworkCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
log.Error("failed collecting net metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting net metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -153,6 +217,7 @@ type networkInterface struct {
|
||||
BytesSentPerSec float64 `perflib:"Bytes Sent/sec"`
|
||||
BytesTotalPerSec float64 `perflib:"Bytes Total/sec"`
|
||||
Name string
|
||||
OutputQueueLength float64 `perflib:"Output Queue Length"`
|
||||
PacketsOutboundDiscarded float64 `perflib:"Packets Outbound Discarded"`
|
||||
PacketsOutboundErrors float64 `perflib:"Packets Outbound Errors"`
|
||||
PacketsPerSec float64 `perflib:"Packets/sec"`
|
||||
@@ -167,13 +232,13 @@ type networkInterface struct {
|
||||
func (c *NetworkCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []networkInterface
|
||||
|
||||
if err := unmarshalObject(ctx.perfObjects["Network Interface"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["Network Interface"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, nic := range dst {
|
||||
if c.nicBlacklistPattern.MatchString(nic.Name) ||
|
||||
!c.nicWhitelistPattern.MatchString(nic.Name) {
|
||||
if c.nicExcludePattern.MatchString(nic.Name) ||
|
||||
!c.nicIncludePattern.MatchString(nic.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -201,6 +266,12 @@ func (c *NetworkCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
|
||||
nic.BytesTotalPerSec,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.OutputQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
nic.OutputQueueLength,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsOutboundDiscarded,
|
||||
prometheus.CounterValue,
|
||||
|
||||
@@ -20,8 +20,8 @@ func TestNetworkToInstanceName(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkNetCollector(b *testing.B) {
|
||||
// Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all interfaces.
|
||||
localNicWhitelist := ".+"
|
||||
nicWhitelist = &localNicWhitelist
|
||||
benchmarkCollector(b, "net", NewNetworkCollector)
|
||||
// Include is not set in testing context (kingpin flags not parsed), causing the collector to skip all interfaces.
|
||||
localNicInclude := ".+"
|
||||
nicInclude = &localNicInclude
|
||||
benchmarkCollector(b, "net", newNetworkCollector)
|
||||
}
|
||||
|
||||
@@ -4,27 +4,28 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("netframework_clrexceptions", NewNETFramework_NETCLRExceptionsCollector)
|
||||
}
|
||||
|
||||
// A NETFramework_NETCLRExceptionsCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRExceptions metrics
|
||||
type NETFramework_NETCLRExceptionsCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
NumberofExcepsThrown *prometheus.Desc
|
||||
NumberofFilters *prometheus.Desc
|
||||
NumberofFinallys *prometheus.Desc
|
||||
ThrowToCatchDepth *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewNETFramework_NETCLRExceptionsCollector ...
|
||||
func NewNETFramework_NETCLRExceptionsCollector() (Collector, error) {
|
||||
// newNETFramework_NETCLRExceptionsCollector ...
|
||||
func newNETFramework_NETCLRExceptionsCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrexceptions"
|
||||
return &NETFramework_NETCLRExceptionsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
NumberofExcepsThrown: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "exceptions_thrown_total"),
|
||||
"Displays the total number of exceptions thrown since the application started. This includes both .NET exceptions and unmanaged exceptions that are converted into .NET exceptions.",
|
||||
@@ -56,7 +57,7 @@ func NewNETFramework_NETCLRExceptionsCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRExceptionsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting win32_perfrawdata_netframework_netclrexceptions metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrexceptions metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -74,7 +75,7 @@ type Win32_PerfRawData_NETFramework_NETCLRExceptions struct {
|
||||
|
||||
func (c *NETFramework_NETCLRExceptionsCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRExceptions
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkNetFrameworkNETCLRExceptionsCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewNETFramework_NETCLRExceptionsCollector)
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRExceptionsCollector)
|
||||
}
|
||||
|
||||
@@ -4,26 +4,26 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("netframework_clrinterop", NewNETFramework_NETCLRInteropCollector)
|
||||
}
|
||||
|
||||
// A NETFramework_NETCLRInteropCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRInterop metrics
|
||||
type NETFramework_NETCLRInteropCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
NumberofCCWs *prometheus.Desc
|
||||
Numberofmarshalling *prometheus.Desc
|
||||
NumberofStubs *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewNETFramework_NETCLRInteropCollector ...
|
||||
func NewNETFramework_NETCLRInteropCollector() (Collector, error) {
|
||||
// newNETFramework_NETCLRInteropCollector ...
|
||||
func newNETFramework_NETCLRInteropCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrinterop"
|
||||
return &NETFramework_NETCLRInteropCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
NumberofCCWs: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "com_callable_wrappers_total"),
|
||||
"Displays the current number of COM callable wrappers (CCWs). A CCW is a proxy for a managed object being referenced from an unmanaged COM client.",
|
||||
@@ -49,7 +49,7 @@ func NewNETFramework_NETCLRInteropCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRInteropCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting win32_perfrawdata_netframework_netclrinterop metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrinterop metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -67,7 +67,7 @@ type Win32_PerfRawData_NETFramework_NETCLRInterop struct {
|
||||
|
||||
func (c *NETFramework_NETCLRInteropCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRInterop
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRInteropCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewNETFramework_NETCLRInteropCollector)
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRInteropCollector)
|
||||
}
|
||||
|
||||
@@ -4,27 +4,27 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("netframework_clrjit", NewNETFramework_NETCLRJitCollector)
|
||||
}
|
||||
|
||||
// A NETFramework_NETCLRJitCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRJit metrics
|
||||
type NETFramework_NETCLRJitCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
NumberofMethodsJitted *prometheus.Desc
|
||||
TimeinJit *prometheus.Desc
|
||||
StandardJitFailures *prometheus.Desc
|
||||
TotalNumberofILBytesJitted *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewNETFramework_NETCLRJitCollector ...
|
||||
func NewNETFramework_NETCLRJitCollector() (Collector, error) {
|
||||
// newNETFramework_NETCLRJitCollector ...
|
||||
func newNETFramework_NETCLRJitCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrjit"
|
||||
return &NETFramework_NETCLRJitCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
NumberofMethodsJitted: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "jit_methods_total"),
|
||||
"Displays the total number of methods JIT-compiled since the application started. This counter does not include pre-JIT-compiled methods.",
|
||||
@@ -56,7 +56,7 @@ func NewNETFramework_NETCLRJitCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRJitCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting win32_perfrawdata_netframework_netclrjit metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrjit metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -76,7 +76,7 @@ type Win32_PerfRawData_NETFramework_NETCLRJit struct {
|
||||
|
||||
func (c *NETFramework_NETCLRJitCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRJit
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRJitCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewNETFramework_NETCLRJitCollector)
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRJitCollector)
|
||||
}
|
||||
|
||||
@@ -4,17 +4,16 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("netframework_clrloading", NewNETFramework_NETCLRLoadingCollector)
|
||||
}
|
||||
|
||||
// A NETFramework_NETCLRLoadingCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRLoading metrics
|
||||
type NETFramework_NETCLRLoadingCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
BytesinLoaderHeap *prometheus.Desc
|
||||
Currentappdomains *prometheus.Desc
|
||||
CurrentAssemblies *prometheus.Desc
|
||||
@@ -26,10 +25,11 @@ type NETFramework_NETCLRLoadingCollector struct {
|
||||
TotalNumberofLoadFailures *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewNETFramework_NETCLRLoadingCollector ...
|
||||
func NewNETFramework_NETCLRLoadingCollector() (Collector, error) {
|
||||
// newNETFramework_NETCLRLoadingCollector ...
|
||||
func newNETFramework_NETCLRLoadingCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrloading"
|
||||
return &NETFramework_NETCLRLoadingCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
BytesinLoaderHeap: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "loader_heap_size_bytes"),
|
||||
"Displays the current size, in bytes, of the memory committed by the class loader across all application domains. Committed memory is the physical space reserved in the disk paging file.",
|
||||
@@ -91,7 +91,7 @@ func NewNETFramework_NETCLRLoadingCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRLoadingCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting win32_perfrawdata_netframework_netclrloading metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrloading metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -120,7 +120,7 @@ type Win32_PerfRawData_NETFramework_NETCLRLoading struct {
|
||||
|
||||
func (c *NETFramework_NETCLRLoadingCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRLoading
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRLoadingCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewNETFramework_NETCLRLoadingCollector)
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRLoadingCollector)
|
||||
}
|
||||
|
||||
@@ -4,17 +4,16 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("netframework_clrlocksandthreads", NewNETFramework_NETCLRLocksAndThreadsCollector)
|
||||
}
|
||||
|
||||
// A NETFramework_NETCLRLocksAndThreadsCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads metrics
|
||||
type NETFramework_NETCLRLocksAndThreadsCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
CurrentQueueLength *prometheus.Desc
|
||||
NumberofcurrentlogicalThreads *prometheus.Desc
|
||||
NumberofcurrentphysicalThreads *prometheus.Desc
|
||||
@@ -24,10 +23,11 @@ type NETFramework_NETCLRLocksAndThreadsCollector struct {
|
||||
TotalNumberofContentions *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewNETFramework_NETCLRLocksAndThreadsCollector ...
|
||||
func NewNETFramework_NETCLRLocksAndThreadsCollector() (Collector, error) {
|
||||
// newNETFramework_NETCLRLocksAndThreadsCollector ...
|
||||
func newNETFramework_NETCLRLocksAndThreadsCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrlocksandthreads"
|
||||
return &NETFramework_NETCLRLocksAndThreadsCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
CurrentQueueLength: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "current_queue_length"),
|
||||
"Displays the total number of threads that are currently waiting to acquire a managed lock in the application.",
|
||||
@@ -77,7 +77,7 @@ func NewNETFramework_NETCLRLocksAndThreadsCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRLocksAndThreadsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting win32_perfrawdata_netframework_netclrlocksandthreads metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrlocksandthreads metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -100,7 +100,7 @@ type Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads struct {
|
||||
|
||||
func (c *NETFramework_NETCLRLocksAndThreadsCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRLocksAndThreadsCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewNETFramework_NETCLRLocksAndThreadsCollector)
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRLocksAndThreadsCollector)
|
||||
}
|
||||
|
||||
@@ -4,17 +4,16 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("netframework_clrmemory", NewNETFramework_NETCLRMemoryCollector)
|
||||
}
|
||||
|
||||
// A NETFramework_NETCLRMemoryCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRMemory metrics
|
||||
type NETFramework_NETCLRMemoryCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AllocatedBytes *prometheus.Desc
|
||||
FinalizationSurvivors *prometheus.Desc
|
||||
HeapSize *prometheus.Desc
|
||||
@@ -32,10 +31,11 @@ type NETFramework_NETCLRMemoryCollector struct {
|
||||
PromotedMemoryfromGen1 *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewNETFramework_NETCLRMemoryCollector ...
|
||||
func NewNETFramework_NETCLRMemoryCollector() (Collector, error) {
|
||||
// newNETFramework_NETCLRMemoryCollector ...
|
||||
func newNETFramework_NETCLRMemoryCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrmemory"
|
||||
return &NETFramework_NETCLRMemoryCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
AllocatedBytes: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "allocated_bytes_total"),
|
||||
"Displays the total number of bytes allocated on the garbage collection heap.",
|
||||
@@ -115,7 +115,7 @@ func NewNETFramework_NETCLRMemoryCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRMemoryCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting win32_perfrawdata_netframework_netclrmemory metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrmemory metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -157,7 +157,7 @@ type Win32_PerfRawData_NETFramework_NETCLRMemory struct {
|
||||
|
||||
func (c *NETFramework_NETCLRMemoryCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRMemory
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRMemoryCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewNETFramework_NETCLRMemoryCollector)
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRMemoryCollector)
|
||||
}
|
||||
|
||||
@@ -4,17 +4,16 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("netframework_clrremoting", NewNETFramework_NETCLRRemotingCollector)
|
||||
}
|
||||
|
||||
// A NETFramework_NETCLRRemotingCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRRemoting metrics
|
||||
type NETFramework_NETCLRRemotingCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
Channels *prometheus.Desc
|
||||
ContextBoundClassesLoaded *prometheus.Desc
|
||||
ContextBoundObjects *prometheus.Desc
|
||||
@@ -23,10 +22,11 @@ type NETFramework_NETCLRRemotingCollector struct {
|
||||
TotalRemoteCalls *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewNETFramework_NETCLRRemotingCollector ...
|
||||
func NewNETFramework_NETCLRRemotingCollector() (Collector, error) {
|
||||
// newNETFramework_NETCLRRemotingCollector ...
|
||||
func newNETFramework_NETCLRRemotingCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrremoting"
|
||||
return &NETFramework_NETCLRRemotingCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
Channels: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "channels_total"),
|
||||
"Displays the total number of remoting channels registered across all application domains since application started.",
|
||||
@@ -70,7 +70,7 @@ func NewNETFramework_NETCLRRemotingCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRRemotingCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting win32_perfrawdata_netframework_netclrremoting metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrremoting metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -90,7 +90,7 @@ type Win32_PerfRawData_NETFramework_NETCLRRemoting struct {
|
||||
|
||||
func (c *NETFramework_NETCLRRemotingCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRRemoting
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRRemotingCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewNETFramework_NETCLRRemotingCollector)
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRRemotingCollector)
|
||||
}
|
||||
|
||||
@@ -4,27 +4,27 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("netframework_clrsecurity", NewNETFramework_NETCLRSecurityCollector)
|
||||
}
|
||||
|
||||
// A NETFramework_NETCLRSecurityCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRSecurity metrics
|
||||
type NETFramework_NETCLRSecurityCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
NumberLinkTimeChecks *prometheus.Desc
|
||||
TimeinRTchecks *prometheus.Desc
|
||||
StackWalkDepth *prometheus.Desc
|
||||
TotalRuntimeChecks *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewNETFramework_NETCLRSecurityCollector ...
|
||||
func NewNETFramework_NETCLRSecurityCollector() (Collector, error) {
|
||||
// newNETFramework_NETCLRSecurityCollector ...
|
||||
func newNETFramework_NETCLRSecurityCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "netframework_clrsecurity"
|
||||
return &NETFramework_NETCLRSecurityCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
NumberLinkTimeChecks: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "link_time_checks_total"),
|
||||
"Displays the total number of link-time code access security checks since the application started.",
|
||||
@@ -56,7 +56,7 @@ func NewNETFramework_NETCLRSecurityCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *NETFramework_NETCLRSecurityCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting win32_perfrawdata_netframework_netclrsecurity metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrsecurity metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -75,7 +75,7 @@ type Win32_PerfRawData_NETFramework_NETCLRSecurity struct {
|
||||
|
||||
func (c *NETFramework_NETCLRSecurityCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRSecurity
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
func BenchmarkNETFrameworkNETCLRSecurityCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", NewNETFramework_NETCLRSecurityCollector)
|
||||
benchmarkCollector(b, "", newNETFramework_NETCLRSecurityCollector)
|
||||
}
|
||||
|
||||
425
collector/nps.go
Normal file
425
collector/nps.go
Normal file
@@ -0,0 +1,425 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A npsCollector is a Prometheus collector for WMI Win32_PerfRawData_IAS_NPSAuthenticationServer and Win32_PerfRawData_IAS_NPSAccountingServer metrics
|
||||
|
||||
type npsCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AccessAccepts *prometheus.Desc
|
||||
AccessChallenges *prometheus.Desc
|
||||
AccessRejects *prometheus.Desc
|
||||
AccessRequests *prometheus.Desc
|
||||
AccessBadAuthenticators *prometheus.Desc
|
||||
AccessDroppedPackets *prometheus.Desc
|
||||
AccessInvalidRequests *prometheus.Desc
|
||||
AccessMalformedPackets *prometheus.Desc
|
||||
AccessPacketsReceived *prometheus.Desc
|
||||
AccessPacketsSent *prometheus.Desc
|
||||
AccessServerResetTime *prometheus.Desc
|
||||
AccessServerUpTime *prometheus.Desc
|
||||
AccessUnknownType *prometheus.Desc
|
||||
|
||||
AccountingRequests *prometheus.Desc
|
||||
AccountingResponses *prometheus.Desc
|
||||
AccountingBadAuthenticators *prometheus.Desc
|
||||
AccountingDroppedPackets *prometheus.Desc
|
||||
AccountingInvalidRequests *prometheus.Desc
|
||||
AccountingMalformedPackets *prometheus.Desc
|
||||
AccountingNoRecord *prometheus.Desc
|
||||
AccountingPacketsReceived *prometheus.Desc
|
||||
AccountingPacketsSent *prometheus.Desc
|
||||
AccountingServerResetTime *prometheus.Desc
|
||||
AccountingServerUpTime *prometheus.Desc
|
||||
AccountingUnknownType *prometheus.Desc
|
||||
}
|
||||
|
||||
func newNPSCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "nps"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
return &npsCollector{
|
||||
logger: logger,
|
||||
AccessAccepts: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_accepts"),
|
||||
"(AccessAccepts)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessChallenges: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_challenges"),
|
||||
"(AccessChallenges)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessRejects: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_rejects"),
|
||||
"(AccessRejects)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_requests"),
|
||||
"(AccessRequests)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessBadAuthenticators: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_bad_authenticators"),
|
||||
"(BadAuthenticators)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessDroppedPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_dropped_packets"),
|
||||
"(DroppedPackets)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessInvalidRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_invalid_requests"),
|
||||
"(InvalidRequests)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessMalformedPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_malformed_packets"),
|
||||
"(MalformedPackets)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessPacketsReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_packets_received"),
|
||||
"(PacketsReceived)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessPacketsSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_packets_sent"),
|
||||
"(PacketsSent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessServerResetTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_server_reset_time"),
|
||||
"(ServerResetTime)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessServerUpTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_server_up_time"),
|
||||
"(ServerUpTime)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccessUnknownType: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "access_unknown_type"),
|
||||
"(UnknownType)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
|
||||
AccountingRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_requests"),
|
||||
"(AccountingRequests)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingResponses: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_responses"),
|
||||
"(AccountingResponses)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingBadAuthenticators: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_bad_authenticators"),
|
||||
"(BadAuthenticators)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingDroppedPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_dropped_packets"),
|
||||
"(DroppedPackets)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingInvalidRequests: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_invalid_requests"),
|
||||
"(InvalidRequests)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingMalformedPackets: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_malformed_packets"),
|
||||
"(MalformedPackets)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingNoRecord: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_no_record"),
|
||||
"(NoRecord)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingPacketsReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_packets_received"),
|
||||
"(PacketsReceived)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingPacketsSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_packets_sent"),
|
||||
"(PacketsSent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingServerResetTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_server_reset_time"),
|
||||
"(ServerResetTime)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingServerUpTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_server_up_time"),
|
||||
"(ServerUpTime)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AccountingUnknownType: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "accounting_unknown_type"),
|
||||
"(UnknownType)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *npsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.CollectAccept(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("failed collecting NPS accept data: %s %v", desc, err))
|
||||
return err
|
||||
}
|
||||
if desc, err := c.CollectAccounting(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("failed collecting NPS accounting data: %s %v", desc, err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Win32_PerfRawData_IAS_NPSAuthenticationServer docs:
|
||||
// at the moment there is no Microsoft documentation
|
||||
type Win32_PerfRawData_IAS_NPSAuthenticationServer struct {
|
||||
Name string
|
||||
|
||||
AccessAccepts uint32
|
||||
AccessChallenges uint32
|
||||
AccessRejects uint32
|
||||
AccessRequests uint32
|
||||
AccessBadAuthenticators uint32
|
||||
AccessDroppedPackets uint32
|
||||
AccessInvalidRequests uint32
|
||||
AccessMalformedPackets uint32
|
||||
AccessPacketsReceived uint32
|
||||
AccessPacketsSent uint32
|
||||
AccessServerResetTime uint32
|
||||
AccessServerUpTime uint32
|
||||
AccessUnknownType uint32
|
||||
}
|
||||
|
||||
type Win32_PerfRawData_IAS_NPSAccountingServer struct {
|
||||
Name string
|
||||
|
||||
AccountingRequests uint32
|
||||
AccountingResponses uint32
|
||||
AccountingBadAuthenticators uint32
|
||||
AccountingDroppedPackets uint32
|
||||
AccountingInvalidRequests uint32
|
||||
AccountingMalformedPackets uint32
|
||||
AccountingNoRecord uint32
|
||||
AccountingPacketsReceived uint32
|
||||
AccountingPacketsSent uint32
|
||||
AccountingServerResetTime uint32
|
||||
AccountingServerUpTime uint32
|
||||
AccountingUnknownType uint32
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *npsCollector) CollectAccept(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_IAS_NPSAuthenticationServer
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessAccepts,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessAccepts),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessChallenges,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessChallenges),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessRejects,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessRejects),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessRequests,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessRequests),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessBadAuthenticators,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessBadAuthenticators),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessDroppedPackets,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessDroppedPackets),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessInvalidRequests,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessInvalidRequests),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessMalformedPackets,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessMalformedPackets),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessPacketsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessPacketsReceived),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessPacketsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessPacketsSent),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessServerResetTime,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessServerResetTime),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessServerUpTime,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessServerUpTime),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccessUnknownType,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccessUnknownType),
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *npsCollector) CollectAccounting(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_IAS_NPSAccountingServer
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingRequests,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingRequests),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingResponses,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingResponses),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingBadAuthenticators,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingBadAuthenticators),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingDroppedPackets,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingDroppedPackets),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingInvalidRequests,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingInvalidRequests),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingMalformedPackets,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingMalformedPackets),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingNoRecord,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingNoRecord),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingPacketsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingPacketsReceived),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingPacketsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingPacketsSent),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingServerResetTime,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingServerResetTime),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingServerUpTime,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingServerUpTime),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AccountingUnknownType,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AccountingUnknownType),
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
9
collector/nps_test.go
Normal file
9
collector/nps_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkNPSCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "nps", newNPSCollector)
|
||||
}
|
||||
@@ -9,20 +9,19 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/headers/netapi32"
|
||||
"github.com/prometheus-community/windows_exporter/headers/psapi"
|
||||
"github.com/prometheus-community/windows_exporter/headers/sysinfoapi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("os", NewOSCollector, "Paging File")
|
||||
}
|
||||
|
||||
// A OSCollector is a Prometheus collector for WMI metrics
|
||||
type OSCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
OSInformation *prometheus.Desc
|
||||
PhysicalMemoryFreeBytes *prometheus.Desc
|
||||
PagingFreeBytes *prometheus.Desc
|
||||
@@ -44,11 +43,13 @@ type pagingFileCounter struct {
|
||||
UsagePeak float64 `perflib:"% Usage Peak"`
|
||||
}
|
||||
|
||||
// NewOSCollector ...
|
||||
func NewOSCollector() (Collector, error) {
|
||||
// newOSCollector ...
|
||||
func newOSCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "os"
|
||||
|
||||
return &OSCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
OSInformation: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "info"),
|
||||
"OperatingSystem.Caption, OperatingSystem.Version",
|
||||
@@ -134,7 +135,7 @@ func NewOSCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *OSCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
log.Error("failed collecting os metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting os metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -204,7 +205,7 @@ func (c *OSCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (
|
||||
file, err := os.Stat(fileString)
|
||||
// For unknown reasons, Windows doesn't always create a page file. Continue collection rather than aborting.
|
||||
if err != nil {
|
||||
log.Debugf("Failed to read page file (reason: %s): %s\n", err, fileString)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("Failed to read page file (reason: %s): %s\n", err, fileString))
|
||||
} else {
|
||||
fsipf += float64(file.Size())
|
||||
}
|
||||
@@ -216,7 +217,7 @@ func (c *OSCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (
|
||||
}
|
||||
|
||||
var pfc = make([]pagingFileCounter, 0)
|
||||
if err := unmarshalObject(ctx.perfObjects["Paging File"], &pfc); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["Paging File"], &pfc, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -275,7 +276,7 @@ func (c *OSCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (
|
||||
fsipf,
|
||||
)
|
||||
} else {
|
||||
log.Debugln("Could not find HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management key. windows_os_paging_free_bytes and windows_os_paging_limit_bytes will be omitted.")
|
||||
_ = level.Debug(c.logger).Log("Could not find HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management key. windows_os_paging_free_bytes and windows_os_paging_limit_bytes will be omitted.")
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.VirtualMemoryFreeBytes,
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkOSCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "os", NewOSCollector)
|
||||
benchmarkCollector(b, "os", newOSCollector)
|
||||
}
|
||||
|
||||
@@ -6,15 +6,14 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
perflibCollector "github.com/leoluk/perflib_exporter/collector"
|
||||
"github.com/leoluk/perflib_exporter/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/prometheus-community/windows_exporter/perflib"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
)
|
||||
|
||||
var nametable = perflib.QueryNameTable("Counter 009") // Reads the names in English TODO: validate that the English names are always present
|
||||
|
||||
func MapCounterToIndex(name string) string {
|
||||
return strconv.Itoa(int(nametable.LookupIndex(name)))
|
||||
return strconv.Itoa(int(perflib.CounterNameTable.LookupIndex(name)))
|
||||
}
|
||||
|
||||
func getPerflibSnapshot(objNames string) (map[string]*perflib.PerfObject, error) {
|
||||
@@ -30,7 +29,7 @@ func getPerflibSnapshot(objNames string) (map[string]*perflib.PerfObject, error)
|
||||
return indexed, nil
|
||||
}
|
||||
|
||||
func unmarshalObject(obj *perflib.PerfObject, vs interface{}) error {
|
||||
func unmarshalObject(obj *perflib.PerfObject, vs interface{}, logger log.Logger) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("counter not found")
|
||||
}
|
||||
@@ -81,7 +80,7 @@ func unmarshalObject(obj *perflib.PerfObject, vs interface{}) error {
|
||||
|
||||
ctr, found := counters[tag]
|
||||
if !found {
|
||||
log.Debugf("missing counter %q, have %v", tag, counterMapKeys(counters))
|
||||
_ = level.Debug(logger).Log("msg", fmt.Sprintf("missing counter %q, have %v", tag, counterMapKeys(counters)))
|
||||
continue
|
||||
}
|
||||
if !target.Field(i).CanSet() {
|
||||
@@ -100,9 +99,9 @@ func unmarshalObject(obj *perflib.PerfObject, vs interface{}) error {
|
||||
}
|
||||
|
||||
switch ctr.Def.CounterType {
|
||||
case perflibCollector.PERF_ELAPSED_TIME:
|
||||
case perflib.PERF_ELAPSED_TIME:
|
||||
target.Field(i).SetFloat(float64(ctr.Value-windowsEpoch) / float64(obj.Frequency))
|
||||
case perflibCollector.PERF_100NSEC_TIMER, perflibCollector.PERF_PRECISION_100NS_TIMER:
|
||||
case perflib.PERF_100NSEC_TIMER, perflib.PERF_PRECISION_100NS_TIMER:
|
||||
target.Field(i).SetFloat(float64(ctr.Value) * ticksToSecondsScaleFactor)
|
||||
default:
|
||||
target.Field(i).SetFloat(float64(ctr.Value))
|
||||
|
||||
@@ -4,8 +4,9 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
perflibCollector "github.com/leoluk/perflib_exporter/collector"
|
||||
"github.com/leoluk/perflib_exporter/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/perflib"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
)
|
||||
|
||||
type simple struct {
|
||||
@@ -37,7 +38,7 @@ func TestUnmarshalPerflib(t *testing.T) {
|
||||
{
|
||||
Def: &perflib.PerfCounterDef{
|
||||
Name: "Something",
|
||||
CounterType: perflibCollector.PERF_COUNTER_COUNTER,
|
||||
CounterType: perflib.PERF_COUNTER_COUNTER,
|
||||
},
|
||||
Value: 123,
|
||||
},
|
||||
@@ -57,14 +58,14 @@ func TestUnmarshalPerflib(t *testing.T) {
|
||||
{
|
||||
Def: &perflib.PerfCounterDef{
|
||||
Name: "Something",
|
||||
CounterType: perflibCollector.PERF_COUNTER_COUNTER,
|
||||
CounterType: perflib.PERF_COUNTER_COUNTER,
|
||||
},
|
||||
Value: 123,
|
||||
},
|
||||
{
|
||||
Def: &perflib.PerfCounterDef{
|
||||
Name: "Something Else",
|
||||
CounterType: perflibCollector.PERF_COUNTER_COUNTER,
|
||||
CounterType: perflib.PERF_COUNTER_COUNTER,
|
||||
HasSecondValue: true,
|
||||
},
|
||||
Value: 256,
|
||||
@@ -86,7 +87,7 @@ func TestUnmarshalPerflib(t *testing.T) {
|
||||
{
|
||||
Def: &perflib.PerfCounterDef{
|
||||
Name: "Something",
|
||||
CounterType: perflibCollector.PERF_COUNTER_COUNTER,
|
||||
CounterType: perflib.PERF_COUNTER_COUNTER,
|
||||
},
|
||||
Value: 321,
|
||||
},
|
||||
@@ -97,7 +98,7 @@ func TestUnmarshalPerflib(t *testing.T) {
|
||||
{
|
||||
Def: &perflib.PerfCounterDef{
|
||||
Name: "Something",
|
||||
CounterType: perflibCollector.PERF_COUNTER_COUNTER,
|
||||
CounterType: perflib.PERF_COUNTER_COUNTER,
|
||||
},
|
||||
Value: 231,
|
||||
},
|
||||
@@ -112,7 +113,7 @@ func TestUnmarshalPerflib(t *testing.T) {
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
output := make([]simple, 0)
|
||||
err := unmarshalObject(c.obj, &output)
|
||||
err := unmarshalObject(c.obj, &output, log.NewNopLogger())
|
||||
if err != nil && !c.expectError {
|
||||
t.Errorf("Did not expect error, got %q", err)
|
||||
}
|
||||
|
||||
@@ -4,33 +4,41 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("process", newProcessCollector, "Process")
|
||||
}
|
||||
const (
|
||||
FlagProcessOldExclude = "collector.process.blacklist"
|
||||
FlagProcessOldInclude = "collector.process.whitelist"
|
||||
|
||||
FlagProcessExclude = "collector.process.exclude"
|
||||
FlagProcessInclude = "collector.process.include"
|
||||
)
|
||||
|
||||
var (
|
||||
processWhitelist = kingpin.Flag(
|
||||
"collector.process.whitelist",
|
||||
"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()
|
||||
processOldInclude *string
|
||||
processOldExclude *string
|
||||
|
||||
processInclude *string
|
||||
processExclude *string
|
||||
|
||||
processIncludeSet bool
|
||||
processExcludeSet bool
|
||||
)
|
||||
|
||||
type processCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
StartTime *prometheus.Desc
|
||||
CPUTimeTotal *prometheus.Desc
|
||||
HandleCount *prometheus.Desc
|
||||
@@ -47,19 +55,66 @@ type processCollector struct {
|
||||
WorkingSetPeak *prometheus.Desc
|
||||
WorkingSet *prometheus.Desc
|
||||
|
||||
processWhitelistPattern *regexp.Regexp
|
||||
processBlacklistPattern *regexp.Regexp
|
||||
processIncludePattern *regexp.Regexp
|
||||
processExcludePattern *regexp.Regexp
|
||||
}
|
||||
|
||||
// newProcessCollectorFlags ...
|
||||
func newProcessCollectorFlags(app *kingpin.Application) {
|
||||
processInclude = app.Flag(
|
||||
FlagProcessInclude,
|
||||
"Regexp of processes to include. Process name must both match include and not match exclude to be included.",
|
||||
).Default(".*").PreAction(func(c *kingpin.ParseContext) error {
|
||||
processIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
processExclude = app.Flag(
|
||||
FlagProcessExclude,
|
||||
"Regexp of processes to exclude. Process name must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
processExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
processOldInclude = app.Flag(
|
||||
FlagProcessOldInclude,
|
||||
"DEPRECATED: Use --collector.process.include",
|
||||
).Hidden().String()
|
||||
processOldExclude = app.Flag(
|
||||
FlagProcessOldExclude,
|
||||
"DEPRECATED: Use --collector.process.exclude",
|
||||
).Hidden().String()
|
||||
}
|
||||
|
||||
// NewProcessCollector ...
|
||||
func newProcessCollector() (Collector, error) {
|
||||
func newProcessCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "process"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *processWhitelist == ".*" && *processBlacklist == "" {
|
||||
log.Warn("No filters specified for process collector. This will generate a very large number of metrics!")
|
||||
if *processOldExclude != "" {
|
||||
if !processExcludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.process.blacklist is DEPRECATED and will be removed in a future release, use --collector.process.exclude")
|
||||
*processExclude = *processOldExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.process.blacklist and --collector.process.exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
if *processOldInclude != "" {
|
||||
if !processIncludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.process.whitelist is DEPRECATED and will be removed in a future release, use --collector.process.include")
|
||||
*processInclude = *processOldInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.process.whitelist and --collector.process.include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
if *processInclude == ".*" && *processExclude == "" {
|
||||
_ = level.Warn(logger).Log("msg", "No filters specified for process collector. This will generate a very large number of metrics!")
|
||||
}
|
||||
|
||||
return &processCollector{
|
||||
logger: logger,
|
||||
StartTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "start_time"),
|
||||
"Time of process start.",
|
||||
@@ -150,8 +205,8 @@ func newProcessCollector() (Collector, error) {
|
||||
[]string{"process", "process_id", "creating_process_id"},
|
||||
nil,
|
||||
),
|
||||
processWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processWhitelist)),
|
||||
processBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processBlacklist)),
|
||||
processIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processInclude)),
|
||||
processExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processExclude)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -194,21 +249,21 @@ type WorkerProcess struct {
|
||||
|
||||
func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
data := make([]perflibProcess, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Process"], &data)
|
||||
err := unmarshalObject(ctx.perfObjects["Process"], &data, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var dst_wp []WorkerProcess
|
||||
q_wp := queryAll(&dst_wp)
|
||||
q_wp := queryAll(&dst_wp, c.logger)
|
||||
if err := wmi.QueryNamespace(q_wp, &dst_wp, "root\\WebAdministration"); err != nil {
|
||||
log.Debugf("Could not query WebAdministration namespace for IIS worker processes: %v. Skipping", err)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("Could not query WebAdministration namespace for IIS worker processes: %v. Skipping", err))
|
||||
}
|
||||
|
||||
for _, process := range data {
|
||||
if process.Name == "_Total" ||
|
||||
c.processBlacklistPattern.MatchString(process.Name) ||
|
||||
!c.processWhitelistPattern.MatchString(process.Name) {
|
||||
c.processExcludePattern.MatchString(process.Name) ||
|
||||
!c.processIncludePattern.MatchString(process.Name) {
|
||||
continue
|
||||
}
|
||||
// Duplicate processes are suffixed # and an index number. Remove those.
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkProcessCollector(b *testing.B) {
|
||||
// Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all processes.
|
||||
localProcessWhitelist := ".+"
|
||||
processWhitelist = &localProcessWhitelist
|
||||
// Include is not set in testing context (kingpin flags not parsed), causing the collector to skip all processes.
|
||||
localProcessInclude := ".+"
|
||||
processInclude = &localProcessInclude
|
||||
|
||||
// No context name required as collector source is WMI
|
||||
benchmarkCollector(b, "", newProcessCollector)
|
||||
|
||||
193
collector/prometheus.go
Normal file
193
collector/prometheus.go
Normal file
@@ -0,0 +1,193 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// Base metrics returned by Prometheus
|
||||
|
||||
var (
|
||||
scrapeDurationDesc = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, "exporter", "collector_duration_seconds"),
|
||||
"windows_exporter: Duration of a collection.",
|
||||
[]string{"collector"},
|
||||
nil,
|
||||
)
|
||||
scrapeSuccessDesc = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, "exporter", "collector_success"),
|
||||
"windows_exporter: Whether the collector was successful.",
|
||||
[]string{"collector"},
|
||||
nil,
|
||||
)
|
||||
scrapeTimeoutDesc = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, "exporter", "collector_timeout"),
|
||||
"windows_exporter: Whether the collector timed out.",
|
||||
[]string{"collector"},
|
||||
nil,
|
||||
)
|
||||
snapshotDuration = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, "exporter", "perflib_snapshot_duration_seconds"),
|
||||
"Duration of perflib snapshot capture",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
)
|
||||
|
||||
// Prometheus implements prometheus.Collector for a set of Windows collectors.
|
||||
type Prometheus struct {
|
||||
maxScrapeDuration time.Duration
|
||||
collectors map[string]Collector
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// NewPrometheus returns a new Prometheus where the set of collectors must
|
||||
// return metrics within the given timeout.
|
||||
func NewPrometheus(timeout time.Duration, cs map[string]Collector, logger log.Logger) *Prometheus {
|
||||
return &Prometheus{
|
||||
maxScrapeDuration: timeout,
|
||||
collectors: cs,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// Describe sends all the descriptors of the collectors included to
|
||||
// the provided channel.
|
||||
func (coll *Prometheus) Describe(ch chan<- *prometheus.Desc) {
|
||||
ch <- scrapeDurationDesc
|
||||
ch <- scrapeSuccessDesc
|
||||
}
|
||||
|
||||
type collectorOutcome int
|
||||
|
||||
const (
|
||||
pending collectorOutcome = iota
|
||||
success
|
||||
failed
|
||||
)
|
||||
|
||||
// Collect sends the collected metrics from each of the collectors to
|
||||
// prometheus.
|
||||
func (coll *Prometheus) Collect(ch chan<- prometheus.Metric) {
|
||||
t := time.Now()
|
||||
cs := make([]string, 0, len(coll.collectors))
|
||||
for name := range coll.collectors {
|
||||
cs = append(cs, name)
|
||||
}
|
||||
scrapeContext, err := PrepareScrapeContext(cs)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
snapshotDuration,
|
||||
prometheus.GaugeValue,
|
||||
time.Since(t).Seconds(),
|
||||
)
|
||||
if err != nil {
|
||||
ch <- prometheus.NewInvalidMetric(scrapeSuccessDesc, fmt.Errorf("failed to prepare scrape: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(len(coll.collectors))
|
||||
collectorOutcomes := make(map[string]collectorOutcome)
|
||||
for name := range coll.collectors {
|
||||
collectorOutcomes[name] = pending
|
||||
}
|
||||
|
||||
metricsBuffer := make(chan prometheus.Metric)
|
||||
l := sync.Mutex{}
|
||||
finished := false
|
||||
go func() {
|
||||
for m := range metricsBuffer {
|
||||
l.Lock()
|
||||
if !finished {
|
||||
ch <- m
|
||||
}
|
||||
l.Unlock()
|
||||
}
|
||||
}()
|
||||
|
||||
for name, c := range coll.collectors {
|
||||
go func(name string, c Collector) {
|
||||
defer wg.Done()
|
||||
outcome := execute(name, c, scrapeContext, metricsBuffer, coll.logger)
|
||||
l.Lock()
|
||||
if !finished {
|
||||
collectorOutcomes[name] = outcome
|
||||
}
|
||||
l.Unlock()
|
||||
}(name, c)
|
||||
}
|
||||
|
||||
allDone := make(chan struct{})
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(allDone)
|
||||
close(metricsBuffer)
|
||||
}()
|
||||
|
||||
// Wait until either all collectors finish, or timeout expires
|
||||
select {
|
||||
case <-allDone:
|
||||
case <-time.After(coll.maxScrapeDuration):
|
||||
}
|
||||
|
||||
l.Lock()
|
||||
finished = true
|
||||
|
||||
remainingCollectorNames := make([]string, 0)
|
||||
for name, outcome := range collectorOutcomes {
|
||||
var successValue, timeoutValue float64
|
||||
if outcome == pending {
|
||||
timeoutValue = 1.0
|
||||
remainingCollectorNames = append(remainingCollectorNames, name)
|
||||
}
|
||||
if outcome == success {
|
||||
successValue = 1.0
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
scrapeSuccessDesc,
|
||||
prometheus.GaugeValue,
|
||||
successValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
scrapeTimeoutDesc,
|
||||
prometheus.GaugeValue,
|
||||
timeoutValue,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
if len(remainingCollectorNames) > 0 {
|
||||
_ = level.Warn(coll.logger).Log("msg", fmt.Sprintf("Collection timed out, still waiting for %v", remainingCollectorNames))
|
||||
}
|
||||
|
||||
l.Unlock()
|
||||
}
|
||||
|
||||
func execute(name string, c Collector, ctx *ScrapeContext, ch chan<- prometheus.Metric, logger log.Logger) collectorOutcome {
|
||||
t := time.Now()
|
||||
err := c.Collect(ctx, ch)
|
||||
duration := time.Since(t).Seconds()
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
scrapeDurationDesc,
|
||||
prometheus.GaugeValue,
|
||||
duration,
|
||||
name,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("msg", fmt.Sprintf("collector %s failed after %fs", name, duration), "err", err)
|
||||
return failed
|
||||
}
|
||||
_ = level.Debug(logger).Log("msg", fmt.Sprintf("collector %s succeeded after %fs.", name, duration))
|
||||
return success
|
||||
}
|
||||
@@ -6,20 +6,19 @@ package collector
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("remote_fx", NewRemoteFx, "RemoteFX Network", "RemoteFX Graphics")
|
||||
}
|
||||
|
||||
// A RemoteFxNetworkCollector is a Prometheus collector for
|
||||
// WMI Win32_PerfRawData_Counters_RemoteFXNetwork & Win32_PerfRawData_Counters_RemoteFXGraphics metrics
|
||||
// https://wutils.com/wmi/root/cimv2/win32_perfrawdata_counters_remotefxnetwork/
|
||||
// https://wutils.com/wmi/root/cimv2/win32_perfrawdata_counters_remotefxgraphics/
|
||||
|
||||
type RemoteFxCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
// net
|
||||
BaseTCPRTT *prometheus.Desc
|
||||
BaseUDPRTT *prometheus.Desc
|
||||
@@ -42,10 +41,12 @@ type RemoteFxCollector struct {
|
||||
SourceFramesPerSecond *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewRemoteFx ...
|
||||
func NewRemoteFx() (Collector, error) {
|
||||
// newRemoteFx ...
|
||||
func newRemoteFx(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "remote_fx"
|
||||
return &RemoteFxCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
|
||||
// net
|
||||
BaseTCPRTT: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "net_base_tcp_rtt_seconds"),
|
||||
@@ -158,11 +159,11 @@ func NewRemoteFx() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *RemoteFxCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collectRemoteFXNetworkCount(ctx, ch); err != nil {
|
||||
log.Error("failed collecting terminal services session count metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
if desc, err := c.collectRemoteFXGraphicsCounters(ctx, ch); err != nil {
|
||||
log.Error("failed collecting terminal services session count metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -184,7 +185,7 @@ type perflibRemoteFxNetwork struct {
|
||||
|
||||
func (c *RemoteFxCollector) collectRemoteFXNetworkCount(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
dst := make([]perflibRemoteFxNetwork, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["RemoteFX Network"], &dst)
|
||||
err := unmarshalObject(ctx.perfObjects["RemoteFX Network"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -274,7 +275,7 @@ type perflibRemoteFxGraphics struct {
|
||||
|
||||
func (c *RemoteFxCollector) collectRemoteFXGraphicsCounters(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
dst := make([]perflibRemoteFxGraphics, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["RemoteFX Graphics"], &dst)
|
||||
err := unmarshalObject(ctx.perfObjects["RemoteFX Graphics"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkRemoteFXCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "remote_fx", NewRemoteFx)
|
||||
benchmarkCollector(b, "remote_fx", newRemoteFx)
|
||||
}
|
||||
|
||||
@@ -4,36 +4,48 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
ole "github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagScheduledTaskOldExclude = "collector.scheduled_task.blacklist"
|
||||
FlagScheduledTaskOldInclude = "collector.scheduled_task.whitelist"
|
||||
|
||||
FlagScheduledTaskExclude = "collector.scheduled_task.exclude"
|
||||
FlagScheduledTaskInclude = "collector.scheduled_task.include"
|
||||
)
|
||||
|
||||
var (
|
||||
taskWhitelist = kingpin.Flag(
|
||||
"collector.scheduled_task.whitelist",
|
||||
"Regexp of tasks to whitelist. Task path must both match whitelist and not match blacklist to be included.",
|
||||
).Default(".+").String()
|
||||
taskBlacklist = kingpin.Flag(
|
||||
"collector.scheduled_task.blacklist",
|
||||
"Regexp of tasks to blacklist. Task path must both match whitelist and not match blacklist to be included.",
|
||||
).String()
|
||||
taskOldExclude *string
|
||||
taskOldInclude *string
|
||||
|
||||
taskExclude *string
|
||||
taskInclude *string
|
||||
|
||||
taskIncludeSet bool
|
||||
taskExcludeSet bool
|
||||
)
|
||||
|
||||
type ScheduledTaskCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
LastResult *prometheus.Desc
|
||||
MissedRuns *prometheus.Desc
|
||||
State *prometheus.Desc
|
||||
|
||||
taskWhitelistPattern *regexp.Regexp
|
||||
taskBlacklistPattern *regexp.Regexp
|
||||
taskIncludePattern *regexp.Regexp
|
||||
taskExcludePattern *regexp.Regexp
|
||||
}
|
||||
|
||||
// TaskState ...
|
||||
@@ -63,13 +75,55 @@ type ScheduledTask struct {
|
||||
|
||||
type ScheduledTasks []ScheduledTask
|
||||
|
||||
func init() {
|
||||
registerCollector("scheduled_task", NewScheduledTask)
|
||||
// newScheduledTask ...
|
||||
func newScheduledTaskFlags(app *kingpin.Application) {
|
||||
taskInclude = app.Flag(
|
||||
FlagScheduledTaskInclude,
|
||||
"Regexp of tasks to include. Task path must both match include and not match exclude to be included.",
|
||||
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
|
||||
taskIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
taskExclude = app.Flag(
|
||||
FlagScheduledTaskExclude,
|
||||
"Regexp of tasks to exclude. Task path must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
taskExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
taskOldInclude = app.Flag(
|
||||
FlagScheduledTaskOldInclude,
|
||||
"DEPRECATED: Use --collector.scheduled_task.include",
|
||||
).Hidden().String()
|
||||
taskOldExclude = app.Flag(
|
||||
FlagScheduledTaskOldExclude,
|
||||
"DEPRECATED: Use --collector.scheduled_task.exclude",
|
||||
).Hidden().String()
|
||||
}
|
||||
|
||||
// NewScheduledTask ...
|
||||
func NewScheduledTask() (Collector, error) {
|
||||
// newScheduledTask ...
|
||||
func newScheduledTask(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "scheduled_task"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *taskOldExclude != "" {
|
||||
if !taskExcludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.scheduled_task.blacklist is DEPRECATED and will be removed in a future release, use --collector.scheduled_task.exclude")
|
||||
*taskExclude = *taskOldExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.scheduled_task.blacklist and --collector.scheduled_task.exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
if *taskOldInclude != "" {
|
||||
if !taskIncludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.scheduled_task.whitelist is DEPRECATED and will be removed in a future release, use --collector.scheduled_task.include")
|
||||
*taskInclude = *taskOldInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.scheduled_task.whitelist and --collector.scheduled_task.include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
@@ -84,6 +138,7 @@ func NewScheduledTask() (Collector, error) {
|
||||
defer ole.CoUninitialize()
|
||||
|
||||
return &ScheduledTaskCollector{
|
||||
logger: logger,
|
||||
LastResult: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "last_result"),
|
||||
"The result that was returned the last time the registered task was run",
|
||||
@@ -105,14 +160,14 @@ func NewScheduledTask() (Collector, error) {
|
||||
nil,
|
||||
),
|
||||
|
||||
taskWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *taskWhitelist)),
|
||||
taskBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *taskBlacklist)),
|
||||
taskIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *taskInclude)),
|
||||
taskExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *taskExclude)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *ScheduledTaskCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting user metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting user metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -128,8 +183,8 @@ func (c *ScheduledTaskCollector) collect(ch chan<- prometheus.Metric) (*promethe
|
||||
}
|
||||
|
||||
for _, task := range scheduledTasks {
|
||||
if c.taskBlacklistPattern.MatchString(task.Path) ||
|
||||
!c.taskWhitelistPattern.MatchString(task.Path) {
|
||||
if c.taskExcludePattern.MatchString(task.Path) ||
|
||||
!c.taskIncludePattern.MatchString(task.Path) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkScheduledTaskCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "scheduled_task", NewScheduledTask)
|
||||
benchmarkCollector(b, "scheduled_task", newScheduledTask)
|
||||
}
|
||||
|
||||
@@ -8,31 +8,29 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("service", NewserviceCollector)
|
||||
}
|
||||
const (
|
||||
FlagServiceWhereClause = "collector.service.services-where"
|
||||
FlagServiceUseAPI = "collector.service.use-api"
|
||||
)
|
||||
|
||||
var (
|
||||
serviceWhereClause = kingpin.Flag(
|
||||
"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.",
|
||||
).Default("").String()
|
||||
useAPI = kingpin.Flag(
|
||||
"collector.service.use-api",
|
||||
"Use API calls to collect service data instead of WMI. Flag 'collector.service.services-where' won't be effective.",
|
||||
).Default("false").Bool()
|
||||
serviceWhereClause *string
|
||||
useAPI *bool
|
||||
)
|
||||
|
||||
// A serviceCollector is a Prometheus collector for WMI Win32_Service metrics
|
||||
type serviceCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
Information *prometheus.Desc
|
||||
State *prometheus.Desc
|
||||
StartMode *prometheus.Desc
|
||||
@@ -41,18 +39,33 @@ type serviceCollector struct {
|
||||
queryWhereClause string
|
||||
}
|
||||
|
||||
// NewserviceCollector ...
|
||||
func NewserviceCollector() (Collector, error) {
|
||||
// newServiceCollectorFlags ...
|
||||
func newServiceCollectorFlags(app *kingpin.Application) {
|
||||
serviceWhereClause = app.Flag(
|
||||
FlagServiceWhereClause,
|
||||
"WQL 'where' clause to use in WMI metrics query. Limits the response to the services you specify and reduces the size of the response.",
|
||||
).Default("").String()
|
||||
useAPI = app.Flag(
|
||||
FlagServiceUseAPI,
|
||||
"Use API calls to collect service data instead of WMI. Flag 'collector.service.services-where' won't be effective.",
|
||||
).Default("false").Bool()
|
||||
}
|
||||
|
||||
// newserviceCollector ...
|
||||
func newserviceCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "service"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
if *serviceWhereClause == "" {
|
||||
log.Warn("No where-clause specified for service collector. This will generate a very large number of metrics!")
|
||||
_ = level.Warn(logger).Log("msg", "No where-clause specified for service collector. This will generate a very large number of metrics!")
|
||||
}
|
||||
if *useAPI {
|
||||
log.Warn("API collection is enabled.")
|
||||
_ = level.Warn(logger).Log("msg", "API collection is enabled.")
|
||||
}
|
||||
|
||||
return &serviceCollector{
|
||||
logger: logger,
|
||||
|
||||
Information: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "info"),
|
||||
"A metric with a constant '1' value labeled with service information",
|
||||
@@ -86,12 +99,12 @@ func NewserviceCollector() (Collector, error) {
|
||||
func (c *serviceCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if *useAPI {
|
||||
if err := c.collectAPI(ch); err != nil {
|
||||
log.Error("failed collecting API service metrics:", err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting API service metrics:", "err", err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := c.collectWMI(ch); err != nil {
|
||||
log.Error("failed collecting WMI service metrics:", err)
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting WMI service metrics:", "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -162,7 +175,7 @@ var (
|
||||
|
||||
func (c *serviceCollector) collectWMI(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_Service
|
||||
q := queryAllWhere(&dst, c.queryWhereClause)
|
||||
q := queryAllWhere(&dst, c.queryWhereClause, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -246,14 +259,14 @@ func (c *serviceCollector) collectAPI(ch chan<- prometheus.Metric) error {
|
||||
// Get UTF16 service name.
|
||||
serviceName, err := syscall.UTF16PtrFromString(service)
|
||||
if err != nil {
|
||||
log.Warnf("Service %s get name error: %#v", service, err)
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Service %s get name error: %#v", service, err))
|
||||
continue
|
||||
}
|
||||
|
||||
// Open connection for service handler.
|
||||
serviceHandle, err := windows.OpenService(svcmgrConnection.Handle, serviceName, windows.GENERIC_READ)
|
||||
if err != nil {
|
||||
log.Warnf("Open service %s error: %#v", service, err)
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Open service %s error: %#v", service, err))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -264,14 +277,14 @@ func (c *serviceCollector) collectAPI(ch chan<- prometheus.Metric) error {
|
||||
// Get Service Configuration.
|
||||
serviceConfig, err := serviceManager.Config()
|
||||
if err != nil {
|
||||
log.Warnf("Get ervice %s config error: %#v", service, err)
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Get ervice %s config error: %#v", service, err))
|
||||
continue
|
||||
}
|
||||
|
||||
// Get Service Current Status.
|
||||
serviceStatus, err := serviceManager.Query()
|
||||
if err != nil {
|
||||
log.Warnf("Get service %s status error: %#v", service, err)
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Get service %s status error: %#v", service, err))
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkServiceCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "service", NewserviceCollector)
|
||||
benchmarkCollector(b, "service", newserviceCollector)
|
||||
}
|
||||
|
||||
@@ -4,23 +4,38 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
"regexp"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("smtp", NewSMTPCollector, "SMTP Server")
|
||||
}
|
||||
const (
|
||||
FlagSmtpServerOldExclude = "collector.smtp.server-blacklist"
|
||||
FlagSmtpServerOldInclude = "collector.smtp.server-whitelist"
|
||||
|
||||
FlagSmtpServerExclude = "collector.smtp.server-exclude"
|
||||
FlagSmtpServerInclude = "collector.smtp.server-include"
|
||||
)
|
||||
|
||||
var (
|
||||
serverWhitelist = kingpin.Flag("collector.smtp.server-whitelist", "Regexp of virtual servers to whitelist. Server name must both match whitelist and not match blacklist to be included.").Default(".+").String()
|
||||
serverBlacklist = kingpin.Flag("collector.smtp.server-blacklist", "Regexp of virtual servers to blacklist. Server name must both match whitelist and not match blacklist to be included.").String()
|
||||
serverOldInclude *string
|
||||
serverOldExclude *string
|
||||
|
||||
serverInclude *string
|
||||
serverExclude *string
|
||||
|
||||
serverIncludeSet bool
|
||||
serverExcludeSet bool
|
||||
)
|
||||
|
||||
type SMTPCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
BadmailedMessagesBadPickupFileTotal *prometheus.Desc
|
||||
BadmailedMessagesGeneralFailureTotal *prometheus.Desc
|
||||
BadmailedMessagesHopCountExceededTotal *prometheus.Desc
|
||||
@@ -64,15 +79,62 @@ type SMTPCollector struct {
|
||||
RemoteRetryQueueLength *prometheus.Desc
|
||||
RoutingTableLookupsTotal *prometheus.Desc
|
||||
|
||||
serverWhitelistPattern *regexp.Regexp
|
||||
serverBlacklistPattern *regexp.Regexp
|
||||
serverIncludePattern *regexp.Regexp
|
||||
serverExcludePattern *regexp.Regexp
|
||||
}
|
||||
|
||||
func NewSMTPCollector() (Collector, error) {
|
||||
log.Info("smtp collector is in an experimental state! Metrics for this collector have not been tested.")
|
||||
func newSMTPCollectorFlags(app *kingpin.Application) {
|
||||
serverInclude = app.Flag(
|
||||
FlagSmtpServerInclude,
|
||||
"Regexp of virtual servers to include. Server name must both match include and not match exclude to be included.",
|
||||
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
|
||||
serverIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
serverExclude = app.Flag(
|
||||
FlagSmtpServerExclude,
|
||||
"Regexp of virtual servers to exclude. Server name must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
serverExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
serverOldInclude = app.Flag(
|
||||
FlagSmtpServerOldInclude,
|
||||
"DEPRECATED: Use --collector.smtp.server-include",
|
||||
).Hidden().String()
|
||||
serverOldExclude = app.Flag(
|
||||
FlagSmtpServerOldExclude,
|
||||
"DEPRECATED: Use --collector.smtp.server-exclude",
|
||||
).Hidden().String()
|
||||
}
|
||||
|
||||
func newSMTPCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "smtp"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
_ = level.Info(logger).Log("msg", "smtp collector is in an experimental state! Metrics for this collector have not been tested.")
|
||||
|
||||
if *serverOldExclude != "" {
|
||||
if !serverExcludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.smtp.server-blacklist is DEPRECATED and will be removed in a future release, use --collector.smtp.server-exclude")
|
||||
*serverExclude = *serverOldExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.smtp.server-blacklist and --collector.smtp.server-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
if *serverOldInclude != "" {
|
||||
if !serverIncludeSet {
|
||||
_ = level.Warn(logger).Log("msg", "--collector.smtp.server-whitelist is DEPRECATED and will be removed in a future release, use --collector.smtp.server-include")
|
||||
*serverInclude = *serverOldInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.smtp.server-whitelist and --collector.smtp.server-include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
return &SMTPCollector{
|
||||
logger: logger,
|
||||
BadmailedMessagesBadPickupFileTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "badmailed_messages_bad_pickup_file_total"),
|
||||
"Total number of malformed pickup messages sent to badmail",
|
||||
@@ -326,8 +388,8 @@ func NewSMTPCollector() (Collector, error) {
|
||||
nil,
|
||||
),
|
||||
|
||||
serverWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *serverWhitelist)),
|
||||
serverBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *serverBlacklist)),
|
||||
serverIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *serverInclude)),
|
||||
serverExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *serverExclude)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -335,7 +397,7 @@ func NewSMTPCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *SMTPCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
log.Error("failed collecting smtp metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting smtp metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -391,14 +453,14 @@ type PerflibSMTPServer struct {
|
||||
|
||||
func (c *SMTPCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []PerflibSMTPServer
|
||||
if err := unmarshalObject(ctx.perfObjects["SMTP Server"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["SMTP Server"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, server := range dst {
|
||||
if server.Name == "_Total" ||
|
||||
c.serverBlacklistPattern.MatchString(server.Name) ||
|
||||
!c.serverWhitelistPattern.MatchString(server.Name) {
|
||||
c.serverExcludePattern.MatchString(server.Name) ||
|
||||
!c.serverIncludePattern.MatchString(server.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkSmtpCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "smtp", NewSMTPCollector)
|
||||
benchmarkCollector(b, "smtp", newSMTPCollector)
|
||||
}
|
||||
|
||||
@@ -4,16 +4,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("system", NewSystemCollector, "System")
|
||||
}
|
||||
|
||||
// A SystemCollector is a Prometheus collector for WMI metrics
|
||||
type SystemCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
ContextSwitchesTotal *prometheus.Desc
|
||||
ExceptionDispatchesTotal *prometheus.Desc
|
||||
ProcessorQueueLength *prometheus.Desc
|
||||
@@ -22,11 +21,12 @@ type SystemCollector struct {
|
||||
Threads *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewSystemCollector ...
|
||||
func NewSystemCollector() (Collector, error) {
|
||||
// newSystemCollector ...
|
||||
func newSystemCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "system"
|
||||
|
||||
return &SystemCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
ContextSwitchesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "context_switches_total"),
|
||||
"Total number of context switches (WMI source: PerfOS_System.ContextSwitchesPersec)",
|
||||
@@ -70,7 +70,7 @@ func NewSystemCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *SystemCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
log.Error("failed collecting system metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting system metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -89,7 +89,7 @@ type system struct {
|
||||
|
||||
func (c *SystemCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []system
|
||||
if err := unmarshalObject(ctx.perfObjects["System"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["System"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkSystemCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "system", NewSystemCollector)
|
||||
benchmarkCollector(b, "system", newSystemCollector)
|
||||
}
|
||||
|
||||
@@ -4,16 +4,15 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("tcp", NewTCPCollector, "TCPv4", "TCPv6")
|
||||
}
|
||||
|
||||
// A TCPCollector is a Prometheus collector for WMI Win32_PerfRawData_Tcpip_TCPv{4,6} metrics
|
||||
type TCPCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
ConnectionFailures *prometheus.Desc
|
||||
ConnectionsActive *prometheus.Desc
|
||||
ConnectionsEstablished *prometheus.Desc
|
||||
@@ -25,11 +24,12 @@ type TCPCollector struct {
|
||||
SegmentsSentTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewTCPCollector ...
|
||||
func NewTCPCollector() (Collector, error) {
|
||||
// newTCPCollector ...
|
||||
func newTCPCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "tcp"
|
||||
|
||||
return &TCPCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
ConnectionFailures: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "connection_failures_total"),
|
||||
"(TCP.ConnectionFailures)",
|
||||
@@ -91,7 +91,7 @@ func NewTCPCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *TCPCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
log.Error("failed collecting tcp metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting tcp metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -173,7 +173,7 @@ func (c *TCPCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric)
|
||||
var dst []tcp
|
||||
|
||||
// TCPv4 counters
|
||||
if err := unmarshalObject(ctx.perfObjects["TCPv4"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["TCPv4"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dst) != 0 {
|
||||
@@ -181,7 +181,7 @@ func (c *TCPCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric)
|
||||
}
|
||||
|
||||
// TCPv6 counters
|
||||
if err := unmarshalObject(ctx.perfObjects["TCPv6"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["TCPv6"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dst) != 0 {
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkTCPCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "tcp", NewTCPCollector)
|
||||
benchmarkCollector(b, "tcp", newTCPCollector)
|
||||
}
|
||||
|
||||
665
collector/teradici_pcoip.go
Normal file
665
collector/teradici_pcoip.go
Normal file
@@ -0,0 +1,665 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
// A teradiciPcoipCollector is a Prometheus collector for WMI metrics:
|
||||
// win32_PerfRawData_TeradiciPerf_PCoIPSessionAudioStatistics
|
||||
// win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics
|
||||
// win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics
|
||||
// win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
|
||||
// win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics
|
||||
|
||||
type teradiciPcoipCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
AudioBytesReceived *prometheus.Desc
|
||||
AudioBytesSent *prometheus.Desc
|
||||
AudioRXBWkbitPersec *prometheus.Desc
|
||||
AudioTXBWkbitPersec *prometheus.Desc
|
||||
AudioTXBWLimitkbitPersec *prometheus.Desc
|
||||
|
||||
BytesReceived *prometheus.Desc
|
||||
BytesSent *prometheus.Desc
|
||||
PacketsReceived *prometheus.Desc
|
||||
PacketsSent *prometheus.Desc
|
||||
RXPacketsLost *prometheus.Desc
|
||||
SessionDurationSeconds *prometheus.Desc
|
||||
TXPacketsLost *prometheus.Desc
|
||||
|
||||
ImagingActiveMinimumQuality *prometheus.Desc
|
||||
ImagingApex2800Offload *prometheus.Desc
|
||||
ImagingBytesReceived *prometheus.Desc
|
||||
ImagingBytesSent *prometheus.Desc
|
||||
ImagingDecoderCapabilitykbitPersec *prometheus.Desc
|
||||
ImagingEncodedFramesPersec *prometheus.Desc
|
||||
ImagingMegapixelPersec *prometheus.Desc
|
||||
ImagingNegativeAcknowledgements *prometheus.Desc
|
||||
ImagingRXBWkbitPersec *prometheus.Desc
|
||||
ImagingSVGAdevTapframesPersec *prometheus.Desc
|
||||
ImagingTXBWkbitPersec *prometheus.Desc
|
||||
|
||||
RoundTripLatencyms *prometheus.Desc
|
||||
RXBWkbitPersec *prometheus.Desc
|
||||
RXBWPeakkbitPersec *prometheus.Desc
|
||||
RXPacketLossPercent *prometheus.Desc
|
||||
RXPacketLossPercent_Base *prometheus.Desc
|
||||
TXBWActiveLimitkbitPersec *prometheus.Desc
|
||||
TXBWkbitPersec *prometheus.Desc
|
||||
TXBWLimitkbitPersec *prometheus.Desc
|
||||
TXPacketLossPercent *prometheus.Desc
|
||||
TXPacketLossPercent_Base *prometheus.Desc
|
||||
|
||||
USBBytesReceived *prometheus.Desc
|
||||
USBBytesSent *prometheus.Desc
|
||||
USBRXBWkbitPersec *prometheus.Desc
|
||||
USBTXBWkbitPersec *prometheus.Desc
|
||||
}
|
||||
|
||||
// newTeradiciPcoipCollector constructs a new teradiciPcoipCollector
|
||||
func newTeradiciPcoipCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "teradici_pcoip"
|
||||
return &teradiciPcoipCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
AudioBytesReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "audio_bytes_received_total"),
|
||||
"(AudioBytesReceived)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AudioBytesSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "audio_bytes_sent_total"),
|
||||
"(AudioBytesSent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AudioRXBWkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "audio_rx_bw_kbit_persec"),
|
||||
"(AudioRXBWkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AudioTXBWkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "audio_tx_bw_kbit_persec"),
|
||||
"(AudioTXBWkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
AudioTXBWLimitkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "audio_tx_bw_limit_kbit_persec"),
|
||||
"(AudioTXBWLimitkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
|
||||
BytesReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "bytes_received_total"),
|
||||
"(BytesReceived)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
BytesSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "bytes_sent_total"),
|
||||
"(BytesSent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PacketsReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "packets_received_total"),
|
||||
"(PacketsReceived)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
PacketsSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "packets_sent_total"),
|
||||
"(PacketsSent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
RXPacketsLost: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "rx_packets_lost_total"),
|
||||
"(RXPacketsLost)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
SessionDurationSeconds: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "session_duration_seconds_total"),
|
||||
"(SessionDurationSeconds)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TXPacketsLost: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "tx_packets_lost_total"),
|
||||
"(TXPacketsLost)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
|
||||
ImagingActiveMinimumQuality: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_active_min_quality"),
|
||||
"(ImagingActiveMinimumQuality)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingApex2800Offload: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_apex2800_offload"),
|
||||
"(ImagingApex2800Offload)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingBytesReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_bytes_received_total"),
|
||||
"(ImagingBytesReceived)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingBytesSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_bytes_sent_total"),
|
||||
"(ImagingBytesSent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingDecoderCapabilitykbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_decoder_capability_kbit_persec"),
|
||||
"(ImagingDecoderCapabilitykbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingEncodedFramesPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_encoded_frames_persec"),
|
||||
"(ImagingEncodedFramesPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingMegapixelPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_megapixel_persec"),
|
||||
"(ImagingMegapixelPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingNegativeAcknowledgements: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_negative_acks_total"),
|
||||
"(ImagingNegativeAcknowledgements)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingRXBWkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_rx_bw_kbit_persec"),
|
||||
"(ImagingRXBWkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingSVGAdevTapframesPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_svga_devtap_frames_persec"),
|
||||
"(ImagingSVGAdevTapframesPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
ImagingTXBWkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "imaging_tx_bw_kbit_persec"),
|
||||
"(ImagingTXBWkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
|
||||
RoundTripLatencyms: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "round_trip_latency_ms"),
|
||||
"(RoundTripLatencyms)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
RXBWkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "rx_bw_kbit_persec"),
|
||||
"(RXBWkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
RXBWPeakkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "rx_bw_peak_kbit_persec"),
|
||||
"(RXBWPeakkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
RXPacketLossPercent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "rx_packet_loss_percent"),
|
||||
"(RXPacketLossPercent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
RXPacketLossPercent_Base: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "rx_packet_loss_percent_base"),
|
||||
"(RXPacketLossPercent_Base)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TXBWActiveLimitkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "tx_bw_active_limit_kbit_persec"),
|
||||
"(TXBWActiveLimitkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TXBWkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "tx_bw_kbit_persec"),
|
||||
"(TXBWkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TXBWLimitkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "tx_bw_limit_kbit_persec"),
|
||||
"(TXBWLimitkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TXPacketLossPercent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "tx_packet_loss_percent"),
|
||||
"(TXPacketLossPercent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
TXPacketLossPercent_Base: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "tx_packet_loss_percent_base"),
|
||||
"(TXPacketLossPercent_Base)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
|
||||
USBBytesReceived: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "usb_bytes_received_total"),
|
||||
"(USBBytesReceived)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
USBBytesSent: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "usb_bytes_sent_total"),
|
||||
"(USBBytesSent)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
USBRXBWkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "usb_rx_bw_kbit_persec"),
|
||||
"(USBRXBWkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
USBTXBWkbitPersec: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "usb_tx_bw_kbit_persec"),
|
||||
"(USBTXBWkbitPersec)",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *teradiciPcoipCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collectAudio(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting teradici session audio metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
if desc, err := c.collectGeneral(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting teradici session general metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
if desc, err := c.collectImaging(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting teradici session imaging metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
if desc, err := c.collectNetwork(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting teradici session network metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
if desc, err := c.collectUsb(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting teradici session USB metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type win32_PerfRawData_TeradiciPerf_PCoIPSessionAudioStatistics struct {
|
||||
AudioBytesReceived uint64
|
||||
AudioBytesSent uint64
|
||||
AudioRXBWkbitPersec uint64
|
||||
AudioTXBWkbitPersec uint64
|
||||
AudioTXBWLimitkbitPersec uint64
|
||||
}
|
||||
|
||||
type win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics struct {
|
||||
BytesReceived uint64
|
||||
BytesSent uint64
|
||||
PacketsReceived uint64
|
||||
PacketsSent uint64
|
||||
RXPacketsLost uint64
|
||||
SessionDurationSeconds uint64
|
||||
TXPacketsLost uint64
|
||||
}
|
||||
|
||||
type win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics struct {
|
||||
ImagingActiveMinimumQuality uint32
|
||||
ImagingApex2800Offload uint32
|
||||
ImagingBytesReceived uint64
|
||||
ImagingBytesSent uint64
|
||||
ImagingDecoderCapabilitykbitPersec uint32
|
||||
ImagingEncodedFramesPersec uint32
|
||||
ImagingMegapixelPersec uint32
|
||||
ImagingNegativeAcknowledgements uint32
|
||||
ImagingRXBWkbitPersec uint64
|
||||
ImagingSVGAdevTapframesPersec uint32
|
||||
ImagingTXBWkbitPersec uint64
|
||||
}
|
||||
|
||||
type win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics struct {
|
||||
RoundTripLatencyms uint32
|
||||
RXBWkbitPersec uint64
|
||||
RXBWPeakkbitPersec uint32
|
||||
RXPacketLossPercent uint32
|
||||
RXPacketLossPercent_Base uint32
|
||||
TXBWActiveLimitkbitPersec uint32
|
||||
TXBWkbitPersec uint64
|
||||
TXBWLimitkbitPersec uint32
|
||||
TXPacketLossPercent uint32
|
||||
TXPacketLossPercent_Base uint32
|
||||
}
|
||||
|
||||
type win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics struct {
|
||||
USBBytesReceived uint64
|
||||
USBBytesSent uint64
|
||||
USBRXBWkbitPersec uint64
|
||||
USBTXBWkbitPersec uint64
|
||||
}
|
||||
|
||||
func (c *teradiciPcoipCollector) collectAudio(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionAudioStatistics
|
||||
q := queryAll(&dst, c.logger)
|
||||
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.AudioBytesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AudioBytesReceived),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AudioBytesSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AudioBytesSent),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AudioRXBWkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].AudioRXBWkbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AudioTXBWkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].AudioTXBWkbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.AudioTXBWLimitkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].AudioTXBWLimitkbitPersec),
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *teradiciPcoipCollector) collectGeneral(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics
|
||||
q := queryAll(&dst, c.logger)
|
||||
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.BytesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].BytesReceived),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.BytesSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].BytesSent),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].PacketsReceived),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.PacketsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].PacketsSent),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RXPacketsLost,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].RXPacketsLost),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SessionDurationSeconds,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].SessionDurationSeconds),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TXPacketsLost,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].TXPacketsLost),
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *teradiciPcoipCollector) collectImaging(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics
|
||||
q := queryAll(&dst, c.logger)
|
||||
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.ImagingActiveMinimumQuality,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].ImagingActiveMinimumQuality),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingApex2800Offload,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].ImagingApex2800Offload),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingBytesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].ImagingBytesReceived),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingBytesSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].ImagingBytesSent),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingDecoderCapabilitykbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].ImagingDecoderCapabilitykbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingEncodedFramesPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].ImagingEncodedFramesPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingMegapixelPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].ImagingMegapixelPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingNegativeAcknowledgements,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].ImagingNegativeAcknowledgements),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingRXBWkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].ImagingRXBWkbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingSVGAdevTapframesPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].ImagingSVGAdevTapframesPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ImagingTXBWkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].ImagingTXBWkbitPersec),
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *teradiciPcoipCollector) collectNetwork(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
|
||||
q := queryAll(&dst, c.logger)
|
||||
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.RoundTripLatencyms,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].RoundTripLatencyms),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RXBWkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].RXBWkbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RXBWPeakkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].RXBWPeakkbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RXPacketLossPercent,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].RXPacketLossPercent),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RXPacketLossPercent_Base,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].RXPacketLossPercent_Base),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TXBWActiveLimitkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].TXBWActiveLimitkbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TXBWkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].TXBWkbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TXBWLimitkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].TXBWLimitkbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TXPacketLossPercent,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].TXPacketLossPercent),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.TXPacketLossPercent_Base,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].TXPacketLossPercent_Base),
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *teradiciPcoipCollector) collectUsb(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics
|
||||
q := queryAll(&dst, c.logger)
|
||||
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.USBBytesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].USBBytesReceived),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.USBBytesSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].USBBytesSent),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.USBRXBWkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].USBRXBWkbitPersec),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.USBTXBWkbitPersec,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].USBTXBWkbitPersec),
|
||||
)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
9
collector/teradici_pcoip_test.go
Normal file
9
collector/teradici_pcoip_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkTeradiciPcoipCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "teradici_pcoip", newTeradiciPcoipCollector)
|
||||
}
|
||||
@@ -7,28 +7,21 @@ import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const ConnectionBrokerFeatureID uint32 = 133
|
||||
|
||||
func init() {
|
||||
registerCollector("terminal_services", NewTerminalServicesCollector, "Terminal Services", "Terminal Services Session", "Remote Desktop Connection Broker Counterset")
|
||||
}
|
||||
|
||||
var (
|
||||
connectionBrokerEnabled = isConnectionBrokerServer()
|
||||
)
|
||||
|
||||
type Win32_ServerFeature struct {
|
||||
ID uint32
|
||||
}
|
||||
|
||||
func isConnectionBrokerServer() bool {
|
||||
func isConnectionBrokerServer(logger log.Logger) bool {
|
||||
var dst []Win32_ServerFeature
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -37,7 +30,7 @@ func isConnectionBrokerServer() bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
log.Debug("host is not a connection broker skipping Connection Broker performance metrics.")
|
||||
_ = level.Debug(logger).Log("msg", "host is not a connection broker skipping Connection Broker performance metrics.")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -46,6 +39,9 @@ func isConnectionBrokerServer() bool {
|
||||
// https://docs.microsoft.com/en-us/previous-versions/aa394344(v%3Dvs.85)
|
||||
// https://wutils.com/wmi/root/cimv2/win32_perfrawdata_localsessionmanager_terminalservices/
|
||||
type TerminalServicesCollector struct {
|
||||
logger log.Logger
|
||||
connectionBrokerEnabled bool
|
||||
|
||||
LocalSessionCount *prometheus.Desc
|
||||
ConnectionBrokerPerformance *prometheus.Desc
|
||||
HandleCount *prometheus.Desc
|
||||
@@ -65,10 +61,14 @@ type TerminalServicesCollector struct {
|
||||
WorkingSetPeak *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewTerminalServicesCollector ...
|
||||
func NewTerminalServicesCollector() (Collector, error) {
|
||||
// newTerminalServicesCollector ...
|
||||
func newTerminalServicesCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "terminal_services"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
return &TerminalServicesCollector{
|
||||
logger: logger,
|
||||
connectionBrokerEnabled: isConnectionBrokerServer(logger),
|
||||
|
||||
LocalSessionCount: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "local_session_count"),
|
||||
"Number of Terminal Services sessions",
|
||||
@@ -178,18 +178,18 @@ func NewTerminalServicesCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *TerminalServicesCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collectTSSessionCount(ctx, ch); err != nil {
|
||||
log.Error("failed collecting terminal services session count metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
if desc, err := c.collectTSSessionCounters(ctx, ch); err != nil {
|
||||
log.Error("failed collecting terminal services session count metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// only collect CollectionBrokerPerformance if host is a Connection Broker
|
||||
if connectionBrokerEnabled {
|
||||
if c.connectionBrokerEnabled {
|
||||
if desc, err := c.collectCollectionBrokerPerformanceCounter(ctx, ch); err != nil {
|
||||
log.Error("failed collecting Connection Broker performance metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting Connection Broker performance metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -204,7 +204,7 @@ type perflibTerminalServices struct {
|
||||
|
||||
func (c *TerminalServicesCollector) collectTSSessionCount(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
dst := make([]perflibTerminalServices, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Terminal Services"], &dst)
|
||||
err := unmarshalObject(ctx.perfObjects["Terminal Services"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -257,10 +257,11 @@ type perflibTerminalServicesSession struct {
|
||||
|
||||
func (c *TerminalServicesCollector) collectTSSessionCounters(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
dst := make([]perflibTerminalServicesSession, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Terminal Services Session"], &dst)
|
||||
err := unmarshalObject(ctx.perfObjects["Terminal Services Session"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
names := make(map[string]bool)
|
||||
|
||||
for _, d := range dst {
|
||||
// only connect metrics for remote named sessions
|
||||
@@ -268,6 +269,12 @@ func (c *TerminalServicesCollector) collectTSSessionCounters(ctx *ScrapeContext,
|
||||
if n == "" || n == "services" || n == "console" {
|
||||
continue
|
||||
}
|
||||
// don't add name already present in labels list
|
||||
if _, ok := names[n]; ok {
|
||||
continue
|
||||
}
|
||||
names[n] = true
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.HandleCount,
|
||||
prometheus.GaugeValue,
|
||||
@@ -371,7 +378,7 @@ type perflibRemoteDesktopConnectionBrokerCounterset struct {
|
||||
func (c *TerminalServicesCollector) collectCollectionBrokerPerformanceCounter(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
|
||||
dst := make([]perflibRemoteDesktopConnectionBrokerCounterset, 0)
|
||||
err := unmarshalObject(ctx.perfObjects["Remote Desktop Connection Broker Counterset"], &dst)
|
||||
err := unmarshalObject(ctx.perfObjects["Remote Desktop Connection Broker Counterset"], &dst, c.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkTerminalServicesCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "terminal_services", NewTerminalServicesCollector)
|
||||
benchmarkCollector(b, "terminal_services", newTerminalServicesCollector)
|
||||
}
|
||||
|
||||
@@ -27,19 +27,21 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/dimchansky/utfbom"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/prometheus/common/expfmt"
|
||||
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagTextFileDirectory = "collector.textfile.directory"
|
||||
)
|
||||
|
||||
var (
|
||||
textFileDirectory = kingpin.Flag(
|
||||
"collector.textfile.directory",
|
||||
"Directory to read text files with metrics from.",
|
||||
).Default(getDefaultPath()).String()
|
||||
textFileDirectory *string
|
||||
|
||||
mtimeDesc = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, "textfile", "mtime_seconds"),
|
||||
@@ -50,20 +52,28 @@ var (
|
||||
)
|
||||
|
||||
type textFileCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
path string
|
||||
// Only set for testing to get predictable output.
|
||||
mtime *float64
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerCollector("textfile", NewTextFileCollector)
|
||||
// newTextFileCollectorFlags ...
|
||||
func newTextFileCollectorFlags(app *kingpin.Application) {
|
||||
textFileDirectory = app.Flag(
|
||||
FlagTextFileDirectory,
|
||||
"Directory to read text files with metrics from.",
|
||||
).Default(getDefaultPath()).String()
|
||||
}
|
||||
|
||||
// NewTextFileCollector returns a new Collector exposing metrics read from files
|
||||
// newTextFileCollector returns a new Collector exposing metrics read from files
|
||||
// in the given textfile directory.
|
||||
func NewTextFileCollector() (Collector, error) {
|
||||
func newTextFileCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "textfile"
|
||||
return &textFileCollector{
|
||||
path: *textFileDirectory,
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
path: *textFileDirectory,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -92,7 +102,7 @@ func duplicateMetricEntry(metricFamilies []*dto.MetricFamily) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<- prometheus.Metric) {
|
||||
func (c *textFileCollector) convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<- prometheus.Metric) {
|
||||
var valType prometheus.ValueType
|
||||
var val float64
|
||||
|
||||
@@ -108,7 +118,7 @@ func convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<- prometheus.Me
|
||||
|
||||
for _, metric := range metricFamily.Metric {
|
||||
if metric.TimestampMs != nil {
|
||||
log.Warnf("Ignoring unsupported custom timestamp on textfile collector metric %v", metric)
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Ignoring unsupported custom timestamp on textfile collector metric %v", metric))
|
||||
}
|
||||
|
||||
labels := metric.GetLabel()
|
||||
@@ -178,7 +188,7 @@ func convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<- prometheus.Me
|
||||
buckets, values...,
|
||||
)
|
||||
default:
|
||||
log.Errorf("unknown metric type for file")
|
||||
_ = level.Error(c.logger).Log("msg", "unknown metric type for file")
|
||||
continue
|
||||
}
|
||||
if metricType == dto.MetricType_GAUGE || metricType == dto.MetricType_COUNTER || metricType == dto.MetricType_UNTYPED {
|
||||
@@ -246,7 +256,7 @@ func (c *textFileCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Met
|
||||
// Iterate over files and accumulate their metrics.
|
||||
files, err := ioutil.ReadDir(c.path)
|
||||
if err != nil && c.path != "" {
|
||||
log.Errorf("Error reading textfile collector directory %q: %s", c.path, err)
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error reading textfile collector directory %q", c.path), "err", err)
|
||||
error = 1.0
|
||||
}
|
||||
|
||||
@@ -260,27 +270,27 @@ fileLoop:
|
||||
continue
|
||||
}
|
||||
path := filepath.Join(c.path, f.Name())
|
||||
log.Debugf("Processing file %q", path)
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("Processing file %q", path))
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Errorf("Error opening %q: %v", path, err)
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error opening %q: %v", path, err))
|
||||
error = 1.0
|
||||
continue
|
||||
}
|
||||
var parser expfmt.TextParser
|
||||
r, encoding := utfbom.Skip(carriageReturnFilteringReader{r: file})
|
||||
if err = checkBOM(encoding); err != nil {
|
||||
log.Errorf("Invalid file encoding detected in %s: %s - file must be UTF8", path, err.Error())
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Invalid file encoding detected in %s: %s - file must be UTF8", path, err.Error()))
|
||||
error = 1.0
|
||||
continue
|
||||
}
|
||||
parsedFamilies, err := parser.TextToMetricFamilies(r)
|
||||
closeErr := file.Close()
|
||||
if closeErr != nil {
|
||||
log.Warnf("Error closing file: %v", err)
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Error closing file"), "err", err)
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorf("Error parsing %q: %v", path, err)
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error parsing %q: %v", path, err))
|
||||
error = 1.0
|
||||
continue
|
||||
}
|
||||
@@ -292,7 +302,7 @@ fileLoop:
|
||||
families_array = append(families_array, mf)
|
||||
for _, m := range mf.Metric {
|
||||
if m.TimestampMs != nil {
|
||||
log.Errorf("Textfile %q contains unsupported client-side timestamps, skipping entire file", path)
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Textfile %q contains unsupported client-side timestamps, skipping entire file", path))
|
||||
error = 1.0
|
||||
continue fileLoop
|
||||
}
|
||||
@@ -305,7 +315,7 @@ fileLoop:
|
||||
|
||||
// If duplicate metrics are detected in a *single* file, skip processing of file metrics
|
||||
if duplicateMetricEntry(families_array) {
|
||||
log.Errorf("Duplicate metrics detected in file %s. Skipping file processing.", f.Name())
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Duplicate metrics detected in file %s. Skipping file processing.", f.Name()))
|
||||
error = 1.0
|
||||
continue
|
||||
}
|
||||
@@ -321,11 +331,11 @@ fileLoop:
|
||||
|
||||
// If duplicates are detected across *multiple* files, return error.
|
||||
if duplicateMetricEntry(metricFamilies) {
|
||||
log.Errorf("Duplicate metrics detected across multiple files")
|
||||
_ = level.Error(c.logger).Log("msg", "Duplicate metrics detected across multiple files")
|
||||
error = 1.0
|
||||
} else {
|
||||
for _, mf := range metricFamilies {
|
||||
convertMetricFamily(mf, ch)
|
||||
c.convertMetricFamily(mf, ch)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/dimchansky/utfbom"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dimchansky/utfbom"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
|
||||
@@ -3,26 +3,26 @@ package collector
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("thermalzone", NewThermalZoneCollector)
|
||||
}
|
||||
|
||||
// A thermalZoneCollector is a Prometheus collector for WMI Win32_PerfRawData_Counters_ThermalZoneInformation metrics
|
||||
type thermalZoneCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
PercentPassiveLimit *prometheus.Desc
|
||||
Temperature *prometheus.Desc
|
||||
ThrottleReasons *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewThermalZoneCollector ...
|
||||
func NewThermalZoneCollector() (Collector, error) {
|
||||
// newThermalZoneCollector ...
|
||||
func newThermalZoneCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "thermalzone"
|
||||
return &thermalZoneCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
Temperature: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "temperature_celsius"),
|
||||
"(Temperature)",
|
||||
@@ -54,7 +54,7 @@ func NewThermalZoneCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *thermalZoneCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ch); err != nil {
|
||||
log.Error("failed collecting thermalzone metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting thermalzone metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -72,7 +72,7 @@ type Win32_PerfRawData_Counters_ThermalZoneInformation struct {
|
||||
|
||||
func (c *thermalZoneCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_Counters_ThermalZoneInformation
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkThermalZoneCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "thermalzone", NewThermalZoneCollector)
|
||||
benchmarkCollector(b, "thermalzone", newThermalZoneCollector)
|
||||
}
|
||||
|
||||
@@ -6,16 +6,15 @@ package collector
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("time", newTimeCollector, "Windows Time Service")
|
||||
}
|
||||
|
||||
// TimeCollector is a Prometheus collector for Perflib counter metrics
|
||||
type TimeCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
ClockFrequencyAdjustmentPPBTotal *prometheus.Desc
|
||||
ComputedTimeOffset *prometheus.Desc
|
||||
NTPClientTimeSourceCount *prometheus.Desc
|
||||
@@ -24,14 +23,16 @@ type TimeCollector struct {
|
||||
NTPServerOutgoingResponsesTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
func newTimeCollector() (Collector, error) {
|
||||
if getWindowsVersion() <= 6.1 {
|
||||
func newTimeCollector(logger log.Logger) (Collector, error) {
|
||||
if getWindowsVersion(logger) <= 6.1 {
|
||||
return nil, errors.New("Windows version older than Server 2016 detected. The time collector will not run and should be disabled via CLI flags or configuration file")
|
||||
|
||||
}
|
||||
|
||||
const subsystem = "time"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
return &TimeCollector{
|
||||
logger: logger,
|
||||
ClockFrequencyAdjustmentPPBTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "clock_frequency_adjustment_ppb_total"),
|
||||
"Total adjustment made to the local system clock frequency by W32Time in Parts Per Billion (PPB) units.",
|
||||
@@ -75,7 +76,7 @@ func newTimeCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *TimeCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
log.Error("failed collecting time metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting time metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -93,7 +94,7 @@ type windowsTime struct {
|
||||
|
||||
func (c *TimeCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []windowsTime // Single-instance class, array is required but will have single entry.
|
||||
if err := unmarshalObject(ctx.perfObjects["Windows Time Service"], &dst); err != nil {
|
||||
if err := unmarshalObject(ctx.perfObjects["Windows Time Service"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -6,17 +6,16 @@ package collector
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/log"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerCollector("vmware", NewVmwareCollector)
|
||||
}
|
||||
|
||||
// A VmwareCollector is a Prometheus collector for WMI Win32_PerfRawData_vmGuestLib_VMem/Win32_PerfRawData_vmGuestLib_VCPU metrics
|
||||
type VmwareCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
MemActive *prometheus.Desc
|
||||
MemBallooned *prometheus.Desc
|
||||
MemLimit *prometheus.Desc
|
||||
@@ -39,10 +38,11 @@ type VmwareCollector struct {
|
||||
HostProcessorSpeedMHz *prometheus.Desc
|
||||
}
|
||||
|
||||
// NewVmwareCollector constructs a new VmwareCollector
|
||||
func NewVmwareCollector() (Collector, error) {
|
||||
// newVmwareCollector constructs a new VmwareCollector
|
||||
func newVmwareCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "vmware"
|
||||
return &VmwareCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
MemActive: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "mem_active_bytes"),
|
||||
"(MemActiveMB)",
|
||||
@@ -165,11 +165,11 @@ func NewVmwareCollector() (Collector, error) {
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *VmwareCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collectMem(ch); err != nil {
|
||||
log.Error("failed collecting vmware memory metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting vmware memory metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
if desc, err := c.collectCpu(ch); err != nil {
|
||||
log.Error("failed collecting vmware cpu metrics:", desc, err)
|
||||
_ = level.Error(c.logger).Log("failed collecting vmware cpu metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -202,7 +202,7 @@ type Win32_PerfRawData_vmGuestLib_VCPU struct {
|
||||
|
||||
func (c *VmwareCollector) collectMem(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_vmGuestLib_VMem
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -291,7 +291,7 @@ func mbToBytes(mb uint64) float64 {
|
||||
|
||||
func (c *VmwareCollector) collectCpu(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []Win32_PerfRawData_vmGuestLib_VCPU
|
||||
q := queryAll(&dst)
|
||||
q := queryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
1296
collector/vmware_blast.go
Normal file
1296
collector/vmware_blast.go
Normal file
File diff suppressed because it is too large
Load Diff
9
collector/vmware_blast_test.go
Normal file
9
collector/vmware_blast_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkVmwareBlastCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "vmware_blast", newVmwareBlastCollector)
|
||||
}
|
||||
@@ -5,5 +5,5 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkVmwareCollector(b *testing.B) {
|
||||
benchmarkCollector(b, "vmware", NewVmwareCollector)
|
||||
benchmarkCollector(b, "vmware", newVmwareCollector)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user