Compare commits

...

478 Commits

Author SHA1 Message Date
Ben Reedy
05091643c6 Merge pull request #1256 from breed808/fix_msi_flag
fix: Set correct eventlog flag for MSI installer
2023-07-22 08:42:41 +10:00
Ben Reedy
76e73487e4 fix: Set correct eventlog flag for MSI installer
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-07-22 08:38:09 +10:00
Ben Reedy
9a2ec21278 Merge pull request #1255 from jkroepke/fix-eventlog
Fix panic with log.file=eventlog
2023-07-22 08:31:11 +10:00
Jan-Otto Kröpke
44b435e7d4 Fix panic with log.file=eventlog
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-21 20:18:15 +02:00
Ben Reedy
f068cf4523 Merge pull request #1218 from tzifudzi/bugfix/missing-container-metrics
Resolve issue preventing networking container stats from being sent to collector
2023-07-21 18:02:08 +10:00
Tatenda Zifudzi
9adefdceeb fix: Resolve missing container network metrics by querying from HNS
This fix ensures that network stats for containerd on Windows are successfully collected. Before this change, other container stats such as CPU and memory are successfully collected, but network stats are failing for containerd.

The root cause is that the code for collecting network stats was originally written to work with docker which relies on v1 schema. After dockershim removal as Kubernetes's container runtime, containerd adoption has increased and this error is more frequently encountered when using containerd as  the runtime. containerd uses v2 schema whereby the network stats need to be queried from the HNS component.

Signed-off-by: Tatenda Zifudzi <tzifudzi@amazon.com>
2023-07-20 11:22:29 -07:00
Ben Reedy
be9d2872a5 Merge pull request #1241 from jkroepke/perflib
Integrate perflib
2023-07-19 19:32:44 +10:00
Ben Reedy
89cb5439b8 Merge pull request #1243 from DiniFarb/master
Load config file from URL
2023-07-17 20:26:34 +10:00
DiniFarb
b08ce0697c Update readme (flag part)
Signed-off-by: DiniFarb <andreas.vogt89@bluewin.ch>
2023-07-17 20:10:15 +10:00
DiniFarb
279a8fce89 Update readme: config file part
Signed-off-by: DiniFarb <andreas.vogt89@bluewin.ch>
2023-07-17 20:10:07 +10:00
DiniFarb
11ec45e710 feat: Skip TLS verify in loading config from url
Signed-off-by: DiniFarb <andreas.vogt89@bluewin.ch>
2023-07-17 20:09:58 +10:00
DiniFarb
6797126e78 update readme
Signed-off-by: DiniFarb <andreas.vogt89@bluewin.ch>
2023-07-17 20:09:49 +10:00
DiniFarb
19794ad2e0 feat: load config file from url (#1207)
Signed-off-by: DiniFarb <andreas.vogt89@bluewin.ch>
2023-07-17 20:09:39 +10:00
Jan-Otto Kröpke
9e59bf920f Post rebase issues
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 10:05:51 +02:00
Jan-Otto Kröpke
11218a95d0 Implement Lazy Loading of NameTable
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 10:01:46 +02:00
Jan-Otto Kröpke
9b5bc37a42 Re-add NameIndex
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 10:00:46 +02:00
Jan-Otto Kröpke
9ef897e07b Add LICENSE
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 10:00:46 +02:00
Jan-Otto Kröpke
3a61935273 Cleanup binaryReaderFrom
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 10:00:46 +02:00
Jan-Otto Kröpke
8b9c9a5bd2 Remove HelpNameTable
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 10:00:46 +02:00
Jan-Otto Kröpke
976e055252 move directory
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 10:00:43 +02:00
Jan-Otto Kröpke
9e368d49e7 add error handling
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 09:59:46 +02:00
Jan-Otto Kröpke
ad1ab35399 remove SortObjects
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 09:59:46 +02:00
Jan-Otto Kröpke
81745eeedf fix docs
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 09:59:46 +02:00
Jan-Otto Kröpke
fff737998d move global Name Tables
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 09:59:46 +02:00
Jan-Otto Kröpke
4ea61a2641 Remove unused nameTableLookuper
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 09:59:46 +02:00
Jan-Otto Kröpke
750225775b Integrate perflib
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-15 09:59:43 +02:00
Ben Reedy
80cf16efe8 Merge pull request #1245 from bragi92/master
fix: Update init container in windows exporter so that it works on both WS2019 and WS2022
2023-07-15 10:58:31 +10:00
Kaveesh Dubey
f96c6654be fix: Update init container in windows exporter so that it works on both WS2019 and WS2022
Signed-off-by: Kaveesh Dubey <kadubey@microsoft.com>
2023-07-14 17:17:53 -07:00
Ben Reedy
10e42d3583 Merge pull request #1188 from rebortg/master
NPS(feature): add nps collector
2023-07-11 06:28:40 +10:00
Ben Reedy
95f250ed39 feat: Update NPS collector for go-kit logging
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-07-11 06:23:10 +10:00
rebortg
7115c9dc22 add nps collector in init.go
Signed-off-by: rebortg <github@ghlr.de>
2023-07-11 06:04:19 +10:00
rebortg
478eaa91d9 delete init() and rename newNPSCollector function
Signed-off-by: rebortg <github@ghlr.de>
2023-07-11 06:04:15 +10:00
rebortg
217b670272 NPS(feature): add nps collector
Signed-off-by: rebortg <github@ghlr.de>
2023-07-11 06:04:12 +10:00
Ben Reedy
d5e8a0ed7e Merge pull request #1184 from peekjef72/update-terminal_services
fix Terminal Service duplicate session names under load.
2023-07-10 12:06:07 +10:00
Peekjef72
8b74c77663 remove known session name
Signed-off-by: Peekjef72 <67902897+peekjef72@users.noreply.github.com>
2023-07-10 12:00:40 +10:00
Ben Reedy
4077290659 Merge pull request #1192 from jkroepke/custom-logger
switch to go-kit logger
2023-07-10 11:57:32 +10:00
Jan-Otto Kröpke
014153a503 Use 0200 for write permissions
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-10 01:31:26 +02:00
Jan-Otto Kröpke
cfb0111d8c revert fix on newTimeCollector
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-10 00:44:30 +02:00
Jan-Otto Kröpke
5d96a42382 fix typo
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-10 00:44:23 +02:00
Jan-Otto Kröpke
6890f391d4 fix lint
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-09 22:42:00 +02:00
Jan-Otto Kröpke
4350587141 go mod tidy
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-09 22:37:58 +02:00
Jan-Otto Kröpke
8509bc69a6 switch to go-kit logger
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-07-09 22:37:27 +02:00
Ben Reedy
e0e31254e2 Merge pull request #1239 from breed808/pwsh_7.3
feat(doc): Document Powershell v7.3 argument parsing
2023-07-09 13:43:28 +10:00
Ben Reedy
c633aadc71 feat(doc): Document Powershell v7.3 argument parsing
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-07-09 13:42:24 +10:00
Ben Reedy
809424f851 Merge pull request #1238 from prometheus-community/dependabot/go_modules/golang.org/x/sys-0.10.0
chore(deps): bump golang.org/x/sys from 0.8.0 to 0.10.0
2023-07-09 08:13:32 +10:00
dependabot[bot]
88d518378c chore(deps): bump golang.org/x/sys from 0.8.0 to 0.10.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.8.0 to 0.10.0.
- [Commits](https://github.com/golang/sys/compare/v0.8.0...v0.10.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-08 21:57:53 +00:00
Ben Reedy
8cfd6bbcf1 Merge pull request #1230 from prometheus-community/dependabot/go_modules/github.com/prometheus/client_golang-1.16.0
chore(deps): bump github.com/prometheus/client_golang from 1.15.1 to 1.16.0
2023-07-09 07:56:54 +10:00
dependabot[bot]
4ba2fe7f22 chore(deps): bump github.com/prometheus/client_golang
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.15.1 to 1.16.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.15.1...v1.16.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-08 21:51:13 +00:00
Ben Reedy
a49a0fc612 Merge pull request #1225 from prometheus-community/dependabot/go_modules/github.com/leoluk/perflib_exporter-0.2.1
chore(deps): bump github.com/leoluk/perflib_exporter from 0.2.0 to 0.2.1
2023-07-09 07:50:25 +10:00
dependabot[bot]
23722ae792 chore(deps): bump github.com/leoluk/perflib_exporter from 0.2.0 to 0.2.1
Bumps [github.com/leoluk/perflib_exporter](https://github.com/leoluk/perflib_exporter) from 0.2.0 to 0.2.1.
- [Release notes](https://github.com/leoluk/perflib_exporter/releases)
- [Commits](https://github.com/leoluk/perflib_exporter/compare/v0.2.0...v0.2.1)

---
updated-dependencies:
- dependency-name: github.com/leoluk/perflib_exporter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-08 21:43:59 +00:00
Ben Reedy
731b996767 Merge pull request #1224 from prometheus-community/dependabot/go_modules/github.com/yusufpapurcu/wmi-1.2.3
chore(deps): bump github.com/yusufpapurcu/wmi from 1.2.2 to 1.2.3
2023-07-09 07:41:45 +10:00
dependabot[bot]
2fe869f1db chore(deps): bump github.com/yusufpapurcu/wmi from 1.2.2 to 1.2.3
Bumps [github.com/yusufpapurcu/wmi](https://github.com/yusufpapurcu/wmi) from 1.2.2 to 1.2.3.
- [Release notes](https://github.com/yusufpapurcu/wmi/releases)
- [Commits](https://github.com/yusufpapurcu/wmi/compare/v1.2.2...v1.2.3)

---
updated-dependencies:
- dependency-name: github.com/yusufpapurcu/wmi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-12 11:57:50 +00:00
Ben Reedy
6ba0297aa9 Merge pull request #1219 from prometheus-community/dependabot/go_modules/github.com/sirupsen/logrus-1.9.3
chore(deps): bump github.com/sirupsen/logrus from 1.9.0 to 1.9.3
2023-06-12 08:04:43 +10:00
dependabot[bot]
dc3e172056 chore(deps): bump github.com/sirupsen/logrus from 1.9.0 to 1.9.3
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.0 to 1.9.3.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.3)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-11 21:46:01 +00:00
Ben Reedy
4327eb386a Merge pull request #1212 from prometheus-community/dependabot/go_modules/github.com/prometheus/common-0.44.0
chore(deps): bump github.com/prometheus/common from 0.42.0 to 0.44.0
2023-06-12 07:45:12 +10:00
dependabot[bot]
79f4cf5dec chore(deps): bump github.com/prometheus/common from 0.42.0 to 0.44.0
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.42.0 to 0.44.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.42.0...v0.44.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-11 21:39:44 +00:00
Ben Reedy
5aae5054e6 Merge pull request #1204 from prometheus-community/dependabot/go_modules/github.com/prometheus/client_golang-1.15.1
chore(deps): bump github.com/prometheus/client_golang from 1.15.0 to 1.15.1
2023-06-12 07:38:55 +10:00
dependabot[bot]
e81231d403 chore(deps): bump github.com/prometheus/client_golang
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.15.0 to 1.15.1.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.15.0...v1.15.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-11 21:22:52 +00:00
Ben Reedy
0e0d0f8fd8 Merge pull request #1202 from prometheus-community/dependabot/go_modules/github.com/prometheus/exporter-toolkit-0.10.0
chore(deps): bump github.com/prometheus/exporter-toolkit from 0.9.1 to 0.10.0
2023-06-12 07:21:32 +10:00
dependabot[bot]
c1e829dbd5 chore(deps): bump github.com/prometheus/exporter-toolkit
Bumps [github.com/prometheus/exporter-toolkit](https://github.com/prometheus/exporter-toolkit) from 0.9.1 to 0.10.0.
- [Release notes](https://github.com/prometheus/exporter-toolkit/releases)
- [Changelog](https://github.com/prometheus/exporter-toolkit/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prometheus/exporter-toolkit/compare/v0.9.1...v0.10.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/exporter-toolkit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-11 21:15:04 +00:00
Ben Reedy
434788a90a Merge pull request #1205 from prometheus-community/dependabot/go_modules/golang.org/x/sys-0.8.0
chore(deps): bump golang.org/x/sys from 0.7.0 to 0.8.0
2023-06-12 07:13:17 +10:00
Ben Reedy
6c06beca1d Merge pull request #1206 from prometheus-community/dependabot/go_modules/github.com/prometheus/client_model-0.4.0
chore(deps): bump github.com/prometheus/client_model from 0.3.0 to 0.4.0
2023-05-23 17:43:28 +10:00
dependabot[bot]
486b4319c7 chore(deps): bump github.com/prometheus/client_model from 0.3.0 to 0.4.0
Bumps [github.com/prometheus/client_model](https://github.com/prometheus/client_model) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/prometheus/client_model/releases)
- [Commits](https://github.com/prometheus/client_model/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_model
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 12:07:52 +00:00
dependabot[bot]
88847204ff chore(deps): bump golang.org/x/sys from 0.7.0 to 0.8.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.7.0 to 0.8.0.
- [Commits](https://github.com/golang/sys/compare/v0.7.0...v0.8.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 12:07:45 +00:00
Ben Reedy
79781c6d75 Merge pull request #1201 from ilyam8/fix_hyperv_vswitch_missing_sent_packets
fix: add missing vswitch packets_sent_total
2023-05-07 20:46:22 +10:00
Ben Reedy
4cd095798d Merge pull request #1133 from breed808/iis_duplicates
fix: Ignore duplicate IIS entries from Perflib
2023-05-07 20:17:25 +10:00
Ben Reedy
1d3af58305 fix: Ignore duplicate IIS entries from Perflib
Perflib often exposes duplicate IIS entries, suffixed with '#' and a
number (I.E. iis_site_name#1).
These duplicate entries were causing the exporter to fail scraping due
to duplicate metrics.

Based on user feedback, the entry with the highest suffix
value is kept, with other duplicate entries discarded.

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" ]

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-05-07 20:12:32 +10:00
Ben Reedy
b431ff6ac3 Merge pull request #1195 from jkroepke/custom-collector
Move prometheus collector from main to collectors
2023-05-07 13:04:58 +10:00
ilyam8
579369dbf5 fix: add missing vswitch packets_sent_total
Signed-off-by: ilyam8 <ilya@netdata.cloud>
2023-05-04 19:25:17 +03:00
Ben Reedy
f19fa777c3 Merge pull request #1189 from vrapolinario/viniap-msft-ws2022
Add yaml for WS2022 nodes
2023-04-30 08:13:27 +10:00
vrapolinario
0db55044e8 Add yaml for WS2022 nodes
Signed-off-by: vrapolinario <viniap@microsoft.com>
2023-04-26 14:49:27 -07:00
Jan-Otto Kröpke
352492ea97 Move collector from main to separate package
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-04-23 15:25:41 +02:00
Ben Reedy
76c435d12c Merge pull request #1170 from breed808/include_exclude
feat!: Deprecate whitelist/blacklist flags
2023-04-19 09:15:30 +10:00
Ben Reedy
fab77d9d31 feat!: Deprecate whitelist/blacklist flags
Flags have been deprecated in favour of include/exclude terminology.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-04-19 06:11:23 +10:00
Ben Reedy
3627520559 Merge pull request #1186 from jkroepke/custom-kingpin
Remove fluent-style kingpin
2023-04-18 08:27:00 +10:00
Ben Reedy
b033ff71ff Merge pull request #1187 from prometheus-community/dependabot/go_modules/github.com/prometheus/client_golang-1.15.0
chore(deps): bump github.com/prometheus/client_golang from 1.14.0 to 1.15.0
2023-04-18 07:14:44 +10:00
dependabot[bot]
8d781cf540 chore(deps): bump github.com/prometheus/client_golang
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.14.0...v1.15.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-17 11:58:31 +00:00
Jan-Otto Kröpke
da6898afc4 Remove fluent-style kingpin
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-04-17 13:22:36 +02:00
Ben Reedy
a105e088b3 Merge pull request #1181 from prometheus-community/dependabot/go_modules/golang.org/x/sys-0.7.0
chore(deps): bump golang.org/x/sys from 0.6.0 to 0.7.0
2023-04-15 05:31:59 +10:00
Ben Reedy
30955eae17 Merge pull request #1183 from Elpatii/master
Fix telemetry.addr deprecated since v0.21.0
2023-04-15 05:31:13 +10:00
Elpatii
d7b08d7ce0 Fix telemetry.addr deprecated since v0.21.0
Signed-off-by: Elpatii <4057711+Elpatii@users.noreply.github.com>
2023-04-12 14:52:55 +02:00
dependabot[bot]
05abe04d90 chore(deps): bump golang.org/x/sys from 0.6.0 to 0.7.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/golang/sys/releases)
- [Commits](https://github.com/golang/sys/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 11:57:37 +00:00
Ben Reedy
bacd040b17 Merge pull request #1174 from breed808/adfs_jwt
fix!: Fix jtw -> jwt ADFS spelling error
2023-04-04 06:15:29 +10:00
Ben Reedy
1df91ba769 fix!: Fix jtw -> jwt ADFS spelling error
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-04-04 05:49:39 +10:00
Ben Reedy
4e02053f13 Merge pull request #1171 from breed808/diskdrive_name
fix!: Set correct diskdrive collector/metric name
2023-04-04 05:48:05 +10:00
Ben Reedy
535f041423 fix!: Set correct diskdrive collector/metric name
Previous name did not match documentation and WMI class.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-04-03 06:17:15 +10:00
Ben Reedy
49afc93d93 Merge pull request #1112 from breed808/remove_init
Remove init functions from collectors
2023-04-01 18:17:27 +10:00
Ben Reedy
04257a1b25 chore: Ensure collector build funcs are private
Collector builder functions are only used internally in the `collector`
package, and shouldn't needlessly be exposed as part of the package API
to downstream clients.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-04-01 17:54:41 +10:00
Ben Reedy
9214a87d0d feat: Remove init functions from collectors
Behaviour of init functions has been centralised in `collector/init.go`,
and can be called during exporter startup. This allows the exporter to
control the timing of collector initialisation, rather than relying on
the import & `init()` method.

This should reduce unexpected behaviour arising from the use of
`init()`, such as #551.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-04-01 17:54:40 +10:00
Ben Reedy
8132083892 Merge pull request #1167 from breed808/ci_deps
chore(ci): Update release workflow actions
2023-03-27 07:04:30 +10:00
Ben Reedy
890fac507e chore(ci): Update release workflow actions
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-03-27 07:03:01 +10:00
Ben Reedy
b29434c7c0 Merge pull request #1166 from breed808/net_output_queue_length
feat: Add output_queue_length metric to net collector
2023-03-26 06:55:02 +10:00
Ben Reedy
7e293a4230 feat: Add output_queue_length metric to net collector
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-03-26 06:48:39 +10:00
Ben Reedy
e21407c112 Merge pull request #1165 from prometheus-community/superq/landing_page
Use new landing page generator
2023-03-26 06:00:29 +10:00
SuperQ
bee042d9fa Use new landing page generator
Use the new exporter-toolkit landing page generator feature.
* Update Go to 1.20.
* Update promu to 0.14.0.

Signed-off-by: SuperQ <superq@gmail.com>
2023-03-25 10:41:48 +01:00
Ben Reedy
6efeace169 Merge pull request #1161 from breed808/default_metrics
feat: Allow default metrics to be disabled
2023-03-25 09:05:52 +10:00
Ben Reedy
a5b3926063 feat: Remove default metrics from e2e test
Metrics are provided by client library, and not the exporter, so
comparing them for differences does not provide much value.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-03-25 09:00:05 +10:00
Ben Reedy
6306973948 feat: Allow default metrics to be disabled
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-03-25 08:59:54 +10:00
Ben Reedy
84b6f15505 Merge pull request #1162 from Mak0tin/update-doc-mssql-iis
Update docs for mssql and iis
2023-03-24 15:49:34 +10:00
Manuel Hernandez
0a75d72610 Update collector.mssql.md
Update metric types from counter to gauge to match code

Signed-off-by: Manuel Hernandez <106690360+Mak0tin@users.noreply.github.com>
2023-03-21 15:49:32 +01:00
Manuel Hernandez
549c4d1098 Update collector.iis.md
Update metric types from counter to gauge to match code

Signed-off-by: Manuel Hernandez <106690360+Mak0tin@users.noreply.github.com>
2023-03-21 12:28:30 +01:00
Ben Reedy
ea2b446130 Merge pull request #1158 from mansikulkarni96/fix1157
fix: Build error with GOFLAGS=-mod=vendor
2023-03-21 07:14:12 +10:00
mansikulkarni96
6129a528c6 fix: Build error with GOFLAGS=-mod=vendor
This commit updates go version in go.mod to go1.17
to resolve build error when vendor flag is used.
Package x/sys/windows requires go1.17 or above
causing make build to fail.

Fixes: #1157
Signed-off-by: mansikulkarni96 <mankulka@redhat.com>
2023-03-20 16:29:10 -04:00
Ben Reedy
13c5bc5c95 Merge pull request #1160 from prometheus-community/dependabot/go_modules/github.com/Microsoft/hcsshim-0.9.8
chore(deps): bump github.com/Microsoft/hcsshim from 0.9.7 to 0.9.8
2023-03-21 05:35:54 +10:00
dependabot[bot]
78b11f9dc0 chore(deps): bump github.com/Microsoft/hcsshim from 0.9.7 to 0.9.8
Bumps [github.com/Microsoft/hcsshim](https://github.com/Microsoft/hcsshim) from 0.9.7 to 0.9.8.
- [Release notes](https://github.com/Microsoft/hcsshim/releases)
- [Commits](https://github.com/Microsoft/hcsshim/compare/v0.9.7...v0.9.8)

---
updated-dependencies:
- dependency-name: github.com/Microsoft/hcsshim
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 11:58:22 +00:00
Ben Reedy
0dc4acac00 Merge pull request #1144 from fuxingZhang/patch-1
docs: fix documentation error
2023-03-19 08:03:10 +10:00
zfx
931c3f78d9 docs: fix documentation errors
Fix the documentation and code inconsistencies caused by the following commit
> e9c594473c

Signed-off-by: zfx <fuxing.zhang@qq.com>
2023-03-13 15:46:36 +08:00
Ben Reedy
6a26df8069 Merge pull request #1148 from ankom2007/patch-1
Update collector.iis.md
2023-03-13 09:47:41 +10:00
Ben Reedy
a4404fa77a Merge pull request #1150 from prometheus-community/dependabot/go_modules/github.com/prometheus/exporter-toolkit-0.9.1
chore(deps): bump github.com/prometheus/exporter-toolkit from 0.8.2 to 0.9.1
2023-03-13 09:44:23 +10:00
dependabot[bot]
e19f80e5c7 chore(deps): bump github.com/prometheus/exporter-toolkit
Bumps [github.com/prometheus/exporter-toolkit](https://github.com/prometheus/exporter-toolkit) from 0.8.2 to 0.9.1.
- [Release notes](https://github.com/prometheus/exporter-toolkit/releases)
- [Changelog](https://github.com/prometheus/exporter-toolkit/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prometheus/exporter-toolkit/compare/v0.8.2...v0.9.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/exporter-toolkit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 09:36:27 +10:00
Ben Reedy
416ccf1228 chore(deps): bump github.com/alecthomas/kingpin
Bumps [github.com/alecthomas/kingpin](https://github.com/alecthomas/kingpin) from
v2.2.6 to v2.3.2.

This also changes the upstream package name from
gopkg.in/alecthomas/kingpin.v2 to github.com/alecthomas/kingpin/v2 which
is required by the upstream exporter-toolkit package.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-03-13 09:36:23 +10:00
Ben Reedy
edbccbdad4 Merge pull request #1151 from prometheus-community/dependabot/go_modules/github.com/prometheus/common-0.42.0
chore(deps): bump github.com/prometheus/common from 0.39.0 to 0.42.0
2023-03-12 18:34:16 +10:00
dependabot[bot]
aa66719b30 chore(deps): bump github.com/prometheus/common from 0.39.0 to 0.42.0
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.39.0 to 0.42.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.39.0...v0.42.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-12 08:11:20 +00:00
Ben Reedy
b1b8c34361 Merge pull request #1146 from prometheus-community/dependabot/go_modules/golang.org/x/sys-0.6.0
chore(deps): bump golang.org/x/sys from 0.4.0 to 0.6.0
2023-03-12 18:10:12 +10:00
dependabot[bot]
9c08c916e0 chore(deps): bump golang.org/x/sys from 0.4.0 to 0.6.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.4.0 to 0.6.0.
- [Release notes](https://github.com/golang/sys/releases)
- [Commits](https://github.com/golang/sys/compare/v0.4.0...v0.6.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-12 07:41:49 +00:00
Ben Reedy
b6c91bfe8c Merge pull request #1152 from breed808/wmi_upstream_change
chore(deps): Update wmi to v1.2.2
2023-03-12 17:41:01 +10:00
Ben Reedy
7886cf9e37 chore(deps): Update wmi to v1.2.2
This includes a move from github.com/StackExchange/wmi to
github.com/yusufpapurcu/wmi, as the StackExchange repository has been
archived.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-03-12 17:34:34 +10:00
Ben Reedy
8d4c38b48e chore(ci): Update golangci-lint to v1.51.2
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-03-12 17:34:33 +10:00
Ben Reedy
0a26661b7d Merge pull request #1142 from prometheus-community/dependabot/go_modules/github.com/Microsoft/hcsshim-0.9.7
chore(deps): bump github.com/Microsoft/hcsshim from 0.9.6 to 0.9.7
2023-03-12 09:31:16 +10:00
Ankur Agarwal
864687daed Update collector.iis.md
Added the description of the metrics for "no documented yet"

Signed-off-by: Ankur Agarwal <75574195+ankom2007@users.noreply.github.com>
2023-03-08 18:16:41 +11:00
dependabot[bot]
c8c3cefecc chore(deps): bump github.com/Microsoft/hcsshim from 0.9.6 to 0.9.7
Bumps [github.com/Microsoft/hcsshim](https://github.com/Microsoft/hcsshim) from 0.9.6 to 0.9.7.
- [Release notes](https://github.com/Microsoft/hcsshim/releases)
- [Commits](https://github.com/Microsoft/hcsshim/compare/v0.9.6...v0.9.7)

---
updated-dependencies:
- dependency-name: github.com/Microsoft/hcsshim
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 11:59:24 +00:00
Ben Reedy
12e5422845 Merge pull request #1137 from DennisGaida/patch-1
Added quote information for absolute paths
2023-02-25 09:57:37 +10:00
Ben Reedy
a7960872bb Merge pull request #1136 from bck01215/patch-2
Remove Bad Comment
2023-02-18 11:17:07 +10:00
Dennis Gaida
94aff9fe73 Added quote information for absolute paths
This had me running in circles because `ioutil.ReadFile` did not read the local file for me when running as a service (i.e. `config.yml` in the same folder as the `windows_exporter.exe`). I had to use absolute paths and additionally quote them.

Signed-off-by: Dennis Gaida <2392217+DennisGaida@users.noreply.github.com>
2023-02-15 16:40:22 +01:00
Brandon Kauffman
9044097f2c Remove Bad Comment
Signed-off-by: Brandon Kauffman <bck01215@gmail.com>
2023-02-14 08:56:11 -05:00
Ben Reedy
a52ce30089 Merge pull request #1127 from tpowelldev/master
Add VDI Metrics collections
2023-02-12 09:44:35 +10:00
Tom Powell
846263afee Returning test functions to public
Signed-off-by: Tom Powell <t.powell@mwam.com>
2023-02-08 10:12:15 +00:00
Tom Powell
ba3cffdc79 Applying PR comments
Signed-off-by: Tom Powell <t.powell@mwam.com>
2023-02-08 09:30:36 +00:00
Tom Powell
dde839b66d Adding Teradici PCoIP session metrics collection
Signed-off-by: Tom Powell <t.powell@mwam.com>

Added collector for VMware Blast session metrics

Signed-off-by: Tom Powell <t.powell@mwam.com>

Updating collection logic to handle missing WMI classes

Signed-off-by: Tom Powell <t.powell@mwam.com>

Updating packet loss metric to gauge

Signed-off-by: Tom Powell <t.powell@mwam.com>
2023-01-25 12:04:55 +00:00
Ben Reedy
ca15e2c70d Merge pull request #1121 from breed808/diskdrive_docs
Add labels to diskdrive docs
2023-01-15 09:53:27 +10:00
Ben Reedy
0ea3bfa5c9 chore(docs): Add labels to diskdrive docs
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-01-15 09:51:45 +10:00
Ben Reedy
5331909446 Merge pull request #1095 from 6fears7/master
Add Win32_DiskDrive Collector
2023-01-15 09:27:49 +10:00
Ben Reedy
e8eb77363e Merge pull request #1119 from prometheus-community/dependabot/go_modules/golang.org/x/sys-0.4.0
chore(deps): bump golang.org/x/sys from 0.3.0 to 0.4.0
2023-01-14 08:47:08 +10:00
pgibbs1
da2707c594 Removed placeholder text
Signed-off-by: pgibbs1 <pgibbs1@liberty.edu>
2023-01-12 17:08:59 -05:00
pgibbs1
b0844b9118 Fixed linting md
Signed-off-by: pgibbs1 <pgibbs1@liberty.edu>
2023-01-12 17:08:59 -05:00
pgibbs1
27977e3730 Added collector docs, entry to readme
Signed-off-by: pgibbs1 <pgibbs1@liberty.edu>
2023-01-12 17:08:59 -05:00
sixfears7
f2f9f624b5 Updated naming convention, fixed metric type
Signed-off-by: sixfears7 <57415489+6fears7@users.noreply.github.com>
Signed-off-by: pgibbs1 <pgibbs1@liberty.edu>
2023-01-12 17:08:59 -05:00
sixfears7
586152a4ad Updated code to add label to size and partition
Signed-off-by: sixfears7 <57415489+6fears7@users.noreply.github.com>
Signed-off-by: pgibbs1 <pgibbs1@liberty.edu>
2023-01-12 17:08:59 -05:00
pgibbs1
9a2ef3fca8 Fixed blackslashes, replaced model with name
Signed-off-by: pgibbs1 <pgibbs1@liberty.edu>
2023-01-12 17:08:59 -05:00
pgibbs1
6912c5b1e7 Removed commented benchmark
Signed-off-by: pgibbs1 <pgibbs1@liberty.edu>
2023-01-12 17:08:59 -05:00
pgibbs1
f24fc07ac4 Fixed moved files
Signed-off-by: pgibbs1 <pgibbs1@liberty.edu>
2023-01-12 17:08:59 -05:00
sixfears7
653182a90c Added diskdrive collector
To retrieve data from Win32_DiskDrive Object

Signed-off-by: sixfears7 <57415489+6fears7@users.noreply.github.com>
Signed-off-by: pgibbs1 <pgibbs1@liberty.edu>
2023-01-12 17:08:59 -05:00
dependabot[bot]
2958e0801d chore(deps): bump golang.org/x/sys from 0.3.0 to 0.4.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/golang/sys/releases)
- [Commits](https://github.com/golang/sys/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 11:04:33 +00:00
Ben Reedy
f5a3cf7839 Merge pull request #1118 from breed808/ci_fix
Fix CI release issues
2023-01-06 07:47:25 +10:00
Ben Reedy
72995f4bb1 fix(ci): Disable ARM MSI builds
Version of Wix in use (3.11.0.1701) doesn't support ARM builds.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-01-06 07:44:53 +10:00
Ben Reedy
1db0dd909b fix(ci): Set correct download URL for promu tool
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-01-06 07:44:52 +10:00
Ben Reedy
cd23833ff2 Merge pull request #1117 from breed808/ci
Update deprecated Github Actions
2023-01-05 22:30:38 +10:00
Ben Reedy
20d7048478 chore(ci): Update deprecated Github Actions
checkout@v2 and go-setup@v2 both used a deprecated Node.js version (12)

See https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/
for context

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-01-05 22:26:33 +10:00
Ben Reedy
a8fad055ac Merge pull request #1115 from breed808/ci
Split CI/CD configuration
2023-01-05 22:05:36 +10:00
Ben Reedy
484385d387 feat(ci): Download promu binaries
Compiling of promu tool unnecessarily extended CI duration.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-01-05 22:01:33 +10:00
Ben Reedy
bf181eee38 feat(ci): Split CI/CD configuration
`build` job was redundant for PRs and pushes to `master` branch, as `go build`
is run in the e2e job.

Linting jobs only need to be run for code changes, and were unnecessarily
extending CI duration for documentation changes.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-01-05 22:01:29 +10:00
Ben Reedy
260e34394a Merge pull request #1113 from tehseenshahab/tesh-logical-disk-collector-extension
Add Avg logical disk RW Queue metrics
2023-01-03 10:12:42 +10:00
Tehseen Shahab
d0c6d13e3b Update e2e output for new metrics
Signed-off-by: Tehseen Shahab <tehseen.shahab@gmail.com>
2023-01-02 11:02:45 +01:00
Tehseen Shahab
f10a06f908 Update metric type to gauge
Signed-off-by: Tehseen Shahab <tehseen.shahab@gmail.com>
2023-01-02 11:02:45 +01:00
Tehseen Shahab
7479946385 Update metric type to gauge
Signed-off-by: Tehseen Shahab <tehseen.shahab@gmail.com>
2023-01-02 11:02:45 +01:00
Tehseen Shahab
66a1e18c32 Add Avg logical disk RW Queue metrics
Signed-off-by: Tehseen Shahab <tehseen.shahab@gmail.com>
2023-01-02 11:02:44 +01:00
Ben Reedy
10078892c2 Merge pull request #1110 from prometheus-community/dependabot/go_modules/github.com/prometheus/common-0.39.0
chore(deps): bump github.com/prometheus/common from 0.38.0 to 0.39.0
2023-01-02 07:04:47 +10:00
dependabot[bot]
f6912cc645 chore(deps): bump github.com/prometheus/common from 0.38.0 to 0.39.0
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.38.0 to 0.39.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.38.0...v0.39.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-02 06:54:18 +10:00
Ben Reedy
c791e5212c Merge pull request #1114 from breed808/scheduled_task_example
Add scheduled_task flag examples
2023-01-01 12:27:10 +10:00
Ben Reedy
09bc4e9e1b chore(docs): Add scheduled_task flag examples
Signed-off-by: Ben Reedy <breed808@breed808.com>
2023-01-01 12:13:21 +10:00
Ben Reedy
015b7c0666 Merge pull request #1109 from prometheus-community/dependabot/go_modules/github.com/Microsoft/hcsshim-0.9.6
chore(deps): bump github.com/Microsoft/hcsshim from 0.9.4 to 0.9.6
2022-12-21 07:39:20 +10:00
dependabot[bot]
5dda46de98 chore(deps): bump github.com/Microsoft/hcsshim from 0.9.4 to 0.9.6
Bumps [github.com/Microsoft/hcsshim](https://github.com/Microsoft/hcsshim) from 0.9.4 to 0.9.6.
- [Release notes](https://github.com/Microsoft/hcsshim/releases)
- [Commits](https://github.com/Microsoft/hcsshim/compare/v0.9.4...v0.9.6)

---
updated-dependencies:
- dependency-name: github.com/Microsoft/hcsshim
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-19 11:06:46 +00:00
Ben Reedy
25c1449b91 Merge pull request #1108 from breed808/os_paging
fix: Continue os collection on missing page file
2022-12-17 16:59:01 +10:00
Ben Reedy
29086368ac fix: Continue os collection on missing page file
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-12-17 07:37:25 +10:00
Ben Reedy
1f9d29470c Merge pull request #1104 from prometheus-community/dependabot/go_modules/github.com/prometheus/common-0.38.0
chore(deps): bump github.com/prometheus/common from 0.37.0 to 0.38.0
2022-12-16 22:28:38 +10:00
Ben Reedy
1493a20262 Merge pull request #1088 from higels/add_mperf_metric
Add cpu metrics based on newer and more accurate perflib sources
2022-12-16 21:51:01 +10:00
dependabot[bot]
f8c98e60db chore(deps): bump github.com/prometheus/common from 0.37.0 to 0.38.0
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.37.0 to 0.38.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.37.0...v0.38.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-12 11:03:13 +00:00
Steffen Higel
f32342400f Fixing up e2e tests for new CPU perf metrics
Signed-off-by: Steffen Higel <higels@valvesoftware.com>
2022-12-08 14:08:32 -08:00
Ben Reedy
9a73630b48 Merge pull request #1102 from prometheus-community/dependabot/go_modules/golang.org/x/sys-0.3.0
chore(deps): bump golang.org/x/sys from 0.2.0 to 0.3.0
2022-12-06 06:44:01 +10:00
dependabot[bot]
5da47255e2 chore(deps): bump golang.org/x/sys from 0.2.0 to 0.3.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/golang/sys/releases)
- [Commits](https://github.com/golang/sys/compare/v0.2.0...v0.3.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-05 11:03:34 +00:00
Ben Reedy
eb102fd37f Merge pull request #1100 from knabben/dedup-listen-address
Cleaning up listen addresses flags before parsing config file
2022-12-04 13:04:32 +10:00
Amim Knabben
3aa409590f Cleaning up listen addresses flags before parsing config file
Signed-off-by: Amim Knabben <aknabben@vmware.com>
2022-12-03 21:03:58 -03:00
Ben Reedy
e8991095d4 Merge pull request #1099 from breed808/exporter_toolkit
chore(deps): bump github.com/prometheus/exporter-toolkit from 0.8.1 to 0.8.2
2022-11-30 19:24:37 +10:00
Ben Reedy
3dbb37deb5 chore(deps): bump github.com/prometheus/exporter-toolkit from 0.8.1 to 0.8.2
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-11-30 18:58:27 +10:00
Ben Reedy
53b6816612 Merge pull request #1096 from bck01215/patch-1
Compatibily with new flag web.listen-address
2022-11-23 19:14:18 +10:00
Ben Reedy
44b63dc23c Merge pull request #1093 from prometheus-community/dependabot/go_modules/github.com/prometheus/client_golang-1.14.0
chore(deps): bump github.com/prometheus/client_golang from 1.13.0 to 1.14.0
2022-11-23 18:29:54 +10:00
Ben Reedy
8b8fd2d3a6 Merge pull request #1094 from prometheus-community/dependabot/go_modules/golang.org/x/sys-0.2.0
chore(deps): bump golang.org/x/sys from 0.1.0 to 0.2.0
2022-11-23 18:27:57 +10:00
Brandon Kauffman
134f62511f Compatibily with ne flag web.listen-address
Signed-off-by: Brandon Kauffman <bck01215@gmail.com>
2022-11-18 20:02:42 -05:00
dependabot[bot]
09a83cf01f chore(deps): bump golang.org/x/sys from 0.1.0 to 0.2.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.1.0 to 0.2.0.
- [Release notes](https://github.com/golang/sys/releases)
- [Commits](https://github.com/golang/sys/compare/v0.1.0...v0.2.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-14 11:03:46 +00:00
dependabot[bot]
46ed47c585 chore(deps): bump github.com/prometheus/client_golang
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.13.0 to 1.14.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.13.0...v1.14.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-14 11:03:36 +00:00
Steffen Higel
187dbfc4ae Add cpu metrics based on newer and more accurate perflib sources
This change adds 4 new CPU related metrics:

 * process_mperf_total
 * processor_rtc_total
 * processor_utility_total
 * processor_privileged_utility_total

and renames the existing process_performance to
processor_performance_total, since it was previously misunderstood and
was unlikely to be have been useful without the above new metrics

The data sources for these are not particularly well understood, and the
examples show that in some cases, arbitrary scaling factors are required
to actually make them useful, but in my testing on hundreds of systems
with a broad range of CPUs and operating systems from 2012r2 through to
2019 has proved out that we can use them to accurately display actual
CPU frequencies and CPU utilisation as it is represented in taskmgr.

Things I don't particularly like and would like input on:

 * I would have preferred to do the scaling of processor_mperf_total in
the code, but there isn't an elegant way of doing this right now.
 * Maybe processor_mperf_total should be called
processor_mperformance_total.

See #787 for discussion.

Signed-off-by: Steffen Higel <higels@valvesoftware.com>
2022-11-02 14:34:04 -07:00
Ben Reedy
6ddab61fa5 Merge pull request #1084 from breed808/perflib
chore(deps): bump perflib to v0.2.0
2022-10-25 16:01:29 +10:00
Ben Reedy
e4b8b5718f chore(deps): bump perflib to v0.2.0
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-10-25 15:51:32 +10:00
Ben Reedy
86f12b9e55 Merge pull request #1082 from prometheus-community/dependabot/go_modules/github.com/prometheus/exporter-toolkit-0.8.1
chore(deps)!: bump github.com/prometheus/exporter-toolkit from 0.7.1 to 0.8.1
2022-10-25 11:50:28 +10:00
Ben Reedy
48cef00491 Merge pull request #1083 from vear959595/master
Add files via upload
2022-10-25 11:40:11 +10:00
Ben Reedy
e9c594473c chore(deps)!: bump github.com/prometheus/exporter-toolkit
Introduction of `web.listen-address` flag in upstream library
(bca43f192e)
has necessitated the removal of the `telemetry.addr` flag in favour of
the upstream flag.

Bumps [github.com/prometheus/exporter-toolkit](https://github.com/prometheus/exporter-toolkit) from 0.7.1 to 0.8.1.
- [Release notes](https://github.com/prometheus/exporter-toolkit/releases)
- [Changelog](https://github.com/prometheus/exporter-toolkit/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prometheus/exporter-toolkit/compare/v0.7.1...v0.8.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/exporter-toolkit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-10-25 11:38:50 +10:00
Ben Reedy
63fb570b23 Merge pull request #1081 from prometheus-community/dependabot/go_modules/github.com/prometheus/client_model-0.3.0
chore(deps): bump github.com/prometheus/client_model from 0.2.0 to 0.3.0
2022-10-25 09:09:21 +10:00
dependabot[bot]
cff611b60c chore(deps): bump github.com/prometheus/client_model from 0.2.0 to 0.3.0
Bumps [github.com/prometheus/client_model](https://github.com/prometheus/client_model) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/prometheus/client_model/releases)
- [Commits](https://github.com/prometheus/client_model/compare/v0.2.0...v0.3.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_model
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-24 22:58:04 +00:00
Ben Reedy
9a262579ce Merge pull request #1080 from breed808/scheduled_task_memory
fix: Remove memory leaks in scheduled_task
2022-10-25 08:51:32 +10:00
Ben Reedy
25d23852d4 fix: Remove memory leaks in scheduled_task
OLE objects must be manually cleared or released to prevent leaks.
Note that these objects do not appear in the heap, so the pprof heap
profiles aren't helpful in identifying OLE leaks.
Resident memory continues to increase if objects are not properly cleared.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-10-25 08:36:36 +10:00
Ben Reedy
70dcd80f3d Merge pull request #1055 from breed808/arm64_builds
Add ARM64 builds to releases
2022-10-25 08:32:26 +10:00
vear959595
c3fa0039ba Add files via upload
adding 503 http error collector

Signed-off-by: vear959595 <69949561+vear959595@users.noreply.github.com>
2022-10-24 21:26:54 +07:00
Ben Reedy
7a6e2d7456 feat(ci): Add ARM64 builds to releases
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-10-24 21:21:43 +10:00
Ben Reedy
68f7efec32 Merge pull request #1077 from MarNicGit/patch-1
Update collector.process.md
2022-10-22 10:03:03 +10:00
Ben Reedy
15b8276cf3 Merge pull request #1078 from gillg/bump-x-sys
Try to bump /x/sys to the current stable version to fix IsWindowsService()
2022-10-19 21:18:07 +10:00
Guillaume Gill
e01dd5e334 Try to bump /x/sys to the current stable version to fix IsWindowsService()
Signed-off-by: Guillaume Gill <guillaume.gill@orangelogic.com>
2022-10-18 22:45:30 +02:00
MarNicGit
8f8369a356 Fixed spelling error
Signed-off-by: MarNicGit <47538428+MarNicGit@users.noreply.github.com>
2022-10-18 10:50:09 +02:00
MarNicGit
347759933f Update collector.process.md
Documented IIS worker process apppool matching.

Discovered this feature at [process.go:221](eb73859393/collector/process.go (L221)). This also solves issue #1074.

Signed-off-by: MarNicGit <47538428+MarNicGit@users.noreply.github.com>
2022-10-18 10:50:09 +02:00
Ben Reedy
eb73859393 Merge pull request #1075 from MarNicGit/patch-1
Update regex
2022-10-10 19:22:45 +10:00
MarNicGit
3e2357fd68 Update regex
Updated the regexp's to better working ones. `.+` does not match process names with no extension. Also used a neater regexp for the `|` example.

Signed-off-by: MarNicGit <47538428+MarNicGit@users.noreply.github.com>
2022-10-08 00:00:53 +02:00
Ben Reedy
677a7c8d67 Merge pull request #1065 from shivsepra/patch-1
Update collector.mssql.md
2022-09-24 06:59:04 +10:00
Shiva Prasad
8f05e77b0a Update collector.mssql.md
Corrected the buffer cache hit ratio PromQL

Signed-off-by: Shiva Prasad <sr7231@gmail.com>
2022-09-21 15:27:34 +05:30
Ben Reedy
8efca83ac4 Merge pull request #1059 from kaffarell/master
Added WebService uptime metric in iis collector
2022-09-14 07:19:51 +10:00
kaffarell
fb38512f38 Added WebService uptime metric in iis collector
Signed-off-by: kaffarell <gabrielgoller123@gmail.com>
2022-09-13 16:41:44 +02:00
Ben Reedy
63800b5c6a Merge pull request #1061 from kaffarell/patch-1
Update collector.logon.md
2022-09-13 06:31:47 +10:00
Gabriel Goller
c1b7ca42c5 Update collector.logon.md
Signed-off-by: Gabriel Goller <gabrielgoller123@gmail.com>
2022-09-10 12:34:19 +02:00
Ben Reedy
f8abca5292 Merge pull request #999 from trunov-ms/master
fix PercentTimeinGC metric
2022-09-10 10:55:25 +10:00
Max Trunov
2ef7c5604a gofmt netframework_clrmemory.go
Signed-off-by: Max Trunov <trunov_ms@taximaxim.ru>
2022-09-09 17:13:26 +05:00
Ben Reedy
a0a81c4a9f Merge pull request #1060 from kaffarell/iis-docs
Added documentation for iis collector
2022-09-09 20:23:42 +10:00
kaffarell
8e27a9983f Added documentation for iis collector
Signed-off-by: kaffarell <gabrielgoller123@gmail.com>
2022-09-09 12:08:33 +02:00
amdmax
6d506887cd Add comments to changes
Signed-off-by: Max Trunov <trunov_ms@taximaxim.ru>
2022-09-07 09:13:12 +05:00
Ben Reedy
15be1c1bd6 Merge pull request #1052 from breed808/os_version_docs
Document recent changes to os_build_info metric
2022-08-30 18:00:40 +10:00
Ben Reedy
7bd2ebc6d0 Document recent changes to os_build_info metric
Changes introduced in 46fa84f have exposed additional labels to the
os_build_info metric.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-08-30 17:50:15 +10:00
Ben Reedy
690fe8de86 Merge pull request #1051 from benridley/feature_version_info
Export extra version information
2022-08-30 16:47:26 +10:00
Ben Ridley
46fa84f9b0 Export extra version information
Adds major version, minor version, and build number as independent
labels when exporting OS info.

Signed-off-by: Ben Ridley <benridley29@gmail.com>
2022-08-29 22:02:00 -07:00
Ben Reedy
4b226cde40 Merge pull request #1047 from jammiemil/master
fix Windows Service timeout during high CPU (eg. post Windows Update)
2022-08-24 21:00:22 +10:00
Ben Reedy
cdeceaeca5 Merge pull request #1034 from gloyka/master
Add Hyper-V Hypervisor Logical Processor metrics
2022-08-24 19:11:18 +10:00
Jamie Milton
8061c4e5fa Additional Comments
Signed-off-by: Jamie Milton <jammiemil@hotmail.com>
2022-08-24 10:04:23 +01:00
Jamie Milton
981d687e60 Remove unused Const
Signed-off-by: Jamie Milton <jammiemil@hotmail.com>
2022-08-24 09:16:16 +01:00
Anton Akhmedzyanov
37ea988125 Added percent suffix for metric names
Signed-off-by: Anton Akhmedzyanov <gloin@gloin.ru>
2022-08-23 19:42:16 +03:00
Anton Akhmedzyanov
a722cee322 Add Hyper-V Hypervisor CPU utilization query.
Signed-off-by: Anton Akhmedzyanov <gloin@gloin.ru>
2022-08-23 19:42:16 +03:00
Anton Akhmedzyanov
b43978eeb4 Add Hyper-V Hypervisor Logical Processor metrics
Signed-off-by: Anton Akhmedzyanov <gloin@gloin.ru>
2022-08-23 19:42:16 +03:00
Jamie Milton
f02f51aceb Correct Channel Definition
Signed-off-by: Jamie Milton <jammiemil@hotmail.com>
2022-08-23 16:47:31 +01:00
Jamie Milton
a5f22ebb04 Move Service Initiate out to seperate package
Signed-off-by: Jamie Milton <jammiemil@hotmail.com>
2022-08-23 14:57:16 +01:00
Ben Reedy
1c199e6c0e Merge pull request #1036 from alvarocabanas/master
Fix Error "Service Access is denied" in service collector useApi
2022-08-23 07:38:08 +10:00
Ben Reedy
306197fe93 Merge pull request #1028 from prometheus-community/dependabot/go_modules/github.com/sirupsen/logrus-1.9.0
chore(deps): bump github.com/sirupsen/logrus from 1.8.1 to 1.9.0
2022-08-21 18:38:11 +10:00
dependabot[bot]
45fac2a618 chore(deps): bump github.com/sirupsen/logrus from 1.8.1 to 1.9.0
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.8.1 to 1.9.0.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.8.1...v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-21 08:28:00 +00:00
Ben Reedy
716707cd06 Merge pull request #1043 from breed808/ci_spellcheck
Fix broken Spellcheck CI job
2022-08-20 21:55:56 +10:00
Ben Reedy
4b0bcb46d0 Fix Exchange docs spelling error
Required to fix Github CI/CD

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-08-20 21:44:42 +10:00
Ben Reedy
55312ebdca Don't spellcheck Go dependency files
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-08-20 21:44:38 +10:00
Ben Reedy
3df660799c Merge pull request #1041 from prometheus-community/dependabot/go_modules/github.com/prometheus/client_golang-1.13.0
chore(deps): bump github.com/prometheus/client_golang from 1.12.2 to 1.13.0
2022-08-20 20:27:37 +10:00
dependabot[bot]
8ef590ee3a chore(deps): bump github.com/prometheus/client_golang
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.12.2 to 1.13.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.12.2...v1.13.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-08 11:13:15 +00:00
alvarocabanas
c9e28c4c00 Fix Service Access is denied in collector useApi
Signed-off-by: Alvaro Cabanas <albanas@gmail.com>
Signed-off-by: alvarocabanas <acabanas@newrelic.com>
2022-07-29 10:53:29 +02:00
Ben Reedy
c5ec339750 Merge pull request #1030 from prometheus-community/dependabot/go_modules/gopkg.in/yaml.v3-3.0.1
chore(deps): bump gopkg.in/yaml.v3 from 3.0.0 to 3.0.1
2022-07-27 19:51:10 +10:00
Ben Reedy
2602ca04f6 Merge pull request #1029 from prometheus-community/dependabot/go_modules/github.com/Microsoft/hcsshim-0.9.4
chore(deps): bump github.com/Microsoft/hcsshim from 0.9.3 to 0.9.4
2022-07-27 19:48:28 +10:00
dependabot[bot]
8fe8e85559 chore(deps): bump gopkg.in/yaml.v3 from 3.0.0 to 3.0.1
Bumps [gopkg.in/yaml.v3](https://github.com/go-yaml/yaml) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/go-yaml/yaml/releases)
- [Commits](https://github.com/go-yaml/yaml/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: gopkg.in/yaml.v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 11:25:10 +00:00
dependabot[bot]
38cfae3e66 chore(deps): bump github.com/Microsoft/hcsshim from 0.9.3 to 0.9.4
Bumps [github.com/Microsoft/hcsshim](https://github.com/Microsoft/hcsshim) from 0.9.3 to 0.9.4.
- [Release notes](https://github.com/Microsoft/hcsshim/releases)
- [Commits](https://github.com/Microsoft/hcsshim/compare/v0.9.3...v0.9.4)

---
updated-dependencies:
- dependency-name: github.com/Microsoft/hcsshim
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 11:25:06 +00:00
Ben Reedy
b2ed5f61b4 Merge pull request #997 from breed808/yaml_v3
Update gopkg.in/yaml_v2 to yaml_v3
2022-07-25 17:15:39 +10:00
Ben Reedy
752d467b12 Merge pull request #1026 from breed808/ci
Add content write permissions to GITHUB_TOKEN
2022-07-23 19:24:58 +10:00
Ben Reedy
1fab2621eb Add content write permissions to GITHUB_TOKEN
Write permissions are required to upload release artifacts.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-07-23 19:05:47 +10:00
Ben Reedy
739642bd6a Merge pull request #1015 from breed808/iis_log_noise
Skip missing IIS instances
2022-07-23 10:31:18 +10:00
Ben Reedy
a4cf96d94d Skip missing IIS instances
Collector would previously break from loop rather than skip nameless
entries, with the additional result of spamming event logs.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-07-23 09:59:01 +10:00
Ben Reedy
1dd7b58bdf Merge pull request #1025 from alexwiedermann/mscluster-fix-wrong-metric
fix: remove UpdateDomain (mscluster-resourcegroup)
2022-07-23 09:57:03 +10:00
Ben Reedy
c696fb40cf Merge pull request #1021 from prometheus-community/dependabot/go_modules/github.com/prometheus/common-0.37.0
chore(deps): bump github.com/prometheus/common from 0.35.0 to 0.37.0
2022-07-23 09:47:02 +10:00
Alex Wiedermann
ae4bc822e8 fix: remove UpdateDomain (mscluster-resourcegroup)
UpdateDomain metric not exists as we can see in  https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resourcegroup, just removing from mscluster_resourcegroup.go
When execute windows_exporter.exe with this metric we get this error:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x60 pc=0xaad61d]

goroutine 66 [running]:
github.com/prometheus/client_golang/prometheus.NewConstMetric(0xc00009de30?, 0x2?, 0x3ff0000000000000?, {0xc000387730?, 0x1?, 0x1?})
        C:/Users/ricar/go/pkg/mod/github.com/prometheus/client_golang@v1.12.2/prometheus/value.go:88 +0x1d
github.com/prometheus/client_golang/prometheus.MustNewConstMetric(...)
        C:/Users/ricar/go/pkg/mod/github.com/prometheus/client_golang@v1.12.2/prometheus/value.go:105
github.com/prometheus-community/windows_exporter/collector.(*MSCluster_ResourceGroupCollector).Collect(0xc000552000, 0x0?, 0x0?)
        E:/Downloads/Prometheus/windows_exporter/windows_exporter/collector/mscluster_resourcegroup.go:240 +0xdfb
main.execute({0xc00006e0c6, 0x17}, {0xef6420, 0xc000552000}, 0x0?, 0x0?)
        E:/Downloads/Prometheus/windows_exporter/windows_exporter/exporter.go:199 +0x84
main.windowsCollector.Collect.func2({0xc00006e0c6, 0x17}, {0xef6420?, 0xc000552000?})
        E:/Downloads/Prometheus/windows_exporter/windows_exporter/exporter.go:140 +0x9b
created by main.windowsCollector.Collect
        E:/Downloads/Prometheus/windows_exporter/windows_exporter/exporter.go:138 +0x5c5

Signed-off-by: Alex Wiedermann <alexwdrnn@gmail.com>
2022-07-22 18:06:29 -03:00
dependabot[bot]
096949c682 chore(deps): bump github.com/prometheus/common from 0.35.0 to 0.37.0
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.35.0 to 0.37.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.35.0...v0.37.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-18 11:20:37 +00:00
Ben Reedy
da15c9659d Merge pull request #1020 from Woldelig/patch-1
Update collector.fsrmquota.md
2022-07-16 10:31:37 +10:00
Christoffer Wold
a12b3e0ea0 Update collector.fsrmquota.md
Fix table formatting

Signed-off-by: Christoffer Wold <christoffer.wold@gmail.com>
2022-07-15 10:33:35 +02:00
Ben Reedy
7e7bdc104f Merge pull request #1012 from gopihc/patch-1
Update kubernetes.md
2022-07-02 07:05:52 +10:00
Gopi Chinnappa
682e6967b0 Update kubernetes.md
Signed-off-by: Gopi Chinnappa <gopihc@gmail.com>
2022-06-28 17:29:56 +05:30
Ben Reedy
93dcdf95f7 Merge pull request #885 from sstorie/mscluster
Add support for MSCluster collectors
2022-06-23 19:25:48 +10:00
Ben Reedy
3619d14844 Merge pull request #1003 from prometheus-community/dependabot/go_modules/github.com/prometheus/common-0.35.0
Bump github.com/prometheus/common from 0.34.0 to 0.35.0
2022-06-21 07:18:11 +10:00
dependabot[bot]
9712fa3bad Bump github.com/prometheus/common from 0.34.0 to 0.35.0
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.34.0 to 0.35.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.34.0...v0.35.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-20 11:38:44 +00:00
Sam Storie
fe7730a51b chore: adding links to the doc pages in the README
Signed-off-by: Storie <Sam.Storie@Emerson.com>
2022-06-19 18:40:43 +10:00
Sam Storie
61ea9d049c chore: fix mis-spelling
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:42 +10:00
Sam Storie
a50fe95370 chore: adding/updating the documentation for mscluster_resourcegroup collector
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:41 +10:00
Sam Storie
33615c8b58 chore: updating the label list in the docs
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:40 +10:00
Sam Storie
313ffb73bd chore: Adding/updating the documentation for mscluster_resource collector
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:39 +10:00
Sam Storie
48e54e8513 chore: Adding/updating documentation for mscluster_node collector
The isolation or quarantine status of the node.

Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:39 +10:00
Sam Storie
bf5177ed12 chore: fixing a typo
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:38 +10:00
Sam Storie
00f79ebaf4 chore: Adding/updating documentation for mscluster_network collector
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:37 +10:00
Sam Storie
3d50cf4309 chore: Added/updated documentation for mscluster_cluster collector
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:36 +10:00
Sam Storie
c7cbc48afc chore: updated links to MS documentation for each struct
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:35 +10:00
Sam Storie
0f304413b5 chore: removing some errant comments about perflib
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:34 +10:00
Sam Storie
b6f12aeb9f feat: added the mscluster_resourcegroup collector functionality
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:33 +10:00
Sam Storie
af523f13bc feat: added the mscluster_resource collector functionality
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:32 +10:00
Sam Storie
8c7dd7fd5f feat: added the mscluster_cluster collector functionality
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:31 +10:00
Sam Storie
6a186f26f0 feat: added mscluster_network collector functionality
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:30 +10:00
Sam Storie
740e277cf6 feat: Adding mscluster_node collector functionality
Breaks out the metrics by the name specified by each node

Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:29 +10:00
Sam Storie
96e081c7d4 feat: adapting to support CimSession and alternative namespaces
Signed-off-by: Sam Storie <sam.storie@emerson.com>
2022-06-19 18:40:28 +10:00
Ben Reedy
3cf0fa347f Merge pull request #954 from breed808/os_paging
Continue OS collector on absent paging file
2022-06-12 09:27:19 +10:00
Ben Reedy
ebabddf558 Continue OS collector on absent paging file
Inactive or missing paging file should not be cause for OS collector to
fail.
Instead, log the error and continue with OS collection.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-06-12 09:13:21 +10:00
amdmax
4e76e6938a fix PercentTimeinGC metric
Signed-off-by: Max Trunov <trunov_ms@taximaxim.ru>
2022-06-10 14:45:45 +05:00
Ben Reedy
5f9759586e Update gopkg.in/yaml_v2 to yaml_v3
Previous version was vulnerable to CVE-2022-28948

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-05-29 10:46:09 +10:00
Ben Reedy
7f69cc0acf Merge pull request #995 from prometheus-community/dependabot/go_modules/github.com/Microsoft/hcsshim-0.9.3
Bump github.com/Microsoft/hcsshim from 0.9.2 to 0.9.3
2022-05-29 10:30:43 +10:00
dependabot[bot]
820c6bdb93 Bump github.com/Microsoft/hcsshim from 0.9.2 to 0.9.3
Bumps [github.com/Microsoft/hcsshim](https://github.com/Microsoft/hcsshim) from 0.9.2 to 0.9.3.
- [Release notes](https://github.com/Microsoft/hcsshim/releases)
- [Commits](https://github.com/Microsoft/hcsshim/compare/v0.9.2...v0.9.3)

---
updated-dependencies:
- dependency-name: github.com/Microsoft/hcsshim
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 11:13:54 +00:00
Ben Reedy
6042ea3e51 Merge pull request #990 from prometheus-community/dependabot/go_modules/github.com/go-kit/log-0.2.1
Bump github.com/go-kit/log from 0.2.0 to 0.2.1
2022-05-17 09:25:51 +10:00
dependabot[bot]
641f3222c7 Bump github.com/go-kit/log from 0.2.0 to 0.2.1
Bumps [github.com/go-kit/log](https://github.com/go-kit/log) from 0.2.0 to 0.2.1.
- [Release notes](https://github.com/go-kit/log/releases)
- [Commits](https://github.com/go-kit/log/compare/v0.2.0...v0.2.1)

---
updated-dependencies:
- dependency-name: github.com/go-kit/log
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 23:12:38 +00:00
Ben Reedy
9241df5528 Merge pull request #989 from prometheus-community/dependabot/go_modules/github.com/go-ole/go-ole-1.2.6
Bump github.com/go-ole/go-ole from 1.2.5 to 1.2.6
2022-05-17 09:11:46 +10:00
dependabot[bot]
c443eafe2b Bump github.com/go-ole/go-ole from 1.2.5 to 1.2.6
Bumps [github.com/go-ole/go-ole](https://github.com/go-ole/go-ole) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/go-ole/go-ole/releases)
- [Changelog](https://github.com/go-ole/go-ole/blob/master/ChangeLog.md)
- [Commits](https://github.com/go-ole/go-ole/compare/v1.2.5...v1.2.6)

---
updated-dependencies:
- dependency-name: github.com/go-ole/go-ole
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 22:50:05 +00:00
Ben Reedy
0cd6fd3f3c Merge pull request #988 from prometheus-community/dependabot/go_modules/github.com/prometheus/client_golang-1.12.2
Bump github.com/prometheus/client_golang from 1.12.1 to 1.12.2
2022-05-17 08:49:13 +10:00
Ben Reedy
79a3a1ccec Adjust e2e output for client_golang-1.12.2
v1.12.2 removes some high cardinality metrics introduced in v1.12.0.
See https://github.com/prometheus/client_golang/issues/967 for context.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-05-17 08:04:25 +10:00
dependabot[bot]
603cb54e8f Bump github.com/prometheus/client_golang from 1.12.1 to 1.12.2
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.12.1 to 1.12.2.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.12.1...v1.12.2)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 11:14:21 +00:00
Ben Reedy
329a96de44 Merge pull request #968 from breed808/textfile
Skip processing files with duplicates metrics
2022-05-16 18:46:23 +10:00
Ben Reedy
fd36eae54d Merge pull request #982 from yangliyl/fix/replace-functions
replace these deprecated functions
2022-05-15 13:13:53 +10:00
yangliyl
0dc32bf434 replace these deprecated functions
Signed-off-by: yangliyl <yangli_yl@qq.com>
2022-05-15 09:49:08 +08:00
Ben Reedy
306e63a240 Skip processing files with duplicates metrics
This change affects processing of single files with duplicate metrics.
Single files with duplicate metrics will be skipped, with no metrics being
collected and exposed by the exporter.

Previous duplicate metric processing across multiple files remains
unchanged (all files skipped, collector returns error).

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-05-15 08:56:23 +10:00
Ben Reedy
42c05df272 Merge pull request #969 from breed808/init_powershell
Use `powershell` image for firewall init container
2022-05-15 08:47:10 +10:00
Ben Reedy
f471cc0e4e Use powershell image for firewall init container
Previous `nanoserver` image did not have Powershell installed, causing
the init container to fail.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-05-15 08:38:31 +10:00
Calle Pettersson
3c4ae95a8d Merge pull request #821 from mousavian/master
Adding Scheduled Tasks Collector
2022-05-14 21:00:23 +02:00
Ben Reedy
21f4757b63 Merge pull request #971 from andbanman/ft_hyperv_vm_memory
Add Hyper-V VM Memory metrics
2022-05-13 07:43:16 +10:00
Ben Reedy
4aba3e1222 Add initial docs for hyperv memory metrics
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-05-13 07:14:55 +10:00
Andrew Banman
8f6204f960 Fix typo in vm_memory_pressure_minimum description
Signed-off-by: Andrew Banman <abanman@pnri.org>
2022-05-12 13:26:26 -07:00
Andrew Banman
dd494b11bb Add _total to hyper-v memory counter metrics
Signed-off-by: Andrew Banman <abanman@pnri.org>
2022-05-12 10:00:59 -07:00
Andrew Banman
9f384e3db1 Fix hyper-v collector memory metric names
Remove "memory", which is redundant with the module and breaks symmetry
with vm_memory_physical_guest_visible.

Signed-off-by: Andrew Banman <abanman@pnri.org>
2022-05-12 09:54:41 -07:00
Andrew Banman
68c338b479 Fix hyper-v collector memory metric descriptions
Signed-off-by: Andrew Banman <abanman@pnri.org>
2022-05-12 09:53:47 -07:00
Andrew Banman
a01f72a8b0 Fix Hyper-V VM memory metric types
Signed-off-by: Andrew Banman <abanman@pnri.org>
2022-05-12 09:49:31 -07:00
Andrew Banman
09ec6e68ad Add Hyper-V VM Memory metrics
Signed-off-by: Andrew Banman <abanman@pnri.org>
2022-05-12 09:49:31 -07:00
Rahman Mousavian
5dc10096f9 Dropping 0.0 value from float declaration
Signed-off-by: Rahman Mousavian <rahman.mousavian@oracle.com>
2022-05-12 17:51:43 +10:00
Rahman Mousavian
1aa00ebca8 Handling errors to prevent panics
Signed-off-by: Rahman Mousavian <rahman.mousavian@oracle.com>
2022-05-12 17:51:43 +10:00
Rahman Mousavian
fb11263c3e Initilizing once, upon app start
Signed-off-by: Rahman Mousavian <rahman.mousavian@oracle.com>
2022-05-12 16:36:47 +10:00
Rahman Mousavian
9df59c75cd Using CoInitializeEx, Locking OLE calls to the OS thread
Signed-off-by: Rahman Mousavian <rahman.mousavian@oracle.com>
2022-05-12 16:36:46 +10:00
Rahman Mousavian
e112446ce9 changing anonymous funcs to normal funcs
Signed-off-by: Rahman Mousavian <rahman.mousavian@oracle.com>
2022-05-12 16:36:46 +10:00
Rahman Mousavian
4f82e02d8d Updated README.md
Signed-off-by: Rahman Mousavian <rahman.mousavian@oracle.com>
2022-05-12 16:36:46 +10:00
Rahman Mousavian
c3ed036402 Added tests
Signed-off-by: Rahman Mousavian <rahman.mousavian@oracle.com>
2022-05-12 16:36:46 +10:00
Rahman Mousavian
393546fe01 Added doc for Scheduled Task collector
Signed-off-by: Rahman Mousavian <rahman.mousavian@oracle.com>
2022-05-12 16:36:46 +10:00
Rahman Mousavian
ca645edde1 Added Scheduled Task Collector
Signed-off-by: Rahman Mousavian <rahman.mousavian@oracle.com>
2022-05-12 16:36:42 +10:00
Ben Reedy
69d4043ce4 Merge pull request #977 from prometheus-community/dependabot/go_modules/github.com/prometheus/common-0.34.0
Bump github.com/prometheus/common from 0.33.0 to 0.34.0
2022-05-04 08:58:25 +10:00
dependabot[bot]
fd5135f5ff Bump github.com/prometheus/common from 0.33.0 to 0.34.0
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.33.0 to 0.34.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.33.0...v0.34.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 22:42:53 +00:00
Ben Reedy
8f08f55cf2 Merge pull request #970 from breed808/ci
Resolve recent CI issues
2022-05-04 05:46:27 +10:00
Calle Pettersson
92d53d07b2 Merge pull request #913 from mjtrangoni/fix-memory-non-counter
Fix memory collector promtool metric issues
2022-05-01 19:15:15 +02:00
Ben Reedy
02e2e257c9 Use go install for build deps
Previous `go get` method of installation was causing issues with
`goversiontool`, preventing successful CI builds.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-04-07 09:13:16 +10:00
Ben Reedy
791df8009c Update golangci-lint CI action to latest version
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-04-07 09:13:10 +10:00
Ben Reedy
aaf202236d Merge pull request #965 from prometheus-community/dependabot/go_modules/github.com/prometheus/common-0.33.0
Bump github.com/prometheus/common from 0.32.1 to 0.33.0
2022-04-06 20:24:58 +10:00
dependabot[bot]
e9ba751c82 Bump github.com/prometheus/common from 0.32.1 to 0.33.0
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.32.1 to 0.33.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.32.1...v0.33.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 11:15:41 +00:00
Calle Pettersson
ed83cb1c3e Merge pull request #963 from jsturtevant/fix-k8s-doc-formatting
Fix formatting for kubernetes documentation
2022-04-03 08:53:45 +02:00
James Sturtevant
ac447e5b15 Fix formatting
Signed-off-by: GitHub <noreply@github.com>
2022-04-01 23:34:10 +00:00
Ben Reedy
4d2a247e50 Merge pull request #948 from breed808/ci_tag_name
Fix image build issues
2022-02-27 18:51:06 +10:00
Ben Reedy
54f86001ad Merge pull request #949 from szediktam/fix/container-docs-typo
fix: typo of container docs
2022-02-27 18:50:07 +10:00
szediktam
bccb3b3296 fix: typo of container docs
Signed-off-by: szediktam <alianlianlianlian@gmail.com>
2022-02-27 16:32:45 +08:00
Ben Reedy
c6285cdf9d Fix VERSION env variable for image push
Powershell uses $Env: prefix for environment variables.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-02-27 17:28:51 +10:00
Ben Reedy
cde750f76d Replace invalid tag characters for master images
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-02-27 17:28:46 +10:00
Ben Reedy
dedd60f02b Merge pull request #943 from szediktam/feat/add_storage_metrics_for_container
feat: add storage metrics for container collector
2022-02-27 13:42:32 +10:00
szediktam
d0c9fc6dbb feat: add useful queries example for container docs
Signed-off-by: szediktam <alianlianlianlian@gmail.com>
2022-02-27 13:32:34 +10:00
szediktam
f728224ef2 feat: add storage metrics for container collector
Signed-off-by: szediktam <alianlianlianlian@gmail.com>
2022-02-27 13:32:23 +10:00
Ben Reedy
fba7682f01 Merge pull request #945 from breed808/ci_master_pushes
Run CI on pushes to master branch
2022-02-27 13:31:29 +10:00
Ben Reedy
79ecaf6a99 Check for listening exporter before querying
CI runs have exposed timing issues where promtool/e2e scripts query the
exporter, before exporter has begun listening.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-02-27 08:37:42 +10:00
Ben Reedy
6941ee7ab2 Run promtool windows_exporter on non-default port
Prevents conflicts when promtool & test jobs are run concurrently in
CI.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-02-26 20:43:25 +10:00
Ben Reedy
5a9711dc90 Run CI on pushes to master branch
Required to keep container image (with "latest" tag) up to date. Will
also ensure the master branch is healthy after PR merges.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-02-26 09:25:27 +10:00
Ben Reedy
5106b829c3 Merge pull request #907 from breed808/ci_promtool
Check default collector metrics with promtool
2022-02-08 18:47:09 +10:00
Ben Reedy
e1796c3d42 Upgrade promu build tool to v0.13.0
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-02-08 17:15:03 +10:00
Ben Reedy
14d3e4ea28 Check default collector metrics with promtool
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-02-08 17:14:39 +10:00
Ben Reedy
36f033ae57 Merge pull request #925 from breed808/cpu_docs
Ensure CPU time description matches `mode` flag
2022-02-08 08:09:18 +10:00
Ben Reedy
0de2fc4af7 Merge pull request #864 from jsturtevant/use-hostprocess
Add HostProcess Container Configuration for k8s
2022-02-08 08:07:24 +10:00
James Sturtevant
b450a50103 Add HostProcess Container Configuration for k8s
Co-authored-by: Brian Redmond <brianisrunning@gmail.com>
Signed-off-by: Brian Redmond <brianisrunning@gmail.com>
Signed-off-by: James Sturtevant <jstur@microsoft.com>
2022-02-07 10:16:34 -08:00
Ben Reedy
e07b2053af Merge pull request #937 from breed808/iis_flags
Add missing whitelist/blacklist checks for IIS
2022-02-02 18:18:13 +10:00
Ben Reedy
7d3c0d3b76 Add missing whitelist/blacklist checks for IIS
Checks were removed in 82f17fd despite flags still being present.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-02-02 08:56:50 +10:00
Ben Reedy
27b2ca0b76 Merge pull request #921 from aymericDD/fix/903
fix: iis metrics greater than IIS v7
2022-01-31 18:53:59 +10:00
Aymeric Daurelle
803a0a9a70 fix: iis metrics greater than IIS v7
The IIS >= 8 metrics was updated two times by application and caused a fatal error. The purpose
of this fix is to update metrics one time by application.

Signed-off-by: Aymeric Daurelle <aymeric.daurelle@cdiscount.com>
2022-01-31 09:24:52 +01:00
Ben Reedy
4891acba2d Merge pull request #934 from prometheus-community/dependabot/go_modules/github.com/prometheus/client_golang-1.12.1
Bump github.com/prometheus/client_golang from 1.11.0 to 1.12.1
2022-01-30 15:46:21 +10:00
Ben Reedy
fa51270218 Add new client_golang metrics to e2e output
Introduced in github.com/prometheus/client_golang v1.12.0

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-01-30 15:31:53 +10:00
dependabot[bot]
a68e6af15a Bump github.com/prometheus/client_golang from 1.11.0 to 1.12.1
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.11.0 to 1.12.1.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.11.0...v1.12.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-30 04:49:07 +00:00
Ben Reedy
7ad9b6d74a Merge pull request #927 from prometheus-community/dependabot/go_modules/github.com/Microsoft/hcsshim-0.9.2
Bump github.com/Microsoft/hcsshim from 0.9.1 to 0.9.2
2022-01-30 14:48:21 +10:00
dependabot[bot]
9acd5e695e Bump github.com/Microsoft/hcsshim from 0.9.1 to 0.9.2
Bumps [github.com/Microsoft/hcsshim](https://github.com/Microsoft/hcsshim) from 0.9.1 to 0.9.2.
- [Release notes](https://github.com/Microsoft/hcsshim/releases)
- [Commits](https://github.com/Microsoft/hcsshim/compare/v0.9.1...v0.9.2)

---
updated-dependencies:
- dependency-name: github.com/Microsoft/hcsshim
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-30 04:38:23 +00:00
Ben Reedy
d4be3b9f31 Ensure CPU time description matches mode flag
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-01-30 13:26:40 +10:00
Ben Reedy
277f141587 Merge pull request #924 from breed808/e2e_fix
Don't upgrade dependencies when installing tools
2022-01-30 12:12:45 +10:00
Ben Reedy
2a5c51a236 Don't upgrade dependencies when installing tools
Dependency upgrade has resulted in github.com/prometheus/client_golang
being upgraded from v1.11.0 to v1.12.0 prior to end-to-end test.
This new release introduces new `go_*` metrics, causing the test to
fail on the unexpected output.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-01-23 09:19:06 +10:00
Ben Reedy
ce205d4c4d Merge pull request #909 from akrauza/more-adfs-metrics-again
Add more ADFS metrics from `AD FS` CounterSet
2022-01-11 09:10:28 +10:00
Austin D. Krauza
2ed0ae837c Add more ADFS metrics from AD FS CounterSet
Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>

Reformat adfsCollector struct

Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>

Add metrics to ADFS collector documentation

Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>

Update ADFS collector with useful queries and links to documentation

Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>

Remove bad table formatter

Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>

Reformat ADFS collector using gofmt

Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>

Fix ADFS Config and Artifact DB Query time metrics

Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>

Update ADFS collector for Config and Artifact DB Query time from gauge to counter

Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>

Update ADFS collector for Config and Artifact DB Query time from gauge to counter

Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>
2022-01-10 17:27:34 -05:00
Mario Trangoni
57c7911c91 Fix memory collector promtool metric issues
See,
```
windows_memory_demand_zero_faults_total non-counter metrics should not have "_total" suffix
windows_memory_cache_faults_total non-counter metrics should not have "_total" suffix
windows_memory_page_faults_total non-counter metrics should not have "_total" suffix
windows_memory_pool_nonpaged_allocs_total non-counter metrics should not have "_total" suffix
windows_memory_pool_nonpaged_bytes_total non-counter metrics should not have "_total" suffix
windows_memory_pool_paged_allocs_total non-counter metrics should not have "_total" suffix
windows_memory_swap_page_operations_total non-counter metrics should not have "_total" suffix
windows_memory_swap_page_reads_total non-counter metrics should not have "_total" suffix
windows_memory_swap_page_writes_total non-counter metrics should not have "_total" suffix
windows_memory_swap_pages_read_total non-counter metrics should not have "_total" suffix
windows_memory_swap_pages_written_total non-counter metrics should not have "_total" suffix
windows_memory_transition_faults_total non-counter metrics should not have "_total" suffix
windows_memory_transition_pages_repurposed_total non-counter metrics should not have "_total" suffix
windows_memory_write_copies_total non-counter metrics should not have "_total" suffix
```

Only `windows_memory_pool_nonpaged_bytes` is a gauge, all the other
metrics were counters.

Also added some missing documentation.

Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2022-01-07 16:59:29 +01:00
Ben Reedy
a56ec9166b Merge pull request #912 from breed808/installer_port
Port should default to 9182 if not defined
2022-01-06 18:18:19 +10:00
Calle Pettersson
e03432a22d Merge pull request #901 from mjtrangoni/fix-some-promtool-warnings
Fix some promtool warnings
2022-01-06 09:12:55 +01:00
Ben Reedy
be004b8423 Port should default to 9182 if not defined
Resolves #911 which was introduced by 45e9357a.

This is due to the exporter only using the default port if no LISTEN_ADDR
**and** no LISTEN_PORT is defined.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-01-06 07:57:31 +10:00
Ben Reedy
e08a0411d6 Merge pull request #908 from akrauza/ADCS
Update repository readme with ADCS documentation link
2022-01-05 07:33:25 +10:00
Austin D. Krauza
3d7894049f Update repository readme with ADCS documentation link
Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>
2022-01-04 10:51:49 -05:00
Ben Reedy
de664d4b93 Merge pull request #905 from mjtrangoni/fix-counter-promtool-warnings
Fix counter metrics should have "_total" suffix issue
2022-01-03 08:06:01 +10:00
Ben Reedy
78e026b6ee Merge pull request #906 from mjtrangoni/fix-badge-gh-actions
README.md: Replace the AppVeyor badge with the GH Actions one
2022-01-03 08:04:26 +10:00
Ben Reedy
9eba8dd024 Merge pull request #896 from mjtrangoni/add-codespell
codespell: add GH Action for checking spelling issues
2022-01-03 08:03:05 +10:00
Mario Trangoni
01100d3e6e README.md: Replace the AppVeyor badge with the GH Actions one
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2022-01-02 18:59:32 +01:00
Mario Trangoni
0f1eb4a936 Fix counter metrics should have "_total" suffix issue
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2022-01-02 18:47:17 +01:00
Mario Trangoni
a8eefae123 codespell: add GH Action for checking spelling issues
After fixing all spelling issues in #892, this will prevent us for
adding new ones.

Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2022-01-02 18:21:43 +01:00
Ben Reedy
746158d354 Merge pull request #895 from akrauza/ADCS
Add Collector for Active Directory Certificate Services (ADCS)
2022-01-02 19:43:47 +10:00
Ben Reedy
d9f4264fc4 Merge pull request #898 from breed808/github_actions
Migrate CI/CD to Github Actions
2022-01-02 19:15:40 +10:00
Austin D. Krauza
a89b53779d Initial commit for ADCS collector
Signed-off-by: Austin D. Krauza <krauza.austin@gmail.com>
2022-01-02 01:24:11 -05:00
Ben Reedy
27ceeecff3 Merge pull request #902 from breed808/textfile
Move textfile mtime metric from loop
2022-01-02 08:32:08 +10:00
Ben Reedy
1ba5835af6 Move textfile mtime metric from loop
Loop was erroneously creating duplicate `windows_textfile_mtime_seconds`
metrics, causing the exporter to return a HTTP 500 error and no metrics
from any collector.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-01-01 11:48:19 +10:00
Ben Reedy
0db956aa4d Migrate CI/CD to Github Actions
Signed-off-by: Ben Reedy <breed808@breed808.com>
2022-01-01 10:04:33 +10:00
Mario Trangoni
9d1628a329 promtool: Fix windows_time_ntp_client_time_source_count
Related to #659, this is a breaking change!

Fixes
```
windows_time_ntp_client_time_source_count non-histogram and non-summary metrics should not have "_count" suffix
```
for the time collector.

Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2021-12-31 13:51:07 +01:00
Mario Trangoni
fc33fa320b promtool: Fix *_handle_count and *_thread_count
Related to #659, this is a breaking change!

Fixes

```
windows_process_handle_count non-histogram and non-summary metrics should not have "_count" suffix
windows_process_thread_count non-histogram and non-summary metrics should not have "_count" suffix
```

for process and terminal_services collectors.

Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2021-12-31 13:51:07 +01:00
Ben Reedy
b6f88cbbdd Use pwsh to run e2e-test target
Powershell >= 5 is required for the `New-Guid` command in the e2e script.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-12-30 20:49:46 +10:00
Calle Pettersson
4b9b9e97cb Merge pull request #893 from prometheus-community/new-appveyor-token
Update CI token
2021-12-28 22:00:26 +01:00
Calle Pettersson
3ebe0e937e Update CI token
Signed-off-by: Calle Pettersson <calle@cape.nu>
2021-12-28 21:44:22 +01:00
Ben Reedy
4d771d2bce Merge pull request #892 from mjtrangoni/fix-golanci-lint
Fix and update golanci-lint reported issues
2021-12-25 10:34:02 +10:00
Mario Trangoni
919f90a571 golangci-lint: Acknowledge all remaining checks and update golanci-lint to v1.43.0
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2021-12-24 11:19:05 +01:00
Ben Reedy
c7d07a37ea Merge pull request #883 from breed808/msi_listen_port
Remove explicit LISTEN_PORT from MSI installer
2021-12-19 08:30:21 +10:00
Ben Reedy
87c21bfa50 Merge pull request #891 from breed808/update_perflib
Update Perflib dependency
2021-12-19 08:27:14 +10:00
Mario Trangoni
df4f6b206b revive: make type exportable and remove unnecessary log word
See,
```
log/gokit_adapter.go:9:26: unexported-return: exported func NewToolkitAdapter returns unexported type *log.logAdapter, which can be annoying to use (revive)
func NewToolkitAdapter() *logAdapter {
                         ^
```

Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2021-12-18 19:54:31 +01:00
Mario Trangoni
9e3c585a28 revive: Remove unnecessary = 0 from var declaration.
See,
```
$ GOOS=windows GOARCH=amd64 golangci-lint run  ./... 2>1 | grep var-declaration
collector/os.go:205:22: var-declaration: should drop = 0 from declaration of var fsipf; it is the zero value (revive)
collector/os.go:226:23: var-declaration: should drop = 0 from declaration of var pfbRaw; it is the zero value (revive)
```

Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2021-12-18 19:30:47 +01:00
Mario Trangoni
e4a43c539b codespell: Fix word spelling issues
See,
```
$ codespell --skip=".git,./vendor" --ignore-words-list=calle
./exporter.go:262: overriden ==> overridden
./collector/dfsr.go:132: receieved ==> received
./collector/dns.go:140: reponses ==> responses
./collector/exchange.go:238: occational ==> occasional
./collector/mssql.go:1961: shoud ==> should
./collector/process.go:137: sharable ==> shareable
./collector/remote_fx.go:64: seccond ==> second
./docs/collector.dfsr.md:47: fils ==> fills, files, file
./docs/collector.exchange.md:39: lengt ==> length
./docs/collector.fsrmquota.md:3: Ressource ==> Resource
./docs/collector.fsrmquota.md:51: Ressource ==> Resource
./docs/collector.os.md:20: sotred ==> sorted, stored
./docs/collector.process.md:56: sharable ==> shareable
./docs/collector.smtp.md:27: mailformed ==> malformed
```

Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2021-12-18 19:19:06 +01:00
Mario Trangoni
03e15a0f80 unconvert: Remove unnecessary conversion
See,
```
collector/os.go:306:10: unnecessary conversion (unconvert)
		float64(fsipf),
		       ^
```

Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2021-12-18 19:05:31 +01:00
Mario Trangoni
b98a956d51 gofmt: Fix File is not gofmt-ed with -s for go1.17
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2021-12-18 19:01:29 +01:00
Calle Pettersson
524bfde5a3 Merge pull request #887 from SouenMazouin/fix/request-error-total-iis
fix: add missing metrics for IIS version >= 8
2021-12-18 15:28:17 +01:00
Ben Reedy
963cee0a13 Update Perflib dependency
Dependabot has likely passed over this as there has been no tagged
release.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-12-18 19:31:08 +10:00
Ben Reedy
45e9357ad9 Remove explicit LISTEN_PORT from MSI installer
Explicit setting of listening port in the service definition causes port
setting in configuration file to be ignored.

Exporter already defines a default port (9812) if one is not specified,
so no impact from this change is anticipated.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-12-18 18:34:47 +10:00
Souen Mazouin
6120ea9be1 fix: add missing metrics for IIS version >= 8
Allows the following metrics to be exposed again, they had disappeared after the migration to perflib :
- worker_request_errors_total
- worker_current_websocket_requests
- worker_websocket_connection_accepted_total
- worker_websocket_connection_rejected_total

Signed-off-by: Souen Mazouin <souen.mazouin@cdiscount.com>
2021-12-14 17:44:08 +01:00
Ben Reedy
376060b053 Merge pull request #884 from prometheus-community/dependabot/go_modules/github.com/prometheus/exporter-toolkit-0.7.1
Bump github.com/prometheus/exporter-toolkit from 0.7.0 to 0.7.1
2021-12-14 10:45:31 +10:00
dependabot[bot]
e04c4aab29 Bump github.com/prometheus/exporter-toolkit from 0.7.0 to 0.7.1
Bumps [github.com/prometheus/exporter-toolkit](https://github.com/prometheus/exporter-toolkit) from 0.7.0 to 0.7.1.
- [Release notes](https://github.com/prometheus/exporter-toolkit/releases)
- [Changelog](https://github.com/prometheus/exporter-toolkit/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prometheus/exporter-toolkit/compare/v0.7.0...v0.7.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/exporter-toolkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-06 11:35:00 +00:00
Ben Reedy
479e6b1381 Merge pull request #882 from geraudster/fix/textfile_default_path
Fix default path for textfile collector
2021-12-02 13:13:13 +10:00
Géraud Duge de bernonville
f6f7dc96e9 Get EXE directory
Signed-off-by: Géraud Duge de bernonville <geraud.dugedebernonville@ext.cdiscount.com>
2021-12-01 10:41:46 +01:00
Ben Reedy
f84f54afda Merge pull request #875 from prometheus-community/dependabot/go_modules/github.com/Microsoft/hcsshim-0.9.1
Bump github.com/Microsoft/hcsshim from 0.8.6 to 0.9.1
2021-11-15 08:27:59 +10:00
dependabot[bot]
e22ef6e3cc Bump github.com/Microsoft/hcsshim from 0.8.6 to 0.9.1
Bumps [github.com/Microsoft/hcsshim](https://github.com/Microsoft/hcsshim) from 0.8.6 to 0.9.1.
- [Release notes](https://github.com/Microsoft/hcsshim/releases)
- [Commits](https://github.com/Microsoft/hcsshim/compare/v0.8.6...v0.9.1)

---
updated-dependencies:
- dependency-name: github.com/Microsoft/hcsshim
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-14 21:57:35 +00:00
Ben Reedy
02b69afe8b Merge pull request #874 from prometheus-community/dependabot/go_modules/github.com/sirupsen/logrus-1.8.1
Bump github.com/sirupsen/logrus from 1.6.0 to 1.8.1
2021-11-15 07:42:52 +10:00
dependabot[bot]
b7a0a09e58 Bump github.com/sirupsen/logrus from 1.6.0 to 1.8.1
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.6.0 to 1.8.1.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.6.0...v1.8.1)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-14 21:29:14 +00:00
Ben Reedy
6105792f29 Merge pull request #876 from prometheus-community/dependabot/go_modules/github.com/dimchansky/utfbom-1.1.1
Bump github.com/dimchansky/utfbom from 1.1.0 to 1.1.1
2021-11-15 07:23:25 +10:00
Ben Reedy
1fbc626ee2 Merge pull request #873 from prometheus-community/dependabot/go_modules/github.com/prometheus/common-0.32.1
Bump github.com/prometheus/common from 0.32.0 to 0.32.1
2021-11-15 07:21:13 +10:00
dependabot[bot]
ca07abc1cd Bump github.com/dimchansky/utfbom from 1.1.0 to 1.1.1
Bumps [github.com/dimchansky/utfbom](https://github.com/dimchansky/utfbom) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/dimchansky/utfbom/releases)
- [Commits](https://github.com/dimchansky/utfbom/compare/v1.1.0...v1.1.1)

---
updated-dependencies:
- dependency-name: github.com/dimchansky/utfbom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-14 11:50:42 +00:00
dependabot[bot]
60583c3366 Bump github.com/prometheus/common from 0.32.0 to 0.32.1
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.32.0 to 0.32.1.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.32.0...v0.32.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-14 11:42:09 +00:00
Ben Reedy
a7dcf5896c Merge pull request #871 from breed808/dependabot
Add Dependabot dependency tracking
2021-11-14 21:38:36 +10:00
Ben Reedy
438cb87fc7 Add Dependabot dependency tracking
Bot will submit PRs when new dependency versions are detected,
preventing dependencies from becoming out-of-date.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-11-14 21:34:26 +10:00
Ben Reedy
f8b6260ab5 Merge pull request #862 from breed808/dependencies
Update dependencies
2021-11-14 11:11:43 +10:00
Calle Pettersson
d2b3f0f94b Merge pull request #869 from rnjstjdgh/master
Update collector.net.md
2021-11-11 09:14:54 +01:00
rnjstjdgh
d6b4466bc3 Update collector.net.md
Signed-off-by: rnjstjdgh <gshgsh0831@gmail.com>
2021-11-11 14:52:32 +09:00
Calle Pettersson
ce3d517cb3 Merge pull request #863 from jsturtevant/fix-service-identification
use IsWindowsService to detect if running as service
2021-11-05 18:47:18 +01:00
James Sturtevant
a6ea021468 use IsWindowsService to detect if running as service
Signed-off-by: James Sturtevant <jstur@microsoft.com>
2021-11-05 10:15:39 -07:00
Ben Reedy
b58dfdf4f3 Update perflib_exporter dependency
Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-11-05 18:30:03 +10:00
Ben Reedy
676eb55f99 Update Prometheus dependencies
Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-11-05 18:30:01 +10:00
Ben Reedy
121d9980c1 Replace go-kit/kit with go-kit/log
External log package has been extracted to a separate external
repository and module.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-11-05 18:29:59 +10:00
Calle Pettersson
947d8473e0 Merge pull request #861 from prometheus-community/maintainers-contacts
Update MAINTAINERS with security contacts
2021-10-29 10:36:43 +02:00
Calle Pettersson
c1569686f7 Update MAINTAINERS with security contacts
Signed-off-by: Calle Pettersson <calle@cape.nu>
2021-10-27 20:46:46 +02:00
Ben Reedy
75966fd37c Merge pull request #848 from ArtamonovEvgenii/master
Set relative default path for textfile collector
2021-10-23 14:27:00 +10:00
eartamonov
d0cfc14af9 Set relative default path for textfile collector
Signed-off-by: Artamonov Evgenii <evgenyi.artamonov@gmail.com>
2021-10-19 14:23:11 +03:00
Ben Reedy
941b66d342 Merge pull request #846 from JDA88/patch-1
Document expected delays in the size metrics
2021-10-01 08:13:58 +10:00
Ben Reedy
388195be97 Update e2e output to match help text changes
Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-10-01 08:09:03 +10:00
JDA88
bbefd8ac97 Document expected delays in the size metrics
Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-10-01 07:58:04 +10:00
Ben Reedy
5b92e1bd3d Merge pull request #841 from breed808/thermal_empty
Thermalzone: return error on empty result
2021-10-01 05:45:09 +10:00
Dave Owen
82f17fd607 Collect IIS metrics using Perflib (#832)
Rewrite IIS collector to use Perflib

Signed-off-by: David Owen <dowen@meddbase.com>
2021-09-25 17:00:39 +02:00
Ben Reedy
3e37b7b6f0 Merge pull request #840 from newrelic-forks/fix_service_memory_leak
Service Api collection close servicehandler to avoid memory leak
2021-09-25 18:22:21 +10:00
Ben Reedy
5d29ff6497 Thermalzone: return error on empty result
Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-09-25 15:35:45 +10:00
Alvaro Cabanas
f4f5aaf146 Service Api collection close servicehandler to avoid memory leak
Signed-off-by: Alvaro Cabanas <acabanas@newrelic.com>
2021-09-23 17:45:31 +02:00
Ben Reedy
5931604b58 Merge pull request #812 from carlossscastro/master
Services collection using API (no WMI)
2021-08-26 08:26:07 +10:00
Carlos Castro
67ca5e5ef2 Update service.go
Signed-off-by: Carlos Castro <ccastro@newrelic.com>
2021-08-25 17:19:41 +01:00
Carlos Castro
384183120f Update service.go
Signed-off-by: Carlos Castro <ccastro@newrelic.com>
2021-08-25 17:19:41 +01:00
Carlos Castro
a9ac2d4672 Collect services using windows api
Signed-off-by: Carlos Castro <ccastro@newrelic.com>
2021-08-25 17:19:41 +01:00
Benjamin Blattberg
1b96bb6d08 Add MSSQL Wait Statistics (#793)
Signed-off-by: benjaminjb <benjamin.blattberg@gmail.com>
2021-06-29 21:32:08 +02:00
Ben Reedy
cc45eeb90b Merge pull request #809 from breed808/process_working_set_private
Add missing Process Collector metrics
2021-06-25 08:36:43 +10:00
Ben Reedy
4b2cd0a024 Merge pull request #759 from breed808/textfile
Fix textfile crashes with duplicate metrics
2021-06-25 08:36:21 +10:00
Ben Reedy
ad447a6b08 Add unit suffix to process working_set metric
Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-06-19 09:02:30 +10:00
Ben Reedy
e4d7604193 Move process metric documentation to markdown file
Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-06-19 09:02:28 +10:00
Ben Reedy
757f88be04 Add missing process counters
Working Set Private and Working Set Peak were being collected, but not
exposed by the exporter.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-06-19 09:02:26 +10:00
Calle Pettersson
cff484b5e1 Merge pull request #804 from max-len/bandwidth-bytes
Export CurrentBandwidth as bytes
2021-06-16 20:16:45 +02:00
Calle Pettersson
2dc568b5cd Merge pull request #805 from max-len/typo
Fix typo: process_memory_limit_bytes
2021-06-16 20:14:55 +02:00
Calle Pettersson
448f505729 Merge pull request #807 from max-len/doc-cpu
Fix doc: collector.cpu.md
2021-06-16 20:12:59 +02:00
Max Lendrich
6d1ba11a8e Fix doc: collector.cpu.md
Signed-off-by: Max Lendrich <maximilian.lendrich@sap.com>
2021-06-16 15:18:29 +02:00
Max Lendrich
0f5a232142 Fix typo
Signed-off-by: Max Lendrich <maximilian.lendrich@sap.com>
2021-06-15 12:38:23 +02:00
Max Lendrich
bbab591570 Export CurrentBandwidth as bytes
From https://prometheus.io/docs/practices/naming/:
To avoid confusion combining different metrics, always use bytes, even
where bits appear more common.

Fixes #800

Signed-off-by: Max Lendrich <maximilian.lendrich@sap.com>
2021-06-14 17:33:27 +02:00
Ben Reedy
2bc3c1859a Merge pull request #802 from breed808/log_dependency
Replace deprecated log lib in remaining collectors
2021-06-12 19:52:29 +10:00
Ben Reedy
7c61a4dc25 Run "go mod tidy" on project
Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-06-12 11:57:46 +10:00
Ben Reedy
5a57da53be Replace deprecated log lib in remaining collectors
Some collectors were missed when migrating to the local
github.com/prometheus-community/windows_exporter/log library.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-06-12 11:57:40 +10:00
Calle Pettersson
72c46664db Merge pull request #789 from Wittionary/issue-776
Fixes #776
2021-05-25 07:35:49 +02:00
Witt Allen
8689c41c68 Added a 'data source' field to specify hcsshim of Host Compute Services in Hyper-V is used
Signed-off-by: Witt Allen <qwert59@gmail.com>
2021-05-24 00:57:20 -05:00
Calle Pettersson
74eac8f29b Merge pull request #788 from benridley/bugfix_sysinfo_layout
Correct layout of SystemInfo structs
2021-05-21 09:41:34 +02:00
Ben Ridley
bb48f1caac Correct layout of SystemInfo structs to prevent incorrect fields being read
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-05-20 16:30:52 -07:00
Ben Reedy
068d03bd01 Merge pull request #783 from breed808/msmq_remove_hardcoded_queue
Remove hard-coded "Computer Queues" filter
2021-05-17 16:58:50 +10:00
Ben Reedy
5072879dca Check duplicates across entire textfile set
Check all textfile metrics will be checked for duplicates. If duplicates
are detected, drop all metrics and log error.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-05-17 16:54:28 +10:00
Ben Reedy
0fb7eec670 Remove hard-coded "Computer Queues" filter
msmq collector would only collect from a hard-coded "Computer Queues"
queue.
Removal of filter allows other queues to be queried with
the collector.msmq.msmq-where flag.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-05-16 14:53:54 +10:00
Ben Reedy
4293497b29 Fix textfile crashes with duplicate metrics
Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-05-12 20:57:17 +10:00
Ben Reedy
95f10f19cb Merge pull request #778 from Wittionary/fix-issue-777
Fixes #777
2021-05-03 14:23:03 +10:00
Witt
288f2a60e7 Changed 'Yes' to 'No' to reflect current state of collectors enabled by default
Signed-off-by: Witt Allen <qwert59@gmail.com>
2021-05-02 19:40:33 -05:00
Ben Reedy
2e32b0e2b1 Merge pull request #767 from louij2/patch-1
Update collector.service.md
2021-05-01 13:14:26 +10:00
Calle Pettersson
09759a4e8c Merge pull request #698 from ramonsmits/patch-1
Example - Using [defaults] with `--collectors.enabled` argument
2021-04-25 19:53:42 +02:00
louij2
dfd42a6c0c Update collector.service.md
Added more details for monitoring multiple services.

Signed-off-by: Luca Chana <clubdog123@gmail.com>
2021-04-24 21:05:36 +01:00
Ramon Smits
576c3bf918 Example - Using [defaults] with --collectors.enabled argument
Signed-off-by: Ramon Smits <ramon.smits@gmail.com>
2021-04-23 18:52:52 +02:00
Ben Reedy
19fee044bf Merge pull request #765 from breed808/checksums
CI: Output artifacts in single, flat directory.
2021-04-20 19:00:35 +10:00
Ben Reedy
45a74fdb7f CI: Output artifacts in single, flat directory.
Nested directories caused issues with promu checksum output, causing
user checks of the sha265sums.txt file to fail as the filenames did not
match.

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-04-19 19:38:17 +10:00
Ben Reedy
db00553ca6 Merge pull request #744 from breed808/tests
Add benchmark for each collector
2021-04-01 22:35:08 +10:00
Ben Reedy
a2c4bf6a2d Add benchmark for each collector
Benchmarks will allow for easier identification of slow collectors.
Additionally, they increase test coverage of the collectors, with some
collectors now reaching 80-95% coverage with this change.

Collector benchmarks have been structed so that common functionality is
present in `collector/collector_test.go` as is done with non-test
functionality in `collector/collector.go`.
Test logic that is specific to individual collectors is present in the
collector test file (E.G. `collector/process_test.go` for the Process
collector).

Signed-off-by: Ben Reedy <breed808@breed808.com>
2021-04-01 22:28:54 +10:00
Calle Pettersson
7adcac8f39 Merge pull request #702 from benridley/dev_cs_collector
Replace WMI in cs and os collectors
2021-03-30 21:26:23 +02:00
Ben Ridley
863b7d8ab4 Merge branch 'dev_cs_collector' of https://github.com/benridley/windows_exporter into dev_cs_collector 2021-03-29 10:14:26 -07:00
Ben Ridley
33c6b2c6a5 Address GitHub feedback
- Defer registry close calls
- Ensure size parameter in GetComputerName is properly specified
- Clean up some comments to ensure correctness

Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-29 10:13:36 -07:00
Calle Pettersson
6dee2422e1 Merge pull request #753 from prometheus-community/fix-ci
Update CI to install tools with go install rather than go get
2021-03-28 10:41:25 +02:00
Calle Pettersson
5d224b43ca Update CI to install tools with go install rather than go get
Signed-off-by: Calle Pettersson <calle@cape.nu>
2021-03-27 15:30:50 +01:00
Calle Pettersson
3f2a143104 Merge pull request #748 from majerus1223/remote_interactive
Fix typo on remote_interactive
2021-03-19 11:34:25 +01:00
Ben Ridley
ee3848141c Simplify struct usage and comments
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
Ben Ridley
df2a7a9ec0 Remove temporary uintptr values, as the garbage collector can move addresses from under them.
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
Ben Ridley
05f0f6f688 Add idiomatic wrappers to be exposed publically, and hide low-level
WinAPI operations

Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
Ben Ridley
d947d0f6db Refactor remaining sysinfoapi calls into header package
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
Ben Ridley
d063bc0842 Add correct scrape context to OS benchmark
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
retryW
dd473c4807 Fixed paging free bytes
moved

Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
retryW
7bd58abd27 Converted PagingFreeBytes to use perflib
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
retryW
6f941044c7 Change Sprintf interpolation to use explicit types
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
retryW
3da11645cf added os_test.go and removed wmi for testing
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
retryW
048bff919e Converted most metrics to non-wmi
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
retryW
f76334213d Convert os time and timezone from WMI to native go
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
Ben Ridley
71054ac429 Replace the CS collector with native WinAPI calls to sysinfoapi
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-18 16:18:47 -07:00
Ben Ridley
248b7214e3 Move netapi free back to a defer statement
Signed-off-by: Ben Ridley <benridley29@gmail.com>
2021-03-19 10:13:04 +11:00
majerus
094558b1f1 Fix typo
Signed-off-by: majerus <james_majerus@msn.com>
2021-03-16 09:12:56 -05:00
Ben Reedy
18495abb69 Merge pull request #736 from basroovers/master
Typo in tcp doc
2021-03-07 11:04:18 +10:00
Bas Roovers
cc709ac380 Update collector.tcp.md
Changed windows_tcp_connections_established to gauge in tcp doc

Signed-off-by: Bas Roovers <basroovers@icloud.com>
2021-02-24 14:39:07 +01:00
179 changed files with 14541 additions and 3282 deletions

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"

105
.github/workflows/lint.yml vendored Normal file
View File

@@ -0,0 +1,105 @@
name: Linting
# Trigger on pull requests and pushes to master branch where Go-related files
# have been changed.
on:
push:
paths:
- "go.mod"
- "go.sum"
- "**.go"
- ".github/workflows/lint.yml"
- "tools/e2e-output.txt"
branches:
- master
pull_request:
paths:
- "go.mod"
- "go.sum"
- "**.go"
- ".github/workflows/lint.yml"
- "tools/e2e-output.txt"
branches:
- master
env:
PROMU_VER: '0.14.0'
PROMTOOL_VER: '2.43.0'
jobs:
test:
runs-on: windows-2019
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '^1.20.2'
- name: Test
run: make test
- name: Install e2e deps
run: |
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:PROMU_VER)/promu-$($Env:PROMU_VER).windows-amd64.zip -OutFile promu-$($Env:PROMU_VER).windows-amd64.zip
Expand-Archive -Path promu-$($Env:PROMU_VER).windows-amd64.zip -DestinationPath .
Copy-Item -Path promu-$($Env:PROMU_VER).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.2.0
# GOPATH\bin dir must be appended to PATH else the `promu` command won't be found
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: e2e Test
run: make e2e-test
promtool:
runs-on: windows-2019
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '^1.20.2'
- name: Install promtool
run: |
Invoke-WebRequest -Uri https://github.com/prometheus/prometheus/releases/download/v$($Env:PROMTOOL_VER)/prometheus-$($Env:PROMTOOL_VER).windows-amd64.zip -OutFile prometheus-$($Env:PROMTOOL_VER).windows-amd64.zip
Expand-Archive -Path prometheus-$($Env:PROMTOOL_VER).windows-amd64.zip -DestinationPath .
Copy-Item -Path prometheus-$($Env:PROMTOOL_VER).windows-amd64\promtool.exe -Destination "$(go env GOPATH)\bin"
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:PROMU_VER)/promu-$($Env:PROMU_VER).windows-amd64.zip -OutFile promu-$($Env:PROMU_VER).windows-amd64.zip
Expand-Archive -Path promu-$($Env:PROMU_VER).windows-amd64.zip -DestinationPath .
Copy-Item -Path promu-$($Env:PROMU_VER).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
# No binaries available so build from source
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.2.0
# GOPATH\bin dir must be appended to PATH else the `promu` command won't be found
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Promtool
run: make promtool
lint:
runs-on: windows-2022
steps:
# `gofmt` linter run by golangci-lint fails on CRLF line endings (the default for Windows)
- name: Set git to use LF
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '^1.20.2'
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.51.2
args: "--timeout=5m"
# golangci-lint action doesn't always provide helpful output, so re-run without the action for
# better output of the problem.
# The cache from the golangci-lint step is re-used here, so this step should finish quickly.
- name: errors
if: ${{ failure() }}
run: golangci-lint run --timeout=5m -c .golangci.yaml

106
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,106 @@
name: Releases
# Trigger on releases.
on:
release:
types:
- published
- edited
permissions:
contents: write
packages: write
env:
PROMU_VER: '0.14.0'
jobs:
build:
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
with:
# fetch-depth required for gitversion in `Build` step
fetch-depth: 0
- uses: actions/setup-go@v3
with:
go-version: '^1.20.2'
- name: Install Build deps
run: |
dotnet tool install --global GitVersion.Tool --version 5.*
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:PROMU_VER)/promu-$($Env:PROMU_VER).windows-amd64.zip -OutFile promu-$($Env:PROMU_VER).windows-amd64.zip
Expand-Archive -Path promu-$($Env:PROMU_VER).windows-amd64.zip -DestinationPath .
Copy-Item -Path promu-$($Env:PROMU_VER).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
# No binaries available so build from source
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.0
# GOPATH\bin dir must be added to PATH else the `promu` and `goversioninfo` commands won't be found
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Build
run: |
$ErrorActionPreference = "Stop"
dotnet-gitversion /output json /showvariable FullSemVer | Set-Content VERSION -PassThru
$Version = Get-Content VERSION
# Windows versioninfo resources need the file version by parts (but product version is free text)
$VersionParts = ($Version -replace '^v?([0-9\.]+).*$','$1').Split(".")
goversioninfo.exe -ver-major $VersionParts[0] -ver-minor $VersionParts[1] -ver-patch $VersionParts[2] -product-version $Version -platform-specific
make crossbuild
# '+' symbols are invalid characters in image tags
(Get-Content -Path VERSION) -replace '\+', '_' | Set-Content -Path VERSION
make build-all
# GH requires all files to have different names, so add version/arch to differentiate
foreach($Arch in "amd64", "arm64","386") {
Move-Item output\$Arch\windows_exporter.exe output\windows_exporter-$Version-$Arch.exe
}
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: windows_exporter_binaries
path: output\windows_exporter-*.exe
- name: Build Release Artifacts
if: startsWith(github.ref, 'refs/tags/')
run: |
$ErrorActionPreference = "Stop"
$BuildVersion = Get-Content VERSION
$TagName = $env:GITHUB_REF -replace 'refs/tags/', ''
# The MSI version is not semver compliant, so just take the numerical parts
$MSIVersion = $TagName -replace '^v?([0-9\.]+).*$','$1'
foreach($Arch in "amd64", "386") {
Write-Verbose "Building windows_exporter $MSIVersion msi for $Arch"
.\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$BuildVersion-$Arch.exe -Version $MSIVersion -Arch "$Arch"
Move-Item installer\Output\windows_exporter-$MSIVersion-$Arch.msi output\
}
promu checksum output\
- name: Login to GitHub container registry
if: ${{ github.event_name != 'pull_request' }}
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push Latest image
if: ${{ github.event_name != 'pull_request' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$Env:VERSION = 'latest'
make push-all
- name: Release
if: startsWith(github.ref, 'refs/tags/')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$TagName = $env:GITHUB_REF -replace 'refs/tags/', ''
Get-ChildItem -Path output\* -Include @('windows_exporter*.msi', 'windows_exporter*.exe', 'sha256sums.txt') | Foreach-Object {gh release upload $TagName $_}
make push-all

26
.github/workflows/spelling.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Spell checking
# Trigger on pull requests, and pushes to master branch.
on:
push:
branches:
- master
pull_request:
branches:
- master
env:
PROMU_VER: 'v0.14.0'
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: codespell-project/actions-codespell@master
with:
check_filenames: true
# When using this Action in other repos, the --skip option below can be removed
skip: ./.git,go.mod,go.sum
ignore_words_list: calle

View File

@@ -3,11 +3,10 @@ linters:
enable:
- deadcode
- errcheck
- golint
- revive
- govet
- gofmt
- ineffassign
- interfacer
- structcheck
- unconvert
- varcheck
@@ -20,4 +19,7 @@ issues:
- # Golint has many capitalisation complaints on WMI class names
text: "`?\\w+`? should be `?\\w+`?"
linters:
- golint
- revive
- text: "don't use ALL_CAPS in Go names; use CamelCase"
linters:
- revive

View File

@@ -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

9
Dockerfile Normal file
View File

@@ -0,0 +1,9 @@
# Note this image doesn't really matter for hostprocess but it is good to build per OS version
# the files in the image are copied to $env:CONTAINER_SANDBOX_MOUNT_POINT on the host
# but the file system is the Host NOT the container
ARG BASE="mcr.microsoft.com/windows/nanoserver:1809"
FROM $BASE
ENV PATH="C:\Windows\system32;C:\Windows;"
COPY output/amd64/windows_exporter.exe /windows_exporter.exe
ENTRYPOINT ["windows_exporter.exe"]

View File

@@ -1,6 +1,9 @@
Contributors in alphabetical order
Maintainers in alphabetical order
* [Ben Reedy](https://github.com/breed808) - breed808@breed808.com
* [Calle Pettersson](https://github.com/carlpett) - calle@cape.nu
Alumni
* [Ben Reedy](https://github.com/breed808)
* [Brian Brazil](https://github.com/brian-brazil)
* [Martin Lindhe](https://github.com/martinlindhe)
* [Calle Pettersson](https://github.com/carlpett)

View File

@@ -1,4 +1,15 @@
export GOOS=windows
export DOCKER_IMAGE_NAME ?= windows-exporter
export DOCKER_REPO ?= ghcr.io/prometheus-community
VERSION?=$(shell cat VERSION)
DOCKER?=docker
# Image Variables for Hostprocess Container
# Windows image build is heavily influenced by https://github.com/kubernetes/kubernetes/blob/master/cluster/images/etcd/Makefile
OS=1809
ALL_OS:= 1809 ltsc2022
BASE_IMAGE=mcr.microsoft.com/windows/nanoserver
.PHONY: build
build: windows_exporter.exe
@@ -8,12 +19,19 @@ windows_exporter.exe: **/*.go
test:
go test -v ./...
bench:
go test -v -bench='benchmark(cpu|logicaldisk|logon|memory|net|process|service|system|tcp|time)collector' ./...
lint:
golangci-lint -c .golangci.yaml run
.PHONY: e2e-test
e2e-test: windows_exporter.exe
powershell -NonInteractive -ExecutionPolicy Bypass -File .\tools\end-to-end-test.ps1
pwsh -NonInteractive -ExecutionPolicy Bypass -File .\tools\end-to-end-test.ps1
.PHONY: promtool
promtool: windows_exporter.exe
pwsh -NonInteractive -ExecutionPolicy Bypass -File .\tools\promtool.ps1
fmt:
gofmt -l -w -s .
@@ -22,4 +40,25 @@ crossbuild:
# The prometheus/golang-builder image for promu crossbuild doesn't exist
# on Windows, so for now, we'll just build twice
GOARCH=amd64 promu build --prefix=output/amd64
GOARCH=arm64 promu build --prefix=output/arm64
GOARCH=386 promu build --prefix=output/386
build-image: crossbuild
$(DOCKER) build --build-arg=BASE=$(BASE_IMAGE):$(OS) -f Dockerfile -t $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)-$(OS) .
sub-build-%:
$(MAKE) OS=$* build-image
build-all: $(addprefix sub-build-,$(ALL_OS))
push:
set -x; \
for osversion in ${ALL_OS}; do \
$(DOCKER) push $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
$(DOCKER) manifest create --amend $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION) $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
full_version=`$(DOCKER) manifest inspect $(BASE_IMAGE):$${osversion} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'` || true; \
$(DOCKER) manifest annotate --os windows --arch amd64 --os-version $${full_version} $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION) $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
done
$(DOCKER) manifest push --purge $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)
push-all: build-all push

View File

@@ -1,6 +1,6 @@
# windows_exporter
[![Build status](https://ci.appveyor.com/api/projects/status/xoym3fftr7giasiw/branch/master?svg=true)](https://ci.appveyor.com/project/prometheus-community/windows-exporter)
![Build Status](https://github.com/prometheus-community/windows_exporter/workflows/windows_exporter%20CI/CD/badge.svg)
A Prometheus exporter for Windows machines.
@@ -10,6 +10,7 @@ A Prometheus exporter for Windows machines.
Name | Description | Enabled by default
---------|-------------|--------------------
[ad](docs/collector.ad.md) | Active Directory Domain Services |
[adcs](docs/collector.adcs.md) | Active Directory Certificate Services |
[adfs](docs/collector.adfs.md) | Active Directory Federation Services |
[cache](docs/collector.cache.md) | Cache metrics |
[cpu](docs/collector.cpu.md) | CPU usage | &#10003;
@@ -26,6 +27,11 @@ Name | Description | Enabled by default
[logical_disk](docs/collector.logical_disk.md) | Logical disks, disk I/O | &#10003;
[logon](docs/collector.logon.md) | User logon sessions |
[memory](docs/collector.memory.md) | Memory usage metrics |
[mscluster_cluster](docs/collector.mscluster_cluster.md) | MSCluster cluster metrics |
[mscluster_network](docs/collector.mscluster_network.md) | MSCluster network metrics |
[mscluster_node](docs/collector.mscluster_node.md) | MSCluster Node metrics |
[mscluster_resource](docs/collector.mscluster_resource.md) | MSCluster Resource metrics |
[mscluster_resourcegroup](docs/collector.mscluster_resourcegroup.md) | MSCluster ResourceGroup metrics |
[msmq](docs/collector.msmq.md) | MSMQ queues |
[mssql](docs/collector.mssql.md) | [SQL Server Performance Objects](https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/use-sql-server-objects#SQLServerPOs) metrics |
[netframework_clrexceptions](docs/collector.netframework_clrexceptions.md) | .NET Framework CLR Exceptions |
@@ -40,14 +46,17 @@ Name | Description | Enabled by default
[os](docs/collector.os.md) | OS metrics (memory, processes, users) | &#10003;
[process](docs/collector.process.md) | Per-process metrics |
[remote_fx](docs/collector.remote_fx.md) | RemoteFX protocol (RDP) metrics |
[scheduled_task](docs/collector.scheduled_task.md) | Scheduled Tasks metrics |
[service](docs/collector.service.md) | Service state metrics | &#10003;
[smtp](docs/collector.smtp.md) | IIS SMTP Server |
[system](docs/collector.system.md) | System calls | &#10003;
[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 | &#10003;
[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.
@@ -73,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 for all the collectors enabled by default." | `[defaults]`
`--collectors.print` | If true, print available collectors and exit. |
`--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).
@@ -95,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:
@@ -114,6 +125,18 @@ 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
See detailed steps to install on Windows Kubernetes [here](./kubernetes/kubernetes.md).
## Supported versions
windows_exporter supports Windows Server versions 2008R2 and later, and desktop Windows version 7 and later.
@@ -136,13 +159,25 @@ 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.
### Using [defaults] with `--collectors.enabled` argument
Using `[defaults]` with `--collectors.enabled` argument which gets expanded with all default collectors.
.\windows_exporter.exe --collectors.enabled "[defaults],process,container"
This enables the additional process and container collectors on top of the defaults.
### 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:

View File

@@ -1,84 +0,0 @@
version: "{build}"
os: Visual Studio 2019
build: off
environment:
GOPATH: c:\gopath
GO111MODULE: on
clone_folder: c:\gopath\src\github.com\prometheus-community\windows_exporter
install:
- mkdir %GOPATH%\bin
- set PATH=%GOPATH%\bin;%PATH%
- set PATH=%PATH%;C:\msys64\mingw64\bin
- choco install gitversion.portable make -y
- ps: |
appveyor DownloadFile https://github.com/golangci/golangci-lint/releases/download/v1.21.0/golangci-lint-1.21.0-windows-amd64.zip
Expand-Archive golangci-lint-1.21.0-windows-amd64.zip
Move-Item golangci-lint-1.21.0-windows-amd64\golangci-lint-1.21.0-windows-amd64\golangci-lint.exe $env:GOPATH\bin\golangci-lint.exe
- ps: |
$env:GO111MODULE="off"
go get -u github.com/prometheus/promu
go get -u github.com/josephspurrier/goversioninfo/cmd/goversioninfo
$env:GO111MODULE="on"
test_script:
- make test
after_test:
- make lint
- make e2e-test
build_script:
- ps: |
# go mod download (or, if we don't call it, go build) will write every dependent package name to
# stderr, which will be interpreted as an error and abort the build if ErrorActionPreference is Stop,
# so we need to run it before setting the preference.
go mod download
$ErrorActionPreference = "Stop"
gitversion /output json /showvariable FullSemVer | Set-Content VERSION -PassThru
$Version = Get-Content VERSION
# Windows versioninfo resources need the file version by parts (but product version is free text)
$VersionParts = ($Version -replace '^v?([0-9\.]+).*$','$1').Split(".")
goversioninfo.exe -ver-major $VersionParts[0] -ver-minor $VersionParts[1] -ver-patch $VersionParts[2] -product-version $Version -platform-specific
make crossbuild
# GH requires all files to have different names, so add version/arch to differentiate
foreach($Arch in "amd64","386") {
Rename-Item output\$Arch\windows_exporter.exe -NewName windows_exporter-$Version-$Arch.exe
}
after_build:
- ps: |
# Build installer packages only on tagged releases
if($env:APPVEYOR_REPO_TAG -ne "True") {
return
}
$ErrorActionPreference = "Stop"
$BuildVersion = Get-Content VERSION
# The MSI version is not semver compliant, so just take the numerical parts
$MSIVersion = $env:APPVEYOR_REPO_TAG_NAME -replace '^v?([0-9\.]+).*$','$1'
foreach($Arch in "amd64","386") {
Write-Verbose "Building windows_exporter $MSIVersion msi for $Arch"
.\installer\build.ps1 -PathToExecutable .\output\$Arch\windows_exporter-$BuildVersion-$Arch.exe -Version $MSIVersion -Arch "$Arch"
Move-Item installer\Output\windows_exporter-$MSIVersion-$Arch.msi output\$Arch\
}
- promu checksum output\
artifacts:
- name: Artifacts
path: output\**\*
deploy:
- provider: GitHub
description: windows_exporter version $(appveyor_build_version)
artifact: Artifacts
auth_token:
secure: 'hFR7Ymxt/Rb25p4BweFvMNhX03lHD9kXJXrRlC/KbThazHuLD5NTx2ibMI6LYRsr'
draft: false
prerelease: false
on:
appveyor_repo_tag: true

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package collector
@@ -5,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
@@ -79,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"),
"",
@@ -456,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
@@ -616,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
}

9
collector/ad_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkADCollector(b *testing.B) {
benchmarkCollector(b, "ad", newADCollector)
}

244
collector/adcs.go Normal file
View File

@@ -0,0 +1,244 @@
//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"
)
type adcsCollector struct {
logger log.Logger
RequestsPerSecond *prometheus.Desc
RequestProcessingTime *prometheus.Desc
RetrievalsPerSecond *prometheus.Desc
RetrievalProcessingTime *prometheus.Desc
FailedRequestsPerSecond *prometheus.Desc
IssuedRequestsPerSecond *prometheus.Desc
PendingRequestsPerSecond *prometheus.Desc
RequestCryptographicSigningTime *prometheus.Desc
RequestPolicyModuleProcessingTime *prometheus.Desc
ChallengeResponsesPerSecond *prometheus.Desc
ChallengeResponseProcessingTime *prometheus.Desc
SignedCertificateTimestampListsPerSecond *prometheus.Desc
SignedCertificateTimestampListProcessingTime *prometheus.Desc
}
// ADCSCollectorMethod ...
func adcsCollectorMethod(logger log.Logger) (Collector, error) {
const subsystem = "adcs"
return &adcsCollector{
logger: log.With(logger, "collector", subsystem),
RequestsPerSecond: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "requests_total"),
"Total certificate requests processed",
[]string{"cert_template"},
nil,
),
RequestProcessingTime: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "request_processing_time_seconds"),
"Last time elapsed for certificate requests",
[]string{"cert_template"},
nil,
),
RetrievalsPerSecond: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "retrievals_total"),
"Total certificate retrieval requests processed",
[]string{"cert_template"},
nil,
),
RetrievalProcessingTime: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "retrievals_processing_time_seconds"),
"Last time elapsed for certificate retrieval request",
[]string{"cert_template"},
nil,
),
FailedRequestsPerSecond: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "failed_requests_total"),
"Total failed certificate requests processed",
[]string{"cert_template"},
nil,
),
IssuedRequestsPerSecond: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "issued_requests_total"),
"Total issued certificate requests processed",
[]string{"cert_template"},
nil,
),
PendingRequestsPerSecond: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "pending_requests_total"),
"Total pending certificate requests processed",
[]string{"cert_template"},
nil,
),
RequestCryptographicSigningTime: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "request_cryptographic_signing_time_seconds"),
"Last time elapsed for signing operation request",
[]string{"cert_template"},
nil,
),
RequestPolicyModuleProcessingTime: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "request_policy_module_processing_time_seconds"),
"Last time elapsed for policy module processing request",
[]string{"cert_template"},
nil,
),
ChallengeResponsesPerSecond: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "challenge_responses_total"),
"Total certificate challenge responses processed",
[]string{"cert_template"},
nil,
),
ChallengeResponseProcessingTime: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "challenge_response_processing_time_seconds"),
"Last time elapsed for challenge response",
[]string{"cert_template"},
nil,
),
SignedCertificateTimestampListsPerSecond: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "signed_certificate_timestamp_lists_total"),
"Total Signed Certificate Timestamp Lists processed",
[]string{"cert_template"},
nil,
),
SignedCertificateTimestampListProcessingTime: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "signed_certificate_timestamp_list_processing_time_seconds"),
"Last time elapsed for Signed Certificate Timestamp List",
[]string{"cert_template"},
nil,
),
}, nil
}
func (c *adcsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
if desc, err := c.collectADCSCounters(ctx, ch); err != nil {
_ = level.Error(c.logger).Log("msg", "failed collecting ADCS metrics", "desc", desc, "err", err)
return err
}
return nil
}
type perflibADCS struct {
Name string
RequestsPerSecond float64 `perflib:"Requests/sec"`
RequestProcessingTime float64 `perflib:"Request processing time (ms)"`
RetrievalsPerSecond float64 `perflib:"Retrievals/sec"`
RetrievalProcessingTime float64 `perflib:"Retrieval processing time (ms)"`
FailedRequestsPerSecond float64 `perflib:"Failed Requests/sec"`
IssuedRequestsPerSecond float64 `perflib:"Issued Requests/sec"`
PendingRequestsPerSecond float64 `perflib:"Pending Requests/sec"`
RequestCryptographicSigningTime float64 `perflib:"Request cryptographic signing time (ms)"`
RequestPolicyModuleProcessingTime float64 `perflib:"Request policy module processing time (ms)"`
ChallengeResponsesPerSecond float64 `perflib:"Challenge Responses/sec"`
ChallengeResponseProcessingTime float64 `perflib:"Challenge Response processing time (ms)"`
SignedCertificateTimestampListsPerSecond float64 `perflib:"Signed Certificate Timestamp Lists/sec"`
SignedCertificateTimestampListProcessingTime float64 `perflib:"Signed Certificate Timestamp List processing time (ms)"`
}
func (c *adcsCollector) collectADCSCounters(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
dst := make([]perflibADCS, 0)
if _, ok := ctx.perfObjects["Certification Authority"]; !ok {
return nil, errors.New("Perflib did not contain an entry for Certification Authority")
}
err := unmarshalObject(ctx.perfObjects["Certification Authority"], &dst, c.logger)
if err != nil {
return nil, err
}
if len(dst) == 0 {
return nil, errors.New("Perflib query for Certification Authority (ADCS) returned empty result set")
}
for _, d := range dst {
n := strings.ToLower(d.Name)
if n == "" {
continue
}
ch <- prometheus.MustNewConstMetric(
c.RequestsPerSecond,
prometheus.CounterValue,
d.RequestsPerSecond,
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RequestProcessingTime,
prometheus.GaugeValue,
milliSecToSec(d.RequestProcessingTime),
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RetrievalsPerSecond,
prometheus.CounterValue,
d.RetrievalsPerSecond,
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RetrievalProcessingTime,
prometheus.GaugeValue,
milliSecToSec(d.RetrievalProcessingTime),
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.FailedRequestsPerSecond,
prometheus.CounterValue,
d.FailedRequestsPerSecond,
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.IssuedRequestsPerSecond,
prometheus.CounterValue,
d.IssuedRequestsPerSecond,
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.PendingRequestsPerSecond,
prometheus.CounterValue,
d.PendingRequestsPerSecond,
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RequestCryptographicSigningTime,
prometheus.GaugeValue,
milliSecToSec(d.RequestCryptographicSigningTime),
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RequestPolicyModuleProcessingTime,
prometheus.GaugeValue,
milliSecToSec(d.RequestPolicyModuleProcessingTime),
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.ChallengeResponsesPerSecond,
prometheus.CounterValue,
d.ChallengeResponsesPerSecond,
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.ChallengeResponseProcessingTime,
prometheus.GaugeValue,
milliSecToSec(d.ChallengeResponseProcessingTime),
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.SignedCertificateTimestampListsPerSecond,
prometheus.CounterValue,
d.SignedCertificateTimestampListsPerSecond,
d.Name,
)
ch <- prometheus.MustNewConstMetric(
c.SignedCertificateTimestampListProcessingTime,
prometheus.GaugeValue,
milliSecToSec(d.SignedCertificateTimestampListProcessingTime),
d.Name,
)
}
return nil, nil
}

9
collector/adcs_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkADCSCollector(b *testing.B) {
benchmarkCollector(b, "adcs", adcsCollectorMethod)
}

View File

@@ -1,34 +1,70 @@
//go:build windows
// +build windows
package collector
import (
"math"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
)
func init() {
registerCollector("adfs", newADFSCollector, "AD FS")
}
type adfsCollector struct {
adLoginConnectionFailures *prometheus.Desc
certificateAuthentications *prometheus.Desc
deviceAuthentications *prometheus.Desc
extranetAccountLockouts *prometheus.Desc
federatedAuthentications *prometheus.Desc
passportAuthentications *prometheus.Desc
passiveRequests *prometheus.Desc
passwordChangeFailed *prometheus.Desc
passwordChangeSucceeded *prometheus.Desc
tokenRequests *prometheus.Desc
windowsIntegratedAuthentications *prometheus.Desc
logger log.Logger
adLoginConnectionFailures *prometheus.Desc
certificateAuthentications *prometheus.Desc
deviceAuthentications *prometheus.Desc
extranetAccountLockouts *prometheus.Desc
federatedAuthentications *prometheus.Desc
passportAuthentications *prometheus.Desc
passiveRequests *prometheus.Desc
passwordChangeFailed *prometheus.Desc
passwordChangeSucceeded *prometheus.Desc
tokenRequests *prometheus.Desc
windowsIntegratedAuthentications *prometheus.Desc
oAuthAuthZRequests *prometheus.Desc
oAuthClientAuthentications *prometheus.Desc
oAuthClientAuthenticationsFailures *prometheus.Desc
oAuthClientCredentialsRequestFailures *prometheus.Desc
oAuthClientCredentialsRequests *prometheus.Desc
oAuthClientPrivateKeyJwtAuthenticationFailures *prometheus.Desc
oAuthClientPrivateKeyJwtAuthentications *prometheus.Desc
oAuthClientSecretBasicAuthenticationFailures *prometheus.Desc
oAuthClientSecretBasicAuthentications *prometheus.Desc
oAuthClientSecretPostAuthenticationFailures *prometheus.Desc
oAuthClientSecretPostAuthentications *prometheus.Desc
oAuthClientWindowsIntegratedAuthenticationFailures *prometheus.Desc
oAuthClientWindowsIntegratedAuthentications *prometheus.Desc
oAuthLogonCertificateRequestFailures *prometheus.Desc
oAuthLogonCertificateTokenRequests *prometheus.Desc
oAuthPasswordGrantRequestFailures *prometheus.Desc
oAuthPasswordGrantRequests *prometheus.Desc
oAuthTokenRequests *prometheus.Desc
samlPTokenRequests *prometheus.Desc
ssoAuthenticationFailures *prometheus.Desc
ssoAuthentications *prometheus.Desc
wsfedTokenRequests *prometheus.Desc
wstrustTokenRequests *prometheus.Desc
upAuthenticationFailures *prometheus.Desc
upAuthentications *prometheus.Desc
externalAuthenticationFailures *prometheus.Desc
externalAuthentications *prometheus.Desc
artifactDBFailures *prometheus.Desc
avgArtifactDBQueryTime *prometheus.Desc
configDBFailures *prometheus.Desc
avgConfigDBQueryTime *prometheus.Desc
federationMetadataRequests *prometheus.Desc
}
// 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",
@@ -95,26 +131,250 @@ func newADFSCollector() (Collector, error) {
nil,
nil,
),
oAuthAuthZRequests: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_authorization_requests_total"),
"Total number of incoming requests to the OAuth Authorization endpoint",
nil,
nil,
),
oAuthClientAuthentications: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_authentication_success_total"),
"Total number of successful OAuth client Authentications",
nil,
nil,
),
oAuthClientAuthenticationsFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_authentication_failure_total"),
"Total number of failed OAuth client Authentications",
nil,
nil,
),
oAuthClientCredentialsRequestFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_credentials_failure_total"),
"Total number of failed OAuth Client Credentials Requests",
nil,
nil,
),
oAuthClientCredentialsRequests: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_credentials_success_total"),
"Total number of successful RP tokens issued for OAuth Client Credentials Requests",
nil,
nil,
),
oAuthClientPrivateKeyJwtAuthenticationFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_privkey_jwt_authentication_failure_total"),
"Total number of failed OAuth Client Private Key Jwt Authentications",
nil,
nil,
),
oAuthClientPrivateKeyJwtAuthentications: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_privkey_jwt_authentications_success_total"),
"Total number of successful OAuth Client Private Key Jwt Authentications",
nil,
nil,
),
oAuthClientSecretBasicAuthenticationFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_secret_basic_authentications_failure_total"),
"Total number of failed OAuth Client Secret Basic Authentications",
nil,
nil,
),
oAuthClientSecretBasicAuthentications: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_secret_basic_authentications_success_total"),
"Total number of successful OAuth Client Secret Basic Authentications",
nil,
nil,
),
oAuthClientSecretPostAuthenticationFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_secret_post_authentications_failure_total"),
"Total number of failed OAuth Client Secret Post Authentications",
nil,
nil,
),
oAuthClientSecretPostAuthentications: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_secret_post_authentications_success_total"),
"Total number of successful OAuth Client Secret Post Authentications",
nil,
nil,
),
oAuthClientWindowsIntegratedAuthenticationFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_windows_authentications_failure_total"),
"Total number of failed OAuth Client Windows Integrated Authentications",
nil,
nil,
),
oAuthClientWindowsIntegratedAuthentications: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_client_windows_authentications_success_total"),
"Total number of successful OAuth Client Windows Integrated Authentications",
nil,
nil,
),
oAuthLogonCertificateRequestFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_logon_certificate_requests_failure_total"),
"Total number of failed OAuth Logon Certificate Requests",
nil,
nil,
),
oAuthLogonCertificateTokenRequests: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_logon_certificate_token_requests_success_total"),
"Total number of successful RP tokens issued for OAuth Logon Certificate Requests",
nil,
nil,
),
oAuthPasswordGrantRequestFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_password_grant_requests_failure_total"),
"Total number of failed OAuth Password Grant Requests",
nil,
nil,
),
oAuthPasswordGrantRequests: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_password_grant_requests_success_total"),
"Total number of successful OAuth Password Grant Requests",
nil,
nil,
),
oAuthTokenRequests: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "oauth_token_requests_success_total"),
"Total number of successful RP tokens issued over OAuth protocol",
nil,
nil,
),
samlPTokenRequests: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "samlp_token_requests_success_total"),
"Total number of successful RP tokens issued over SAML-P protocol",
nil,
nil,
),
ssoAuthenticationFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "sso_authentications_failure_total"),
"Total number of failed SSO authentications",
nil,
nil,
),
ssoAuthentications: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "sso_authentications_success_total"),
"Total number of successful SSO authentications",
nil,
nil,
),
wsfedTokenRequests: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "wsfed_token_requests_success_total"),
"Total number of successful RP tokens issued over WS-Fed protocol",
nil,
nil,
),
wstrustTokenRequests: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "wstrust_token_requests_success_total"),
"Total number of successful RP tokens issued over WS-Trust protocol",
nil,
nil,
),
upAuthenticationFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "userpassword_authentications_failure_total"),
"Total number of failed AD U/P authentications",
nil,
nil,
),
upAuthentications: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "userpassword_authentications_success_total"),
"Total number of successful AD U/P authentications",
nil,
nil,
),
externalAuthenticationFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "external_authentications_failure_total"),
"Total number of failed authentications from external MFA providers",
nil,
nil,
),
externalAuthentications: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "external_authentications_success_total"),
"Total number of successful authentications from external MFA providers",
nil,
nil,
),
artifactDBFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "db_artifact_failure_total"),
"Total number of failures connecting to the artifact database",
nil,
nil,
),
avgArtifactDBQueryTime: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "db_artifact_query_time_seconds_total"),
"Accumulator of time taken for an artifact database query",
nil,
nil,
),
configDBFailures: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "db_config_failure_total"),
"Total number of failures connecting to the configuration database",
nil,
nil,
),
avgConfigDBQueryTime: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "db_config_query_time_seconds_total"),
"Accumulator of time taken for a configuration database query",
nil,
nil,
),
federationMetadataRequests: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "federation_metadata_requests_total"),
"Total number of Federation Metadata requests",
nil,
nil,
),
}, nil
}
type perflibADFS struct {
AdLoginConnectionFailures float64 `perflib:"AD login Connection Failures"`
CertificateAuthentications float64 `perflib:"Certificate Authentications"`
DeviceAuthentications float64 `perflib:"Device Authentications"`
ExtranetAccountLockouts float64 `perflib:"Extranet Account Lockouts"`
FederatedAuthentications float64 `perflib:"Federated Authentications"`
PassportAuthentications float64 `perflib:"Microsoft Passport Authentications"`
PassiveRequests float64 `perflib:"Passive Requests"`
PasswordChangeFailed float64 `perflib:"Password Change Failed Requests"`
PasswordChangeSucceeded float64 `perflib:"Password Change Successful Requests"`
TokenRequests float64 `perflib:"Token Requests"`
WindowsIntegratedAuthentications float64 `perflib:"Windows Integrated Authentications"`
AdLoginConnectionFailures float64 `perflib:"AD Login Connection Failures"`
CertificateAuthentications float64 `perflib:"Certificate Authentications"`
DeviceAuthentications float64 `perflib:"Device Authentications"`
ExtranetAccountLockouts float64 `perflib:"Extranet Account Lockouts"`
FederatedAuthentications float64 `perflib:"Federated Authentications"`
PassportAuthentications float64 `perflib:"Microsoft Passport Authentications"`
PassiveRequests float64 `perflib:"Passive Requests"`
PasswordChangeFailed float64 `perflib:"Password Change Failed Requests"`
PasswordChangeSucceeded float64 `perflib:"Password Change Successful Requests"`
TokenRequests float64 `perflib:"Token Requests"`
WindowsIntegratedAuthentications float64 `perflib:"Windows Integrated Authentications"`
OAuthAuthZRequests float64 `perflib:"OAuth AuthZ Requests"`
OAuthClientAuthentications float64 `perflib:"OAuth Client Authentications"`
OAuthClientAuthenticationFailures float64 `perflib:"OAuth Client Authentications Failures"`
OAuthClientCredentialRequestFailures float64 `perflib:"OAuth Client Credentials Request Failures"`
OAuthClientCredentialRequests float64 `perflib:"OAuth Client Credentials Requests"`
OAuthClientPrivKeyJWTAuthnFailures float64 `perflib:"OAuth Client Private Key Jwt Authentication Failures"`
OAuthClientPrivKeyJWTAuthentications float64 `perflib:"OAuth Client Private Key Jwt Authentications"`
OAuthClientBasicAuthnFailures float64 `perflib:"OAuth Client Secret Basic Authentication Failures"`
OAuthClientBasicAuthentications float64 `perflib:"OAuth Client Secret Basic Authentication Requests"`
OAuthClientSecretPostAuthnFailures float64 `perflib:"OAuth Client Secret Post Authentication Failures"`
OAuthClientSecretPostAuthentications float64 `perflib:"OAuth Client Secret Post Authentications"`
OAuthClientWindowsAuthnFailures float64 `perflib:"OAuth Client Windows Integrated Authentication Failures"`
OAuthClientWindowsAuthentications float64 `perflib:"OAuth Client Windows Integrated Authentications"`
OAuthLogonCertRequestFailures float64 `perflib:"OAuth Logon Certificate Request Failures"`
OAuthLogonCertTokenRequests float64 `perflib:"OAuth Logon Certificate Token Requests"`
OAuthPasswordGrantRequestFailures float64 `perflib:"OAuth Password Grant Request Failures"`
OAuthPasswordGrantRequests float64 `perflib:"OAuth Password Grant Requests"`
OAuthTokenRequests float64 `perflib:"OAuth Token Requests"`
SAMLPTokenRequests float64 `perflib:"SAML-P Token Requests"`
SSOAuthenticationFailures float64 `perflib:"SSO Authentication Failures"`
SSOAuthentications float64 `perflib:"SSO Authentications"`
WSFedTokenRequests float64 `perflib:"WS-Fed Token Requests"`
WSTrustTokenRequests float64 `perflib:"WS-Trust Token Requests"`
UsernamePasswordAuthnFailures float64 `perflib:"U/P Authentication Failures"`
UsernamePasswordAuthentications float64 `perflib:"U/P Authentications"`
ExternalAuthentications float64 `perflib:"External Authentications"`
ExternalAuthNFailures float64 `perflib:"External Authentication Failures"`
ArtifactDBFailures float64 `perflib:"Artifact Database Connection Failures"`
AvgArtifactDBQueryTime float64 `perflib:"Average Artifact Database Query Time"`
ConfigDBFailures float64 `perflib:"Configuration Database Connection Failures"`
AvgConfigDBQueryTime float64 `perflib:"Average Config Database Query Time"`
FederationMetadataRequests float64 `perflib:"Federation Metadata Requests"`
}
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
}
@@ -184,5 +444,197 @@ func (c *adfsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric)
prometheus.CounterValue,
adfsData[0].WindowsIntegratedAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthAuthZRequests,
prometheus.CounterValue,
adfsData[0].OAuthAuthZRequests,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientAuthenticationsFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientAuthenticationFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientCredentialsRequestFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientCredentialRequestFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientCredentialsRequests,
prometheus.CounterValue,
adfsData[0].OAuthClientCredentialRequests,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientPrivateKeyJwtAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientPrivKeyJWTAuthnFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientPrivateKeyJwtAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientPrivKeyJWTAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientSecretBasicAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientBasicAuthnFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientSecretBasicAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientBasicAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientSecretPostAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientSecretPostAuthnFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientSecretPostAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientSecretPostAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientWindowsIntegratedAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientWindowsAuthnFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientWindowsIntegratedAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientWindowsAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthLogonCertificateRequestFailures,
prometheus.CounterValue,
adfsData[0].OAuthLogonCertRequestFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthLogonCertificateTokenRequests,
prometheus.CounterValue,
adfsData[0].OAuthLogonCertTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthPasswordGrantRequestFailures,
prometheus.CounterValue,
adfsData[0].OAuthPasswordGrantRequestFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthPasswordGrantRequests,
prometheus.CounterValue,
adfsData[0].OAuthPasswordGrantRequests,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthTokenRequests,
prometheus.CounterValue,
adfsData[0].OAuthTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.samlPTokenRequests,
prometheus.CounterValue,
adfsData[0].SAMLPTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.ssoAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].SSOAuthenticationFailures,
)
ch <- prometheus.MustNewConstMetric(
c.ssoAuthentications,
prometheus.CounterValue,
adfsData[0].SSOAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.wsfedTokenRequests,
prometheus.CounterValue,
adfsData[0].WSFedTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.wstrustTokenRequests,
prometheus.CounterValue,
adfsData[0].WSTrustTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.upAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].UsernamePasswordAuthnFailures,
)
ch <- prometheus.MustNewConstMetric(
c.upAuthentications,
prometheus.CounterValue,
adfsData[0].UsernamePasswordAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.externalAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].ExternalAuthNFailures,
)
ch <- prometheus.MustNewConstMetric(
c.externalAuthentications,
prometheus.CounterValue,
adfsData[0].ExternalAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.artifactDBFailures,
prometheus.CounterValue,
adfsData[0].ArtifactDBFailures,
)
ch <- prometheus.MustNewConstMetric(
c.avgArtifactDBQueryTime,
prometheus.CounterValue,
adfsData[0].AvgArtifactDBQueryTime*math.Pow(10, -8),
)
ch <- prometheus.MustNewConstMetric(
c.configDBFailures,
prometheus.CounterValue,
adfsData[0].ConfigDBFailures,
)
ch <- prometheus.MustNewConstMetric(
c.avgConfigDBQueryTime,
prometheus.CounterValue,
adfsData[0].AvgConfigDBQueryTime*math.Pow(10, -8),
)
ch <- prometheus.MustNewConstMetric(
c.federationMetadataRequests,
prometheus.CounterValue,
adfsData[0].FederationMetadataRequests,
)
return nil
}

9
collector/adfs_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkADFSCollector(b *testing.B) {
benchmarkCollector(b, "adfs", newADFSCollector)
}

View File

@@ -1,18 +1,18 @@
//go:build windows
// +build windows
package collector
import (
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
)
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
@@ -45,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)",
@@ -228,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
@@ -270,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
}

View File

@@ -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))
@@ -148,3 +153,7 @@ func expandEnabledChildCollectors(enabled string) []string {
sort.Strings(result)
return result
}
func milliSecToSec(t float64) float64 {
return t / 1000
}

View File

@@ -3,6 +3,9 @@ package collector
import (
"reflect"
"testing"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
)
func TestExpandChildCollectors(t *testing.T) {
@@ -32,3 +35,27 @@ func TestExpandChildCollectors(t *testing.T) {
})
}
}
func benchmarkCollector(b *testing.B, name string, collectFunc func(logger log.Logger) (Collector, error)) {
// Create perflib scrape context. Some perflib collectors required a correct context,
// or will fail during benchmark.
scrapeContext, err := PrepareScrapeContext([]string{name})
if err != nil {
b.Error(err)
}
c, err := collectFunc(log.NewNopLogger())
if err != nil {
b.Error(err)
}
metrics := make(chan prometheus.Metric)
go func() {
for {
<-metrics
}
}()
for i := 0; i < b.N; i++ {
c.Collect(scrapeContext, metrics) //nolint:errcheck
}
}

View File

@@ -1,19 +1,22 @@
//go:build windows
// +build windows
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
@@ -36,12 +39,20 @@ type ContainerMetricsCollector struct {
PacketsSent *prometheus.Desc
DroppedPacketsIncoming *prometheus.Desc
DroppedPacketsOutgoing *prometheus.Desc
// Storage
ReadCountNormalized *prometheus.Desc
ReadSizeBytes *prometheus.Desc
WriteCountNormalized *prometheus.Desc
WriteSizeBytes *prometheus.Desc
}
// NewContainerMetricsCollector constructs a new ContainerMetricsCollector
func NewContainerMetricsCollector() (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",
@@ -126,6 +137,30 @@ func NewContainerMetricsCollector() (Collector, error) {
[]string{"container_id", "interface"},
nil,
),
ReadCountNormalized: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "storage_read_count_normalized_total"),
"Read Count Normalized",
[]string{"container_id"},
nil,
),
ReadSizeBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "storage_read_size_bytes_total"),
"Read Size Bytes",
[]string{"container_id"},
nil,
),
WriteCountNormalized: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "storage_write_count_normalized_total"),
"Write Count Normalized",
[]string{"container_id"},
nil,
),
WriteSizeBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "storage_write_size_bytes_total"),
"Write Size Bytes",
[]string{"container_id"},
nil,
),
}, nil
}
@@ -133,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)
}
}
@@ -152,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
}
@@ -167,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,
@@ -226,52 +265,96 @@ func (c *ContainerMetricsCollector) collect(ch chan<- prometheus.Metric) (*prome
float64(cstats.Processor.RuntimeKernel100ns)*ticksToSecondsScaleFactor,
containerIdWithPrefix,
)
ch <- prometheus.MustNewConstMetric(
c.ReadCountNormalized,
prometheus.CounterValue,
float64(cstats.Storage.ReadCountNormalized),
containerIdWithPrefix,
)
ch <- prometheus.MustNewConstMetric(
c.ReadSizeBytes,
prometheus.CounterValue,
float64(cstats.Storage.ReadSizeBytes),
containerIdWithPrefix,
)
ch <- prometheus.MustNewConstMetric(
c.WriteCountNormalized,
prometheus.CounterValue,
float64(cstats.Storage.WriteCountNormalized),
containerIdWithPrefix,
)
ch <- prometheus.MustNewConstMetric(
c.WriteSizeBytes,
prometheus.CounterValue,
float64(cstats.Storage.WriteSizeBytes),
containerIdWithPrefix,
)
}
if len(cstats.Network) == 0 {
log.Info("No Network Stats for container: ", containerDetails.ID)
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
}
networkStats := cstats.Network
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
}
for _, networkInterface := range networkStats {
ch <- prometheus.MustNewConstMetric(
c.BytesReceived,
prometheus.CounterValue,
float64(networkInterface.BytesReceived),
containerIdWithPrefix, networkInterface.EndpointId,
float64(endpointStats.BytesReceived),
containerIdWithPrefix, endpointId,
)
ch <- prometheus.MustNewConstMetric(
c.BytesSent,
prometheus.CounterValue,
float64(networkInterface.BytesSent),
containerIdWithPrefix, networkInterface.EndpointId,
float64(endpointStats.BytesSent),
containerIdWithPrefix, endpointId,
)
ch <- prometheus.MustNewConstMetric(
c.PacketsReceived,
prometheus.CounterValue,
float64(networkInterface.PacketsReceived),
containerIdWithPrefix, networkInterface.EndpointId,
float64(endpointStats.PacketsReceived),
containerIdWithPrefix, endpointId,
)
ch <- prometheus.MustNewConstMetric(
c.PacketsSent,
prometheus.CounterValue,
float64(networkInterface.PacketsSent),
containerIdWithPrefix, networkInterface.EndpointId,
float64(endpointStats.PacketsSent),
containerIdWithPrefix, endpointId,
)
ch <- prometheus.MustNewConstMetric(
c.DroppedPacketsIncoming,
prometheus.CounterValue,
float64(networkInterface.DroppedPacketsIncoming),
containerIdWithPrefix, networkInterface.EndpointId,
float64(endpointStats.DroppedPacketsIncoming),
containerIdWithPrefix, endpointId,
)
ch <- prometheus.MustNewConstMetric(
c.DroppedPacketsOutgoing,
prometheus.CounterValue,
float64(networkInterface.DroppedPacketsOutgoing),
containerIdWithPrefix, networkInterface.EndpointId,
float64(endpointStats.DroppedPacketsOutgoing),
containerIdWithPrefix, endpointId,
)
break
}
}

View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkContainerCollector(b *testing.B) {
benchmarkCollector(b, "container", newContainerMetricsCollector)
}

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package collector
@@ -5,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
@@ -36,13 +31,18 @@ type cpuCollectorFull struct {
ProcessorFrequencyMHz *prometheus.Desc
ProcessorMaxFrequencyMHz *prometheus.Desc
ProcessorPerformance *prometheus.Desc
ProcessorMPerf *prometheus.Desc
ProcessorRTC *prometheus.Desc
ProcessorUtility *prometheus.Desc
ProcessorPrivUtility *prometheus.Desc
}
// 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
@@ -51,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",
@@ -59,7 +60,7 @@ func newCPUCollector() (Collector, error) {
),
TimeTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "time_total"),
"Time that processor spent in different modes (idle, user, system, ...)",
"Time that processor spent in different modes (dpc, idle, interrupt, privileged, user)",
[]string{"core", "mode"},
nil,
),
@@ -79,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",
@@ -87,7 +89,7 @@ func newCPUCollector() (Collector, error) {
),
TimeTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "time_total"),
"Time that processor spent in different modes (idle, user, system, ...)",
"Time that processor spent in different modes (dpc, idle, interrupt, privileged, user)",
[]string{"core", "mode"},
nil,
),
@@ -128,11 +130,35 @@ func newCPUCollector() (Collector, error) {
nil,
),
ProcessorPerformance: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "processor_performance"),
prometheus.BuildFQName(Namespace, subsystem, "processor_performance_total"),
"Processor Performance is the average performance of the processor while it is executing instructions, as a percentage of the nominal performance of the processor. On some processors, Processor Performance may exceed 100%",
[]string{"core"},
nil,
),
ProcessorMPerf: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "processor_mperf_total"),
"Processor MPerf is the number of TSC ticks incremented while executing instructions",
[]string{"core"},
nil,
),
ProcessorRTC: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "processor_rtc_total"),
"Processor RTC represents the number of RTC ticks made since the system booted. It should consistently be 64e6, and can be used to properly derive Processor Utility Rate",
[]string{"core"},
nil,
),
ProcessorUtility: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "processor_utility_total"),
"Processor Utility represents is the amount of time the core spends executing instructions",
[]string{"core"},
nil,
),
ProcessorPrivUtility: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "processor_privileged_utility_total"),
"Processor Privilieged Utility represents is the amount of time the core has spent executing instructions inside the kernel",
[]string{"core"},
nil,
),
}, nil
}
@@ -157,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
}
@@ -257,14 +283,16 @@ type perflibProcessorInformation struct {
PrivilegedUtilitySeconds float64 `perflib:"% Privileged Utility"`
ProcessorFrequencyMHz float64 `perflib:"Processor Frequency"`
ProcessorPerformance float64 `perflib:"% Processor Performance"`
ProcessorMPerf float64 `perflib:"% Processor Performance,secondvalue"`
ProcessorTimeSeconds float64 `perflib:"% Processor Time"`
ProcessorUtilityRate float64 `perflib:"% Processor Utility"`
ProcessorRTC float64 `perflib:"% Processor Utility,secondvalue"`
UserTimeSeconds float64 `perflib:"% User Time"`
}
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
}
@@ -365,10 +393,34 @@ func (c *cpuCollectorFull) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
)
ch <- prometheus.MustNewConstMetric(
c.ProcessorPerformance,
prometheus.GaugeValue,
prometheus.CounterValue,
cpu.ProcessorPerformance,
core,
)
ch <- prometheus.MustNewConstMetric(
c.ProcessorMPerf,
prometheus.CounterValue,
cpu.ProcessorMPerf,
core,
)
ch <- prometheus.MustNewConstMetric(
c.ProcessorRTC,
prometheus.CounterValue,
cpu.ProcessorRTC,
core,
)
ch <- prometheus.MustNewConstMetric(
c.ProcessorUtility,
prometheus.CounterValue,
cpu.ProcessorUtilityRate,
core,
)
ch <- prometheus.MustNewConstMetric(
c.ProcessorPrivUtility,
prometheus.CounterValue,
cpu.PrivilegedUtilitySeconds,
core,
)
}
return nil

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package collector
@@ -7,15 +8,12 @@ import (
"strconv"
"strings"
"github.com/StackExchange/wmi"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
"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"
@@ -23,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",
@@ -58,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

9
collector/cpu_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkCPUCollector(b *testing.B) {
benchmarkCollector(b, "cpu", newCPUCollector)
}

View File

@@ -1,31 +1,31 @@
//go:build windows
// +build windows
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-community/windows_exporter/headers/sysinfoapi"
"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,57 +54,53 @@ 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
}
// Win32_ComputerSystem docs:
// - https://msdn.microsoft.com/en-us/library/aa394102
type Win32_ComputerSystem struct {
NumberOfLogicalProcessors uint32
TotalPhysicalMemory uint64
DNSHostname string
Domain string
Workgroup *string
}
func (c *CSCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
var dst []Win32_ComputerSystem
q := queryAll(&dst)
if err := wmi.Query(q, &dst); err != nil {
// Get systeminfo for number of processors
systemInfo := sysinfoapi.GetSystemInfo()
// Get memory status for physical memory
mem, err := sysinfoapi.GlobalMemoryStatusEx()
if err != nil {
return nil, err
}
if len(dst) == 0 {
return nil, errors.New("WMI query returned empty result set")
}
ch <- prometheus.MustNewConstMetric(
c.LogicalProcessors,
prometheus.GaugeValue,
float64(dst[0].NumberOfLogicalProcessors),
float64(systemInfo.NumberOfProcessors),
)
ch <- prometheus.MustNewConstMetric(
c.PhysicalMemoryBytes,
prometheus.GaugeValue,
float64(dst[0].TotalPhysicalMemory),
float64(mem.TotalPhys),
)
var fqdn string
if dst[0].Workgroup == nil || dst[0].Domain != *dst[0].Workgroup {
fqdn = dst[0].DNSHostname + "." + dst[0].Domain
} else {
fqdn = dst[0].DNSHostname
hostname, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSHostname)
if err != nil {
return nil, err
}
domain, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSDomain)
if err != nil {
return nil, err
}
fqdn, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSFullyQualified)
if err != nil {
return nil, err
}
ch <- prometheus.MustNewConstMetric(
c.Hostname,
prometheus.GaugeValue,
1.0,
dst[0].DNSHostname,
dst[0].Domain,
hostname,
domain,
fqdn,
)

9
collector/cs_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkCsCollector(b *testing.B) {
benchmarkCollector(b, "cs", newCSCollector)
}

View File

@@ -1,27 +1,25 @@
//go:build windows
// +build windows
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
@@ -91,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))
@@ -104,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"),
@@ -128,7 +134,7 @@ func NewDFSRCollector() (Collector, error) {
ConnectionFilesReceivedTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "connection_received_files_total"),
"Total number of files receieved for connection",
"Total number of files received for connection",
[]string{"name"},
nil,
),
@@ -447,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
}
@@ -554,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
}
@@ -764,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
}

9
collector/dfsr_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkDFSRCollector(b *testing.B) {
benchmarkCollector(b, "dfsr", newDFSRCollector)
}

View File

@@ -1,17 +1,17 @@
//go:build windows
// +build windows
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
@@ -39,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)",
@@ -229,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
}

9
collector/dhcp_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkDHCPCollector(b *testing.B) {
benchmarkCollector(b, "dhcp", newDhcpCollector)
}

209
collector/diskdrive.go Normal file
View 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
}

View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkDiskDriveCollector(b *testing.B) {
benchmarkCollector(b, "disk_drive", newDiskDriveInfoCollector)
}

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package collector
@@ -5,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
@@ -40,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",
@@ -136,7 +138,7 @@ func NewDNSCollector() (Collector, error) {
),
Responses: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "responses_total"),
"Number of reponses sent by DNS server",
"Number of responses sent by DNS server",
[]string{"protocol"},
nil,
),
@@ -183,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
@@ -237,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
}

9
collector/dns_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkDNSCollector(b *testing.B) {
benchmarkCollector(b, "dns", newDNSCollector)
}

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package collector
@@ -7,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
@@ -82,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 {
@@ -107,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"),
@@ -202,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
}
}
@@ -222,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
}
@@ -234,7 +239,7 @@ func (c *exchangeCollector) collectADAccessProcesses(ctx *ScrapeContext, ch chan
}
// since we're not including the PID suffix from the instance names in the label names,
// we get an occational duplicate. This seems to affect about 4 instances only on this object.
// we get an occasional duplicate. This seems to affect about 4 instances only on this object.
labelUseCount[labelName]++
if labelUseCount[labelName] > 1 {
labelName = fmt.Sprintf("%s_%d", labelName, labelUseCount[labelName])
@@ -280,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
}
@@ -308,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
}
@@ -362,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
}
@@ -390,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
}
@@ -426,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
}
@@ -482,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
}
@@ -556,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
}
@@ -607,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 {

View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkExchangeCollector(b *testing.B) {
benchmarkCollector(b, "exchange", newExchangeCollector)
}

View File

@@ -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

View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkFsrmQuotaCollector(b *testing.B) {
benchmarkCollector(b, "fsrmquota", newFSRMQuotaCollector)
}

View File

@@ -1,21 +1,22 @@
//go:build windows
// +build windows
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
@@ -52,6 +53,11 @@ type HyperVCollector struct {
LogicalProcessors *prometheus.Desc
VirtualProcessors *prometheus.Desc
// Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor
HostLPGuestRunTimePercent *prometheus.Desc
HostLPHypervisorRunTimePercent *prometheus.Desc
HostLPTotalRunTimePercent *prometheus.Desc
// Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor
HostGuestRunTime *prometheus.Desc
HostHypervisorRunTime *prometheus.Desc
@@ -110,12 +116,27 @@ type HyperVCollector struct {
VMNetworkDroppedPacketsOutgoing *prometheus.Desc
VMNetworkPacketsReceived *prometheus.Desc
VMNetworkPacketsSent *prometheus.Desc
// Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM
VMMemoryAddedMemory *prometheus.Desc
VMMemoryAveragePressure *prometheus.Desc
VMMemoryCurrentPressure *prometheus.Desc
VMMemoryGuestVisiblePhysicalMemory *prometheus.Desc
VMMemoryMaximumPressure *prometheus.Desc
VMMemoryMemoryAddOperations *prometheus.Desc
VMMemoryMemoryRemoveOperations *prometheus.Desc
VMMemoryMinimumPressure *prometheus.Desc
VMMemoryPhysicalMemory *prometheus.Desc
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",
@@ -296,6 +317,27 @@ func NewHyperVCollector() (Collector, error) {
//
HostLPGuestRunTimePercent: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("host_lp"), "guest_run_time_percent"),
"The percentage of time spent by the processor in guest code",
[]string{"core"},
nil,
),
HostLPHypervisorRunTimePercent: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("host_lp"), "hypervisor_run_time_percent"),
"The percentage of time spent by the processor in hypervisor code",
[]string{"core"},
nil,
),
HostLPTotalRunTimePercent: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("host_lp"), "total_run_time_percent"),
"The percentage of time spent by the processor in guest and hypervisor code",
[]string{"core"},
nil,
),
//
HostGuestRunTime: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("host_cpu"), "guest_run_time"),
"The time spent by the virtual processor in guest code",
@@ -592,6 +634,69 @@ func NewHyperVCollector() (Collector, error) {
[]string{"vm_interface"},
nil,
),
//
VMMemoryAddedMemory: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "added_total"),
"This counter represents memory in MB added to the VM",
[]string{"vm"},
nil,
),
VMMemoryAveragePressure: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "pressure_average"),
"This gauge represents the average pressure in the VM.",
[]string{"vm"},
nil,
),
VMMemoryCurrentPressure: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "pressure_current"),
"This gauge represents the current pressure in the VM.",
[]string{"vm"},
nil,
),
VMMemoryGuestVisiblePhysicalMemory: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "physical_guest_visible"),
"'This gauge represents the amount of memory in MB visible to the VM guest.'",
[]string{"vm"},
nil,
),
VMMemoryMaximumPressure: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "pressure_maximum"),
"This gauge represents the maximum pressure band in the VM.",
[]string{"vm"},
nil,
),
VMMemoryMemoryAddOperations: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "add_operations_total"),
"This counter represents the number of operations adding memory to the VM.",
[]string{"vm"},
nil,
),
VMMemoryMemoryRemoveOperations: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "remove_operations_total"),
"This counter represents the number of operations removing memory from the VM.",
[]string{"vm"},
nil,
),
VMMemoryMinimumPressure: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "pressure_minimum"),
"This gauge represents the minimum pressure band in the VM.",
[]string{"vm"},
nil,
),
VMMemoryPhysicalMemory: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "physical"),
"This gauge represents the current amount of memory in MB assigned to the VM.",
[]string{"vm"},
nil,
),
VMMemoryRemovedMemory: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_memory"), "removed_total"),
"This counter represents memory in MB removed from the VM",
[]string{"vm"},
nil,
),
}, nil
}
@@ -599,52 +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 {
_ = 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 {
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual memory metrics", "desc", desc, "err", err)
return err
}
@@ -659,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
}
@@ -692,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
}
@@ -756,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
}
@@ -894,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
}
@@ -918,6 +1033,59 @@ func (c *HyperVCollector) collectVmProcessor(ch chan<- prometheus.Metric) (*prom
return nil, nil
}
// Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor ...
type Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor struct {
Name string
PercentGuestRunTime uint64
PercentHypervisorRunTime uint64
PercentTotalRunTime uint
}
func (c *HyperVCollector) collectHostLPUsage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor
q := queryAll(&dst, c.logger)
if err := wmi.Query(q, &dst); err != nil {
return nil, err
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
// The name format is Hv LP <core id>
parts := strings.Split(obj.Name, " ")
if len(parts) != 3 {
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Unexpected format of Name in collectHostLPUsage: %q", obj.Name))
continue
}
coreId := parts[2]
ch <- prometheus.MustNewConstMetric(
c.HostLPGuestRunTimePercent,
prometheus.GaugeValue,
float64(obj.PercentGuestRunTime),
coreId,
)
ch <- prometheus.MustNewConstMetric(
c.HostLPHypervisorRunTimePercent,
prometheus.GaugeValue,
float64(obj.PercentHypervisorRunTime),
coreId,
)
ch <- prometheus.MustNewConstMetric(
c.HostLPTotalRunTimePercent,
prometheus.GaugeValue,
float64(obj.PercentTotalRunTime),
coreId,
)
}
return nil, nil
}
// Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor ...
type Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor struct {
Name string
@@ -929,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
}
@@ -941,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]
@@ -990,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
}
@@ -1002,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]
@@ -1077,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
}
@@ -1212,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,
@@ -1236,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
}
@@ -1306,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
}
@@ -1375,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
}
@@ -1430,3 +1604,104 @@ func (c *HyperVCollector) collectVmNetwork(ch chan<- prometheus.Metric) (*promet
return nil, nil
}
// Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM ...
type Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM struct {
Name string
AddedMemory uint64
AveragePressure uint64
CurrentPressure uint64
GuestVisiblePhysicalMemory uint64
MaximumPressure uint64
MemoryAddOperations uint64
MemoryRemoveOperations uint64
MinimumPressure uint64
PhysicalMemory uint64
RemovedMemory uint64
}
func (c *HyperVCollector) collectVmMemory(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
var dst []Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM
q := queryAll(&dst, c.logger)
if err := wmi.Query(q, &dst); err != nil {
return nil, err
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
ch <- prometheus.MustNewConstMetric(
c.VMMemoryAddedMemory,
prometheus.CounterValue,
float64(obj.AddedMemory),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.VMMemoryAveragePressure,
prometheus.GaugeValue,
float64(obj.AveragePressure),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.VMMemoryCurrentPressure,
prometheus.GaugeValue,
float64(obj.CurrentPressure),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.VMMemoryGuestVisiblePhysicalMemory,
prometheus.GaugeValue,
float64(obj.GuestVisiblePhysicalMemory),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.VMMemoryMaximumPressure,
prometheus.GaugeValue,
float64(obj.MaximumPressure),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.VMMemoryMemoryAddOperations,
prometheus.CounterValue,
float64(obj.MemoryAddOperations),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.VMMemoryMemoryRemoveOperations,
prometheus.CounterValue,
float64(obj.MemoryRemoveOperations),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.VMMemoryMinimumPressure,
prometheus.GaugeValue,
float64(obj.MinimumPressure),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.VMMemoryPhysicalMemory,
prometheus.GaugeValue,
float64(obj.PhysicalMemory),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.VMMemoryRemovedMemory,
prometheus.CounterValue,
float64(obj.RemovedMemory),
obj.Name,
)
}
return nil, nil
}

9
collector/hyperv_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkHypervCollector(b *testing.B) {
benchmarkCollector(b, "hyperv", newHyperVCollector)
}

File diff suppressed because it is too large Load Diff

49
collector/iis_test.go Normal file
View File

@@ -0,0 +1,49 @@
package collector
import (
"reflect"
"testing"
)
func BenchmarkIISCollector(b *testing.B) {
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
View 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...)
}
}

View File

@@ -1,34 +1,45 @@
//go:build windows
// +build windows
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
ReadBytesTotal *prometheus.Desc
ReadsTotal *prometheus.Desc
WriteBytesTotal *prometheus.Desc
@@ -43,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)",
@@ -59,6 +118,20 @@ func NewLogicalDiskCollector() (Collector, error) {
nil,
),
AvgReadQueue: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "avg_read_requests_queued"),
"Average number of read requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskReadQueueLength)",
[]string{"volume"},
nil,
),
AvgWriteQueue: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "avg_write_requests_queued"),
"Average number of write requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskWriteQueueLength)",
[]string{"volume"},
nil,
),
ReadBytesTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "read_bytes_total"),
"The number of bytes transferred from the disk during read operations (LogicalDisk.DiskReadBytesPerSec)",
@@ -103,14 +176,14 @@ func NewLogicalDiskCollector() (Collector, error) {
FreeSpace: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "free_bytes"),
"Free space in bytes (LogicalDisk.PercentFreeSpace)",
"Free space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace)",
[]string{"volume"},
nil,
),
TotalSpace: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "size_bytes"),
"Total space in bytes (LogicalDisk.PercentFreeSpace_Base)",
"Total space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace_Base)",
[]string{"volume"},
nil,
),
@@ -150,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
}
@@ -159,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
@@ -169,33 +242,35 @@ func (c *LogicalDiskCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.
// - https://msdn.microsoft.com/en-us/windows/hardware/aa394307(v=vs.71) - Win32_PerfRawData_PerfDisk_LogicalDisk class
// - https://msdn.microsoft.com/en-us/library/ms803973.aspx - LogicalDisk object reference
type logicalDisk struct {
Name string
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
DiskReadBytesPerSec float64 `perflib:"Disk Read Bytes/sec"`
DiskReadsPerSec float64 `perflib:"Disk Reads/sec"`
DiskWriteBytesPerSec float64 `perflib:"Disk Write Bytes/sec"`
DiskWritesPerSec float64 `perflib:"Disk Writes/sec"`
PercentDiskReadTime float64 `perflib:"% Disk Read Time"`
PercentDiskWriteTime float64 `perflib:"% Disk Write Time"`
PercentFreeSpace float64 `perflib:"% Free Space_Base"`
PercentFreeSpace_Base float64 `perflib:"Free Megabytes"`
PercentIdleTime float64 `perflib:"% Idle Time"`
SplitIOPerSec float64 `perflib:"Split IO/Sec"`
AvgDiskSecPerRead float64 `perflib:"Avg. Disk sec/Read"`
AvgDiskSecPerWrite float64 `perflib:"Avg. Disk sec/Write"`
AvgDiskSecPerTransfer float64 `perflib:"Avg. Disk sec/Transfer"`
Name string
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
AvgDiskReadQueueLength float64 `perflib:"Avg. Disk Read Queue Length"`
AvgDiskWriteQueueLength float64 `perflib:"Avg. Disk Write Queue Length"`
DiskReadBytesPerSec float64 `perflib:"Disk Read Bytes/sec"`
DiskReadsPerSec float64 `perflib:"Disk Reads/sec"`
DiskWriteBytesPerSec float64 `perflib:"Disk Write Bytes/sec"`
DiskWritesPerSec float64 `perflib:"Disk Writes/sec"`
PercentDiskReadTime float64 `perflib:"% Disk Read Time"`
PercentDiskWriteTime float64 `perflib:"% Disk Write Time"`
PercentFreeSpace float64 `perflib:"% Free Space_Base"`
PercentFreeSpace_Base float64 `perflib:"Free Megabytes"`
PercentIdleTime float64 `perflib:"% Idle Time"`
SplitIOPerSec float64 `perflib:"Split IO/Sec"`
AvgDiskSecPerRead float64 `perflib:"Avg. Disk sec/Read"`
AvgDiskSecPerWrite float64 `perflib:"Avg. Disk sec/Write"`
AvgDiskSecPerTransfer float64 `perflib:"Avg. Disk sec/Transfer"`
}
func (c *LogicalDiskCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
var dst []logicalDisk
if err := unmarshalObject(ctx.perfObjects["LogicalDisk"], &dst); 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
}
@@ -206,6 +281,20 @@ func (c *LogicalDiskCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.
volume.Name,
)
ch <- prometheus.MustNewConstMetric(
c.AvgReadQueue,
prometheus.GaugeValue,
volume.AvgDiskReadQueueLength*ticksToSecondsScaleFactor,
volume.Name,
)
ch <- prometheus.MustNewConstMetric(
c.AvgWriteQueue,
prometheus.GaugeValue,
volume.AvgDiskWriteQueueLength*ticksToSecondsScaleFactor,
volume.Name,
)
ch <- prometheus.MustNewConstMetric(
c.ReadBytesTotal,
prometheus.CounterValue,

View File

@@ -0,0 +1,13 @@
package collector
import (
"testing"
)
func BenchmarkLogicalDiskCollector(b *testing.B) {
// Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all disks.
localVolumeInclude := ".+"
volumeInclude = &localVolumeInclude
benchmarkCollector(b, "logical_disk", newLogicalDiskCollector)
}

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package collector
@@ -5,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)",
@@ -37,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
@@ -51,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
}

10
collector/logon_test.go Normal file
View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkLogonCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newLogonCollector)
}

View File

@@ -1,21 +1,21 @@
// returns data points from Win32_PerfRawData_PerfOS_Memory
// <add link to documentation here> - Win32_PerfRawData_PerfOS_Memory class
//go:build windows
// +build windows
package collector
import (
"github.com/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
@@ -50,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"+
@@ -76,7 +78,8 @@ func NewMemoryCollector() (Collector, error) {
),
CacheFaultsTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "cache_faults_total"),
"(CacheFaultsPersec)",
"Number of faults which occur when a page sought in the file system cache is not found there and must be retrieved from elsewhere in memory (soft fault) "+
"or from disk (hard fault) (Cache Faults/sec)",
nil,
nil,
),
@@ -95,13 +98,14 @@ func NewMemoryCollector() (Collector, error) {
DemandZeroFaultsTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "demand_zero_faults_total"),
"The number of zeroed pages required to satisfy faults. Zeroed pages, pages emptied of previously stored data and filled with zeros, are a security"+
" feature of Windows that prevent processes from seeing data stored by earlier processes that used the memory space (DemandZeroFaults)",
" feature of Windows that prevent processes from seeing data stored by earlier processes that used the memory space (Demand Zero Faults/sec)",
nil,
nil,
),
FreeAndZeroPageListBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "free_and_zero_page_list_bytes"),
"(FreeAndZeroPageListBytes)",
"The amount of physical memory, in bytes, that is assigned to the free and zero page lists. This memory does not contain cached data. It is immediately"+
" available for allocation to a process or for system use (FreeAndZeroPageListBytes)",
nil,
nil,
),
@@ -113,13 +117,14 @@ func NewMemoryCollector() (Collector, error) {
),
ModifiedPageListBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "modified_page_list_bytes"),
"(ModifiedPageListBytes)",
"The amount of physical memory, in bytes, that is assigned to the modified page list. This memory contains cached data and code that is not actively in "+
"use by processes, the system and the system cache (ModifiedPageListBytes)",
nil,
nil,
),
PageFaultsTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "page_faults_total"),
"(PageFaultsPersec)",
"Overall rate at which faulted pages are handled by the processor (Page Faults/sec)",
nil,
nil,
),
@@ -161,14 +166,15 @@ func NewMemoryCollector() (Collector, error) {
nil,
),
PoolNonpagedBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "pool_nonpaged_bytes_total"),
"(PoolNonpagedBytes)",
prometheus.BuildFQName(Namespace, subsystem, "pool_nonpaged_bytes"),
"Number of bytes in the non-paged pool, an area of the system virtual memory that is used for objects that cannot be written to disk, but must "+
"remain in physical memory as long as they are allocated (PoolNonpagedBytes)",
nil,
nil,
),
PoolPagedAllocsTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "pool_paged_allocs_total"),
"(PoolPagedAllocs)",
"Number of calls to allocate space in the paged pool, regardless of the amount of space allocated in each call (PoolPagedAllocs)",
nil,
nil,
),
@@ -180,67 +186,72 @@ func NewMemoryCollector() (Collector, error) {
),
PoolPagedResidentBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "pool_paged_resident_bytes"),
"(PoolPagedResidentBytes)",
"The size, in bytes, of the portion of the paged pool that is currently resident and active in physical memory. The paged pool is an area of the "+
"system virtual memory that is used for objects that can be written to disk when they are not being used (PoolPagedResidentBytes)",
nil,
nil,
),
StandbyCacheCoreBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "standby_cache_core_bytes"),
"(StandbyCacheCoreBytes)",
"The amount of physical memory, in bytes, that is assigned to the core standby cache page lists. This memory contains cached data and code that is "+
"not actively in use by processes, the system and the system cache (StandbyCacheCoreBytes)",
nil,
nil,
),
StandbyCacheNormalPriorityBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "standby_cache_normal_priority_bytes"),
"(StandbyCacheNormalPriorityBytes)",
"The amount of physical memory, in bytes, that is assigned to the normal priority standby cache page lists. This memory contains cached data and "+
"code that is not actively in use by processes, the system and the system cache (StandbyCacheNormalPriorityBytes)",
nil,
nil,
),
StandbyCacheReserveBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "standby_cache_reserve_bytes"),
"(StandbyCacheReserveBytes)",
"The amount of physical memory, in bytes, that is assigned to the reserve standby cache page lists. This memory contains cached data and code "+
"that is not actively in use by processes, the system and the system cache (StandbyCacheReserveBytes)",
nil,
nil,
),
SystemCacheResidentBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "system_cache_resident_bytes"),
"(SystemCacheResidentBytes)",
"The size, in bytes, of the portion of the system file cache which is currently resident and active in physical memory (SystemCacheResidentBytes)",
nil,
nil,
),
SystemCodeResidentBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "system_code_resident_bytes"),
"(SystemCodeResidentBytes)",
"The size, in bytes, of the pageable operating system code that is currently resident and active in physical memory (SystemCodeResidentBytes)",
nil,
nil,
),
SystemCodeTotalBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "system_code_total_bytes"),
"(SystemCodeTotalBytes)",
"The size, in bytes, of the pageable operating system code currently mapped into the system virtual address space (SystemCodeTotalBytes)",
nil,
nil,
),
SystemDriverResidentBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "system_driver_resident_bytes"),
"(SystemDriverResidentBytes)",
"The size, in bytes, of the pageable physical memory being used by device drivers. It is the working set (physical memory area) of the drivers (SystemDriverResidentBytes)",
nil,
nil,
),
SystemDriverTotalBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "system_driver_total_bytes"),
"(SystemDriverTotalBytes)",
"The size, in bytes, of the pageable virtual memory currently being used by device drivers. Pageable memory can be written to disk when it is not being used (SystemDriverTotalBytes)",
nil,
nil,
),
TransitionFaultsTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "transition_faults_total"),
"(TransitionFaultsPersec)",
"Number of faults rate at which page faults are resolved by recovering pages that were being used by another process sharing the page, or were on the "+
"modified page list or the standby list, or were being written to disk at the time of the page fault (TransitionFaultsPersec)",
nil,
nil,
),
TransitionPagesRepurposedTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "transition_pages_repurposed_total"),
"(TransitionPagesRePurposedPersec)",
"Transition Pages RePurposed is the rate at which the number of transition cache pages were reused for a different purpose (TransitionPagesRePurposedPersec)",
nil,
nil,
),
@@ -257,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
@@ -302,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
}
@@ -326,7 +337,7 @@ func (c *MemoryCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metri
ch <- prometheus.MustNewConstMetric(
c.CacheFaultsTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].CacheFaultsPersec,
)
@@ -344,7 +355,7 @@ func (c *MemoryCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metri
ch <- prometheus.MustNewConstMetric(
c.DemandZeroFaultsTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].DemandZeroFaultsPersec,
)
@@ -368,37 +379,37 @@ func (c *MemoryCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metri
ch <- prometheus.MustNewConstMetric(
c.PageFaultsTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].PageFaultsPersec,
)
ch <- prometheus.MustNewConstMetric(
c.SwapPageReadsTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].PageReadsPersec,
)
ch <- prometheus.MustNewConstMetric(
c.SwapPagesReadTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].PagesInputPersec,
)
ch <- prometheus.MustNewConstMetric(
c.SwapPagesWrittenTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].PagesOutputPersec,
)
ch <- prometheus.MustNewConstMetric(
c.SwapPageOperationsTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].PagesPersec,
)
ch <- prometheus.MustNewConstMetric(
c.SwapPageWritesTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].PageWritesPersec,
)
@@ -416,7 +427,7 @@ func (c *MemoryCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metri
ch <- prometheus.MustNewConstMetric(
c.PoolPagedAllocsTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].PoolPagedAllocs,
)
@@ -482,19 +493,19 @@ func (c *MemoryCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metri
ch <- prometheus.MustNewConstMetric(
c.TransitionFaultsTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].TransitionFaultsPersec,
)
ch <- prometheus.MustNewConstMetric(
c.TransitionPagesRepurposedTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].TransitionPagesRePurposedPersec,
)
ch <- prometheus.MustNewConstMetric(
c.WriteCopiesTotal,
prometheus.GaugeValue,
prometheus.CounterValue,
dst[0].WriteCopiesPersec,
)

9
collector/memory_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkMemoryCollector(b *testing.B) {
benchmarkCollector(b, "memory", newMemoryCollector)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,117 @@
package collector
import (
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
// A MSCluster_NetworkCollector is a Prometheus collector for WMI MSCluster_Network metrics
type MSCluster_NetworkCollector struct {
logger log.Logger
Characteristics *prometheus.Desc
Flags *prometheus.Desc
Metric *prometheus.Desc
Role *prometheus.Desc
State *prometheus.Desc
}
func newMSCluster_NetworkCollector(logger log.Logger) (Collector, error) {
const subsystem = "mscluster_network"
return &MSCluster_NetworkCollector{
logger: log.With(logger, "collector", subsystem),
Characteristics: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
"Provides the characteristics of the network.",
[]string{"name"},
nil,
),
Flags: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "flags"),
"Provides access to the flags set for the node. ",
[]string{"name"},
nil,
),
Metric: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "metric"),
"The metric of a cluster network (networks with lower values are used first). If this value is set, then the AutoMetric property is set to false.",
[]string{"name"},
nil,
),
Role: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "role"),
"Provides access to the network's Role property. The Role property describes the role of the network in the cluster. 0: None; 1: Cluster; 2: Client; 3: Both ",
[]string{"name"},
nil,
),
State: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "state"),
"Provides the current state of the network. 1-1: Unknown; 0: Unavailable; 1: Down; 2: Partitioned; 3: Up",
[]string{"name"},
nil,
),
}, nil
}
// MSCluster_Network docs:
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-network
type MSCluster_Network struct {
Name string
Characteristics uint
Flags uint
Metric uint
Role uint
State uint
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *MSCluster_NetworkCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
var dst []MSCluster_Network
q := queryAll(&dst, c.logger)
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
return err
}
for _, v := range dst {
ch <- prometheus.MustNewConstMetric(
c.Characteristics,
prometheus.GaugeValue,
float64(v.Characteristics),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Flags,
prometheus.GaugeValue,
float64(v.Flags),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Metric,
prometheus.GaugeValue,
float64(v.Metric),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Role,
prometheus.GaugeValue,
float64(v.Role),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.State,
prometheus.GaugeValue,
float64(v.State),
v.Name,
)
}
return nil
}

252
collector/mscluster_node.go Normal file
View File

@@ -0,0 +1,252 @@
package collector
import (
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
// A MSCluster_NodeCollector is a Prometheus collector for WMI MSCluster_Node metrics
type MSCluster_NodeCollector struct {
logger log.Logger
BuildNumber *prometheus.Desc
Characteristics *prometheus.Desc
DetectedCloudPlatform *prometheus.Desc
DynamicWeight *prometheus.Desc
Flags *prometheus.Desc
MajorVersion *prometheus.Desc
MinorVersion *prometheus.Desc
NeedsPreventQuorum *prometheus.Desc
NodeDrainStatus *prometheus.Desc
NodeHighestVersion *prometheus.Desc
NodeLowestVersion *prometheus.Desc
NodeWeight *prometheus.Desc
State *prometheus.Desc
StatusInformation *prometheus.Desc
}
func newMSCluster_NodeCollector(logger log.Logger) (Collector, error) {
const subsystem = "mscluster_node"
return &MSCluster_NodeCollector{
logger: log.With(logger, "collector", subsystem),
BuildNumber: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "build_number"),
"Provides access to the node's BuildNumber property.",
[]string{"name"},
nil,
),
Characteristics: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
"Provides access to the characteristics set for the node.",
[]string{"name"},
nil,
),
DetectedCloudPlatform: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "detected_cloud_platform"),
"(DetectedCloudPlatform)",
[]string{"name"},
nil,
),
DynamicWeight: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "dynamic_weight"),
"The dynamic vote weight of the node adjusted by dynamic quorum feature.",
[]string{"name"},
nil,
),
Flags: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "flags"),
"Provides access to the flags set for the node.",
[]string{"name"},
nil,
),
MajorVersion: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "major_version"),
"Provides access to the node's MajorVersion property, which specifies the major portion of the Windows version installed.",
[]string{"name"},
nil,
),
MinorVersion: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "minor_version"),
"Provides access to the node's MinorVersion property, which specifies the minor portion of the Windows version installed.",
[]string{"name"},
nil,
),
NeedsPreventQuorum: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "needs_prevent_quorum"),
"Whether the cluster service on that node should be started with prevent quorum flag.",
[]string{"name"},
nil,
),
NodeDrainStatus: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "node_drain_status"),
"The current node drain status of a node. 0: Not Initiated; 1: In Progress; 2: Completed; 3: Failed",
[]string{"name"},
nil,
),
NodeHighestVersion: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "node_highest_version"),
"Provides access to the node's NodeHighestVersion property, which specifies the highest possible version of the cluster service with which the node can join or communicate.",
[]string{"name"},
nil,
),
NodeLowestVersion: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "node_lowest_version"),
"Provides access to the node's NodeLowestVersion property, which specifies the lowest possible version of the cluster service with which the node can join or communicate.",
[]string{"name"},
nil,
),
NodeWeight: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "node_weight"),
"The vote weight of the node.",
[]string{"name"},
nil,
),
State: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "state"),
"Returns the current state of a node. -1: Unknown; 0: Up; 1: Down; 2: Paused; 3: Joining",
[]string{"name"},
nil,
),
StatusInformation: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "status_information"),
"The isolation or quarantine status of the node.",
[]string{"name"},
nil,
),
}, nil
}
// MSCluster_Node docs:
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-node
type MSCluster_Node struct {
Name string
BuildNumber uint
Characteristics uint
DetectedCloudPlatform uint
DynamicWeight uint
Flags uint
MajorVersion uint
MinorVersion uint
NeedsPreventQuorum uint
NodeDrainStatus uint
NodeHighestVersion uint
NodeLowestVersion uint
NodeWeight uint
State uint
StatusInformation uint
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *MSCluster_NodeCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
var dst []MSCluster_Node
q := queryAll(&dst, c.logger)
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
return err
}
for _, v := range dst {
ch <- prometheus.MustNewConstMetric(
c.BuildNumber,
prometheus.GaugeValue,
float64(v.BuildNumber),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Characteristics,
prometheus.GaugeValue,
float64(v.Characteristics),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.DetectedCloudPlatform,
prometheus.GaugeValue,
float64(v.DetectedCloudPlatform),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.DynamicWeight,
prometheus.GaugeValue,
float64(v.DynamicWeight),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Flags,
prometheus.GaugeValue,
float64(v.Flags),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.MajorVersion,
prometheus.GaugeValue,
float64(v.MajorVersion),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.MinorVersion,
prometheus.GaugeValue,
float64(v.MinorVersion),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NeedsPreventQuorum,
prometheus.GaugeValue,
float64(v.NeedsPreventQuorum),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NodeDrainStatus,
prometheus.GaugeValue,
float64(v.NodeDrainStatus),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NodeHighestVersion,
prometheus.GaugeValue,
float64(v.NodeHighestVersion),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NodeLowestVersion,
prometheus.GaugeValue,
float64(v.NodeLowestVersion),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.NodeWeight,
prometheus.GaugeValue,
float64(v.NodeWeight),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.State,
prometheus.GaugeValue,
float64(v.State),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.StatusInformation,
prometheus.GaugeValue,
float64(v.StatusInformation),
v.Name,
)
}
return nil
}

View File

@@ -0,0 +1,284 @@
package collector
import (
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
// A MSCluster_ResourceCollector is a Prometheus collector for WMI MSCluster_Resource metrics
type MSCluster_ResourceCollector struct {
logger log.Logger
Characteristics *prometheus.Desc
DeadlockTimeout *prometheus.Desc
EmbeddedFailureAction *prometheus.Desc
Flags *prometheus.Desc
IsAlivePollInterval *prometheus.Desc
LooksAlivePollInterval *prometheus.Desc
MonitorProcessId *prometheus.Desc
PendingTimeout *prometheus.Desc
ResourceClass *prometheus.Desc
RestartAction *prometheus.Desc
RestartDelay *prometheus.Desc
RestartPeriod *prometheus.Desc
RestartThreshold *prometheus.Desc
RetryPeriodOnFailure *prometheus.Desc
State *prometheus.Desc
Subclass *prometheus.Desc
}
func newMSCluster_ResourceCollector(logger log.Logger) (Collector, error) {
const subsystem = "mscluster_resource"
return &MSCluster_ResourceCollector{
logger: log.With(logger, "collector", subsystem),
Characteristics: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
"Provides the characteristics of the object.",
[]string{"type", "owner_group", "name"},
nil,
),
DeadlockTimeout: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "deadlock_timeout"),
"Indicates the length of time to wait, in milliseconds, before declaring a deadlock in any call into a resource.",
[]string{"type", "owner_group", "name"},
nil,
),
EmbeddedFailureAction: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "embedded_failure_action"),
"The time, in milliseconds, that a resource should remain in a failed state before the Cluster service attempts to restart it.",
[]string{"type", "owner_group", "name"},
nil,
),
Flags: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "flags"),
"Provides access to the flags set for the object.",
[]string{"type", "owner_group", "name"},
nil,
),
IsAlivePollInterval: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "is_alive_poll_interval"),
"Provides access to the resource's IsAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it is operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the IsAlivePollInterval property for the resource type associated with the resource.",
[]string{"type", "owner_group", "name"},
nil,
),
LooksAlivePollInterval: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "looks_alive_poll_interval"),
"Provides access to the resource's LooksAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it appears operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the LooksAlivePollInterval property for the resource type associated with the resource.",
[]string{"type", "owner_group", "name"},
nil,
),
MonitorProcessId: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "monitor_process_id"),
"Provides the process ID of the resource host service that is currently hosting the resource.",
[]string{"type", "owner_group", "name"},
nil,
),
PendingTimeout: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "pending_timeout"),
"Provides access to the resource's PendingTimeout property. If a resource cannot be brought online or taken offline in the number of milliseconds specified by the PendingTimeout property, the resource is forcibly terminated.",
[]string{"type", "owner_group", "name"},
nil,
),
ResourceClass: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "resource_class"),
"Gets or sets the resource class of a resource. 0: Unknown; 1: Storage; 2: Network; 32768: Unknown ",
[]string{"type", "owner_group", "name"},
nil,
),
RestartAction: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "restart_action"),
"Provides access to the resource's RestartAction property, which is the action to be taken by the Cluster Service if the resource fails.",
[]string{"type", "owner_group", "name"},
nil,
),
RestartDelay: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "restart_delay"),
"Indicates the time delay before a failed resource is restarted.",
[]string{"type", "owner_group", "name"},
nil,
),
RestartPeriod: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "restart_period"),
"Provides access to the resource's RestartPeriod property, which is interval of time, in milliseconds, during which a specified number of restart attempts can be made on a nonresponsive resource.",
[]string{"type", "owner_group", "name"},
nil,
),
RestartThreshold: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "restart_threshold"),
"Provides access to the resource's RestartThreshold property which is the maximum number of restart attempts that can be made on a resource within an interval defined by the RestartPeriod property before the Cluster Service initiates the action specified by the RestartAction property.",
[]string{"type", "owner_group", "name"},
nil,
),
RetryPeriodOnFailure: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "retry_period_on_failure"),
"Provides access to the resource's RetryPeriodOnFailure property, which is the interval of time (in milliseconds) that a resource should remain in a failed state before the Cluster service attempts to restart it.",
[]string{"type", "owner_group", "name"},
nil,
),
State: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "state"),
"The current state of the resource. -1: Unknown; 0: Inherited; 1: Initializing; 2: Online; 3: Offline; 4: Failed; 128: Pending; 129: Online Pending; 130: Offline Pending ",
[]string{"type", "owner_group", "name"},
nil,
),
Subclass: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "subclass"),
"Provides the list of references to nodes that can be the owner of this resource.",
[]string{"type", "owner_group", "name"},
nil,
),
}, nil
}
// MSCluster_Resource docs:
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resource
type MSCluster_Resource struct {
Name string
Type string
OwnerGroup string
Characteristics uint
DeadlockTimeout uint
EmbeddedFailureAction uint
Flags uint
IsAlivePollInterval uint
LooksAlivePollInterval uint
MonitorProcessId uint
PendingTimeout uint
ResourceClass uint
RestartAction uint
RestartDelay uint
RestartPeriod uint
RestartThreshold uint
RetryPeriodOnFailure uint
State uint
Subclass uint
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *MSCluster_ResourceCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
var dst []MSCluster_Resource
q := queryAll(&dst, c.logger)
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
return err
}
for _, v := range dst {
ch <- prometheus.MustNewConstMetric(
c.Characteristics,
prometheus.GaugeValue,
float64(v.Characteristics),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.DeadlockTimeout,
prometheus.GaugeValue,
float64(v.DeadlockTimeout),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.EmbeddedFailureAction,
prometheus.GaugeValue,
float64(v.EmbeddedFailureAction),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Flags,
prometheus.GaugeValue,
float64(v.Flags),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.IsAlivePollInterval,
prometheus.GaugeValue,
float64(v.IsAlivePollInterval),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.LooksAlivePollInterval,
prometheus.GaugeValue,
float64(v.LooksAlivePollInterval),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.MonitorProcessId,
prometheus.GaugeValue,
float64(v.MonitorProcessId),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.PendingTimeout,
prometheus.GaugeValue,
float64(v.PendingTimeout),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.ResourceClass,
prometheus.GaugeValue,
float64(v.ResourceClass),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RestartAction,
prometheus.GaugeValue,
float64(v.RestartAction),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RestartDelay,
prometheus.GaugeValue,
float64(v.RestartDelay),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RestartPeriod,
prometheus.GaugeValue,
float64(v.RestartPeriod),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RestartThreshold,
prometheus.GaugeValue,
float64(v.RestartThreshold),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.RetryPeriodOnFailure,
prometheus.GaugeValue,
float64(v.RetryPeriodOnFailure),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.State,
prometheus.GaugeValue,
float64(v.State),
v.Type, v.OwnerGroup, v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Subclass,
prometheus.GaugeValue,
float64(v.Subclass),
v.Type, v.OwnerGroup, v.Name,
)
}
return nil
}

View File

@@ -0,0 +1,240 @@
package collector
import (
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
// A MSCluster_ResourceGroupCollector is a Prometheus collector for WMI MSCluster_ResourceGroup metrics
type MSCluster_ResourceGroupCollector struct {
logger log.Logger
AutoFailbackType *prometheus.Desc
Characteristics *prometheus.Desc
ColdStartSetting *prometheus.Desc
DefaultOwner *prometheus.Desc
FailbackWindowEnd *prometheus.Desc
FailbackWindowStart *prometheus.Desc
FailoverPeriod *prometheus.Desc
FailoverThreshold *prometheus.Desc
FaultDomain *prometheus.Desc
Flags *prometheus.Desc
GroupType *prometheus.Desc
PlacementOptions *prometheus.Desc
Priority *prometheus.Desc
ResiliencyPeriod *prometheus.Desc
State *prometheus.Desc
}
func newMSCluster_ResourceGroupCollector(logger log.Logger) (Collector, error) {
const subsystem = "mscluster_resourcegroup"
return &MSCluster_ResourceGroupCollector{
logger: log.With(logger, "collector", subsystem),
AutoFailbackType: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "auto_failback_type"),
"Provides access to the group's AutoFailbackType property.",
[]string{"name"},
nil,
),
Characteristics: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "characteristics"),
"Provides the characteristics of the group.",
[]string{"name"},
nil,
),
ColdStartSetting: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "cold_start_setting"),
"Indicates whether a group can start after a cluster cold start.",
[]string{"name"},
nil,
),
DefaultOwner: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "default_owner"),
"Number of the last node the resource group was activated on or explicitly moved to.",
[]string{"name"},
nil,
),
FailbackWindowEnd: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "failback_window_end"),
"The FailbackWindowEnd property provides the latest time that the group can be moved back to the node identified as its preferred node.",
[]string{"name"},
nil,
),
FailbackWindowStart: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "failback_window_start"),
"The FailbackWindowStart property provides the earliest time (that is, local time as kept by the cluster) that the group can be moved back to the node identified as its preferred node.",
[]string{"name"},
nil,
),
FailoverPeriod: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "failover_period"),
"The FailoverPeriod property specifies a number of hours during which a maximum number of failover attempts, specified by the FailoverThreshold property, can occur.",
[]string{"name"},
nil,
),
FailoverThreshold: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "failover_threshold"),
"The FailoverThreshold property specifies the maximum number of failover attempts.",
[]string{"name"},
nil,
),
Flags: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "flags"),
"Provides access to the flags set for the group. ",
[]string{"name"},
nil,
),
GroupType: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "group_type"),
"The Type of the resource group.",
[]string{"name"},
nil,
),
Priority: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "priority"),
"Priority value of the resource group",
[]string{"name"},
nil,
),
ResiliencyPeriod: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "resiliency_period"),
"The resiliency period for this group, in seconds.",
[]string{"name"},
nil,
),
State: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "state"),
"The current state of the resource group. -1: Unknown; 0: Online; 1: Offline; 2: Failed; 3: Partial Online; 4: Pending",
[]string{"name"},
nil,
),
}, nil
}
// MSCluster_ResourceGroup docs:
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resourcegroup
type MSCluster_ResourceGroup struct {
Name string
AutoFailbackType uint
Characteristics uint
ColdStartSetting uint
DefaultOwner uint
FailbackWindowEnd int
FailbackWindowStart int
FailoverPeriod uint
FailoverThreshold uint
Flags uint
GroupType uint
Priority uint
ResiliencyPeriod uint
State uint
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *MSCluster_ResourceGroupCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
var dst []MSCluster_ResourceGroup
q := queryAll(&dst, c.logger)
if err := wmi.QueryNamespace(q, &dst, "root/MSCluster"); err != nil {
return err
}
for _, v := range dst {
ch <- prometheus.MustNewConstMetric(
c.AutoFailbackType,
prometheus.GaugeValue,
float64(v.AutoFailbackType),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Characteristics,
prometheus.GaugeValue,
float64(v.Characteristics),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.ColdStartSetting,
prometheus.GaugeValue,
float64(v.ColdStartSetting),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.DefaultOwner,
prometheus.GaugeValue,
float64(v.DefaultOwner),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.FailbackWindowEnd,
prometheus.GaugeValue,
float64(v.FailbackWindowEnd),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.FailbackWindowStart,
prometheus.GaugeValue,
float64(v.FailbackWindowStart),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.FailoverPeriod,
prometheus.GaugeValue,
float64(v.FailoverPeriod),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.FailoverThreshold,
prometheus.GaugeValue,
float64(v.FailoverThreshold),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Flags,
prometheus.GaugeValue,
float64(v.Flags),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.GroupType,
prometheus.GaugeValue,
float64(v.GroupType),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.Priority,
prometheus.GaugeValue,
float64(v.Priority),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.ResiliencyPeriod,
prometheus.GaugeValue,
float64(v.ResiliencyPeriod),
v.Name,
)
ch <- prometheus.MustNewConstMetric(
c.State,
prometheus.GaugeValue,
float64(v.State),
v.Name,
)
}
return nil
}

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package collector
@@ -5,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
@@ -29,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",
@@ -70,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
@@ -87,35 +99,33 @@ 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
}
for _, msmq := range dst {
if msmq.Name == "Computer Queues" {
continue
}
ch <- prometheus.MustNewConstMetric(
c.BytesinJournalQueue,
prometheus.GaugeValue,
float64(msmq.BytesinJournalQueue),
strings.ToLower(msmq.Name),
)
ch <- prometheus.MustNewConstMetric(
c.BytesinQueue,
prometheus.GaugeValue,
float64(msmq.BytesinQueue),
strings.ToLower(msmq.Name),
)
ch <- prometheus.MustNewConstMetric(
c.MessagesinJournalQueue,
prometheus.GaugeValue,
float64(msmq.MessagesinJournalQueue),
strings.ToLower(msmq.Name),
)
ch <- prometheus.MustNewConstMetric(
c.MessagesinQueue,
prometheus.GaugeValue,

10
collector/msmq_test.go Normal file
View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkMsmqCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newMSMQCollector)
}

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package collector
@@ -10,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
@@ -40,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
}
@@ -62,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
}
@@ -70,7 +71,7 @@ func getMSSQLInstances() mssqlInstancesType {
type mssqlCollectorsMap map[string]mssqlCollectorFunc
func mssqlAvailableClassCollectors() string {
return "accessmethods,availreplica,bufman,databases,dbreplica,genstats,locks,memmgr,sqlstats,sqlerrors,transactions"
return "accessmethods,availreplica,bufman,databases,dbreplica,genstats,locks,memmgr,sqlstats,sqlerrors,transactions,waitstats"
}
func (c *MSSQLCollector) getMSSQLCollectors() mssqlCollectorsMap {
@@ -86,6 +87,7 @@ func (c *MSSQLCollector) getMSSQLCollectors() mssqlCollectorsMap {
mssqlCollectors["sqlstats"] = c.collectSQLStats
mssqlCollectors["sqlerrors"] = c.collectSQLErrors
mssqlCollectors["transactions"] = c.collectTransactions
mssqlCollectors["waitstats"] = c.collectWaitStats
return mssqlCollectors
}
@@ -121,16 +123,16 @@ func mssqlGetPerfObjectName(sqlInstance string, collector string) string {
suffix = "SQL Statistics"
case "transactions":
suffix = "Transactions"
case "waitstats":
suffix = "Wait Statistics"
}
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
@@ -382,18 +384,45 @@ type MSSQLCollector struct {
TransactionsVersionStoreCreationUnits *prometheus.Desc
TransactionsVersionStoreTruncationUnits *prometheus.Desc
// Win32_PerfRawData_{instance}_SQLServerWaitStatistics
WaitStatsLockWaits *prometheus.Desc
WaitStatsMemoryGrantQueueWaits *prometheus.Desc
WaitStatsThreadSafeMemoryObjectsWaits *prometheus.Desc
WaitStatsLogWriteWaits *prometheus.Desc
WaitStatsLogBufferWaits *prometheus.Desc
WaitStatsNetworkIOWaits *prometheus.Desc
WaitStatsPageIOLatchWaits *prometheus.Desc
WaitStatsPageLatchWaits *prometheus.Desc
WaitStatsNonpageLatchWaits *prometheus.Desc
WaitStatsWaitForTheWorkerWaits *prometheus.Desc
WaitStatsWorkspaceSynchronizationWaits *prometheus.Desc
WaitStatsTransactionOwnershipWaits *prometheus.Desc
mssqlInstances mssqlInstancesType
mssqlCollectors mssqlCollectorsMap
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 {
@@ -403,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"),
@@ -1789,6 +1819,91 @@ func NewMSSQLCollector() (Collector, error) {
nil,
),
// Win32_PerfRawData_{instance}_SQLServerWaitStatistics
WaitStatsLockWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_lock_waits"),
"(WaitStats.LockWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsMemoryGrantQueueWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_memory_grant_queue_waits"),
"(WaitStats.MemoryGrantQueueWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsThreadSafeMemoryObjectsWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_thread_safe_memory_objects_waits"),
"(WaitStats.ThreadSafeMemoryObjectsWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsLogWriteWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_log_write_waits"),
"(WaitStats.LogWriteWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsLogBufferWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_log_buffer_waits"),
"(WaitStats.LogBufferWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsNetworkIOWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_network_io_waits"),
"(WaitStats.NetworkIOWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsPageIOLatchWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_page_io_latch_waits"),
"(WaitStats.PageIOLatchWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsPageLatchWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_page_latch_waits"),
"(WaitStats.PageLatchWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsNonpageLatchWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_nonpage_latch_waits"),
"(WaitStats.NonpageLatchWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsWaitForTheWorkerWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_wait_for_the_worker_waits"),
"(WaitStats.WaitForTheWorkerWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsWorkspaceSynchronizationWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_workspace_synchronization_waits"),
"(WaitStats.WorkspaceSynchronizationWaits)",
[]string{"mssql_instance", "item"},
nil,
),
WaitStatsTransactionOwnershipWaits: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "waitstats_transaction_ownership_waits"),
"(WaitStats.TransactionOwnershipWaits)",
[]string{"mssql_instance", "item"},
nil,
),
mssqlInstances: mssqlInstances,
}
@@ -1818,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(
@@ -1855,7 +1970,7 @@ func (c *MSSQLCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric
}
wg.Wait()
// this shoud return an error if any? some? children errord.
// this should return an error if any? some? children errord.
if c.mssqlChildCollectorFailure > 0 {
return errors.New("at least one child collector failed")
}
@@ -1913,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
}
@@ -2248,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
}
@@ -2356,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
}
@@ -2560,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
}
@@ -2799,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
}
@@ -3181,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
}
@@ -3376,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
}
@@ -3474,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
}
@@ -3643,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
}
@@ -3731,6 +3846,123 @@ func (c *MSSQLCollector) collectSQLStats(ctx *ScrapeContext, ch chan<- prometheu
return nil, nil
}
// Win32_PerfRawData_MSSQLSERVER_SQLServerWaitStatistics docs:
// - https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-wait-statistics-object
type mssqlWaitStatistics struct {
Name string
WaitStatsLockWaits float64 `perflib:"Lock waits"`
WaitStatsMemoryGrantQueueWaits float64 `perflib:"Memory grant queue waits"`
WaitStatsThreadSafeMemoryObjectsWaits float64 `perflib:"Thread-safe memory objects waits"`
WaitStatsLogWriteWaits float64 `perflib:"Log write waits"`
WaitStatsLogBufferWaits float64 `perflib:"Log buffer waits"`
WaitStatsNetworkIOWaits float64 `perflib:"Network IO waits"`
WaitStatsPageIOLatchWaits float64 `perflib:"Page IO latch waits"`
WaitStatsPageLatchWaits float64 `perflib:"Page latch waits"`
WaitStatsNonpageLatchWaits float64 `perflib:"Non-Page latch waits"`
WaitStatsWaitForTheWorkerWaits float64 `perflib:"Wait for the worker"`
WaitStatsWorkspaceSynchronizationWaits float64 `perflib:"Workspace synchronization waits"`
WaitStatsTransactionOwnershipWaits float64 `perflib:"Transaction ownership waits"`
}
func (c *MSSQLCollector) collectWaitStats(ctx *ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
var dst []mssqlWaitStatistics
_ = 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, c.logger); err != nil {
return nil, err
}
for _, v := range dst {
item := v.Name
ch <- prometheus.MustNewConstMetric(
c.WaitStatsLockWaits,
prometheus.CounterValue,
v.WaitStatsLockWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsMemoryGrantQueueWaits,
prometheus.CounterValue,
v.WaitStatsMemoryGrantQueueWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsThreadSafeMemoryObjectsWaits,
prometheus.CounterValue,
v.WaitStatsThreadSafeMemoryObjectsWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsLogWriteWaits,
prometheus.CounterValue,
v.WaitStatsLogWriteWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsLogBufferWaits,
prometheus.CounterValue,
v.WaitStatsLogBufferWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsNetworkIOWaits,
prometheus.CounterValue,
v.WaitStatsNetworkIOWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsPageIOLatchWaits,
prometheus.CounterValue,
v.WaitStatsPageIOLatchWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsPageLatchWaits,
prometheus.CounterValue,
v.WaitStatsPageLatchWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsNonpageLatchWaits,
prometheus.CounterValue,
v.WaitStatsNonpageLatchWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsWaitForTheWorkerWaits,
prometheus.CounterValue,
v.WaitStatsWaitForTheWorkerWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsWorkspaceSynchronizationWaits,
prometheus.CounterValue,
v.WaitStatsWorkspaceSynchronizationWaits,
sqlInstance, item,
)
ch <- prometheus.MustNewConstMetric(
c.WaitStatsTransactionOwnershipWaits,
prometheus.CounterValue,
v.WaitStatsTransactionOwnershipWaits,
sqlInstance, item,
)
}
return nil, nil
}
type mssqlSQLErrors struct {
Name string
ErrorsPersec float64 `perflib:"Errors/sec"`
@@ -3740,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
}
@@ -3783,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
}

9
collector/mssql_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkMSSQLCollector(b *testing.B) {
benchmarkCollector(b, "mssql", newMSSQLCollector)
}

View File

@@ -1,37 +1,48 @@
//go:build windows
// +build windows
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
@@ -42,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)",
@@ -69,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)",
@@ -118,14 +183,14 @@ func NewNetworkCollector() (Collector, error) {
nil,
),
CurrentBandwidth: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "current_bandwidth"),
prometheus.BuildFQName(Namespace, subsystem, "current_bandwidth_bytes"),
"(Network.CurrentBandwidth)",
[]string{"nic"},
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
}
@@ -133,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
@@ -152,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"`
@@ -166,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
}
@@ -200,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,
@@ -251,7 +323,7 @@ func (c *NetworkCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
ch <- prometheus.MustNewConstMetric(
c.CurrentBandwidth,
prometheus.GaugeValue,
nic.CurrentBandwidth,
nic.CurrentBandwidth/8,
name,
)
}

View File

@@ -1,8 +1,11 @@
//go:build windows
// +build windows
package collector
import "testing"
import (
"testing"
)
func TestNetworkToInstanceName(t *testing.T) {
data := map[string]string{
@@ -15,3 +18,10 @@ func TestNetworkToInstanceName(t *testing.T) {
}
}
}
func BenchmarkNetCollector(b *testing.B) {
// 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)
}

View File

@@ -1,29 +1,31 @@
//go:build windows
// +build windows
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.",
@@ -55,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
@@ -73,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
}

View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkNetFrameworkNETCLRExceptionsCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newNETFramework_NETCLRExceptionsCollector)
}

View File

@@ -1,28 +1,29 @@
//go:build windows
// +build windows
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.",
@@ -48,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
@@ -66,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
}

View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkNETFrameworkNETCLRInteropCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newNETFramework_NETCLRInteropCollector)
}

View File

@@ -1,29 +1,30 @@
//go:build windows
// +build windows
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.",
@@ -55,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
@@ -75,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
}

View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkNETFrameworkNETCLRJitCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newNETFramework_NETCLRJitCollector)
}

View File

@@ -1,19 +1,19 @@
//go:build windows
// +build windows
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
@@ -25,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.",
@@ -90,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
@@ -119,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
}

View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkNETFrameworkNETCLRLoadingCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newNETFramework_NETCLRLoadingCollector)
}

View File

@@ -1,19 +1,19 @@
//go:build windows
// +build windows
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
@@ -23,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.",
@@ -76,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
@@ -99,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
}

View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkNETFrameworkNETCLRLocksAndThreadsCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newNETFramework_NETCLRLocksAndThreadsCollector)
}

View File

@@ -1,19 +1,19 @@
//go:build windows
// +build windows
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
@@ -31,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.",
@@ -114,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
@@ -123,26 +124,31 @@ func (c *NETFramework_NETCLRMemoryCollector) Collect(ctx *ScrapeContext, ch chan
type Win32_PerfRawData_NETFramework_NETCLRMemory struct {
Name string
AllocatedBytesPersec uint64
FinalizationSurvivors uint64
Frequency_PerfTime uint64
Gen0heapsize uint64
Gen0PromotedBytesPerSec uint64
Gen1heapsize uint64
Gen1PromotedBytesPerSec uint64
Gen2heapsize uint64
LargeObjectHeapsize uint64
NumberBytesinallHeaps uint64
NumberGCHandles uint64
NumberGen0Collections uint64
NumberGen1Collections uint64
NumberGen2Collections uint64
NumberInducedGC uint64
NumberofPinnedObjects uint64
NumberofSinkBlocksinuse uint64
NumberTotalcommittedBytes uint64
NumberTotalreservedBytes uint64
PercentTimeinGC uint32
AllocatedBytesPersec uint64
FinalizationSurvivors uint64
Frequency_PerfTime uint64
Gen0heapsize uint64
Gen0PromotedBytesPerSec uint64
Gen1heapsize uint64
Gen1PromotedBytesPerSec uint64
Gen2heapsize uint64
LargeObjectHeapsize uint64
NumberBytesinallHeaps uint64
NumberGCHandles uint64
NumberGen0Collections uint64
NumberGen1Collections uint64
NumberGen2Collections uint64
NumberInducedGC uint64
NumberofPinnedObjects uint64
NumberofSinkBlocksinuse uint64
NumberTotalcommittedBytes uint64
NumberTotalreservedBytes uint64
// PercentTimeinGC has countertype=PERF_RAW_FRACTION.
// Formula: (100 * CounterValue) / BaseValue
// By docs https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/scripting-articles/ms974615(v=msdn.10)#perf_raw_fraction
PercentTimeinGC uint32
// BaseValue is just a "magic" number used to make the calculation come out right.
PercentTimeinGC_base uint32
ProcessID uint64
PromotedFinalizationMemoryfromGen0 uint64
PromotedMemoryfromGen0 uint64
@@ -151,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
}
@@ -293,7 +299,7 @@ func (c *NETFramework_NETCLRMemoryCollector) collect(ch chan<- prometheus.Metric
ch <- prometheus.MustNewConstMetric(
c.TimeinGC,
prometheus.GaugeValue,
float64(process.PercentTimeinGC)/float64(process.Frequency_PerfTime),
float64(100*process.PercentTimeinGC)/float64(process.PercentTimeinGC_base),
process.Name,
)
}

View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkNETFrameworkNETCLRMemoryCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newNETFramework_NETCLRMemoryCollector)
}

View File

@@ -1,19 +1,19 @@
//go:build windows
// +build windows
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
@@ -22,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.",
@@ -69,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
@@ -89,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
}

View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkNETFrameworkNETCLRRemotingCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newNETFramework_NETCLRRemotingCollector)
}

View File

@@ -1,29 +1,30 @@
//go:build windows
// +build windows
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.",
@@ -55,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
@@ -74,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
}

View File

@@ -0,0 +1,10 @@
package collector
import (
"testing"
)
func BenchmarkNETFrameworkNETCLRSecurityCollector(b *testing.B) {
// No context name required as collector source is WMI
benchmarkCollector(b, "", newNETFramework_NETCLRSecurityCollector)
}

425
collector/nps.go Normal file
View 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
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkNPSCollector(b *testing.B) {
benchmarkCollector(b, "nps", newNPSCollector)
}

View File

@@ -1,22 +1,27 @@
//go:build windows
// +build windows
package collector
import (
"errors"
"fmt"
"os"
"strings"
"time"
"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-community/windows_exporter/headers/netapi32"
"github.com/prometheus-community/windows_exporter/headers/psapi"
"github.com/prometheus-community/windows_exporter/headers/sysinfoapi"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/windows/registry"
)
func init() {
registerCollector("os", NewOSCollector)
}
// A OSCollector is a Prometheus collector for WMI metrics
type OSCollector struct {
logger log.Logger
OSInformation *prometheus.Desc
PhysicalMemoryFreeBytes *prometheus.Desc
PagingFreeBytes *prometheus.Desc
@@ -32,15 +37,23 @@ type OSCollector struct {
Timezone *prometheus.Desc
}
// NewOSCollector ...
func NewOSCollector() (Collector, error) {
type pagingFileCounter struct {
Name string
Usage float64 `perflib:"% Usage"`
UsagePeak float64 `perflib:"% Usage Peak"`
}
// 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",
[]string{"product", "version"},
[]string{"product", "version", "major_version", "minor_version", "build_number"},
nil,
),
PagingLimitBytes: prometheus.NewDesc(
@@ -86,7 +99,7 @@ func NewOSCollector() (Collector, error) {
nil,
),
ProcessMemoryLimitBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "process_memory_limix_bytes"),
prometheus.BuildFQName(Namespace, subsystem, "process_memory_limit_bytes"),
"OperatingSystem.MaxProcessMemorySize",
nil,
nil,
@@ -121,8 +134,8 @@ func NewOSCollector() (Collector, error) {
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *OSCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Error("failed collecting os metrics:", desc, err)
if desc, err := c.collect(ctx, ch); err != nil {
_ = level.Error(c.logger).Log("failed collecting os metrics", "desc", desc, "err", err)
return err
}
return nil
@@ -146,41 +159,103 @@ type Win32_OperatingSystem struct {
Version string
}
func (c *OSCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
var dst []Win32_OperatingSystem
q := queryAll(&dst)
if err := wmi.Query(q, &dst); err != nil {
func (c *OSCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
nwgi, err := netapi32.GetWorkstationInfo()
if err != nil {
return nil, err
}
if len(dst) == 0 {
return nil, errors.New("WMI query returned empty result set")
gmse, err := sysinfoapi.GlobalMemoryStatusEx()
if err != nil {
return nil, err
}
currentTime := time.Now()
timezoneName, _ := currentTime.Zone()
// Get total allocation of paging files across all disks.
memManKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`, registry.QUERY_VALUE)
defer memManKey.Close()
if err != nil {
return nil, err
}
pagingFiles, _, pagingErr := memManKey.GetStringsValue("ExistingPageFiles")
// Get build number and product name from registry
ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
defer ntKey.Close()
if err != nil {
return nil, err
}
pn, _, err := ntKey.GetStringValue("ProductName")
if err != nil {
return nil, err
}
bn, _, err := ntKey.GetStringValue("CurrentBuildNumber")
if err != nil {
return nil, err
}
var fsipf float64
for _, pagingFile := range pagingFiles {
fileString := strings.ReplaceAll(pagingFile, `\??\`, "")
file, err := os.Stat(fileString)
// For unknown reasons, Windows doesn't always create a page file. Continue collection rather than aborting.
if err != nil {
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("Failed to read page file (reason: %s): %s\n", err, fileString))
} else {
fsipf += float64(file.Size())
}
}
gpi, err := psapi.GetPerformanceInfo()
if err != nil {
return nil, err
}
var pfc = make([]pagingFileCounter, 0)
if err := unmarshalObject(ctx.perfObjects["Paging File"], &pfc, c.logger); err != nil {
return nil, err
}
// Get current page file usage.
var pfbRaw float64
for _, pageFile := range pfc {
if strings.Contains(strings.ToLower(pageFile.Name), "_total") {
continue
}
pfbRaw += pageFile.Usage
}
// Subtract from total page file allocation on disk.
pfb := fsipf - (pfbRaw * float64(gpi.PageSize))
ch <- prometheus.MustNewConstMetric(
c.OSInformation,
prometheus.GaugeValue,
1.0,
dst[0].Caption,
dst[0].Version,
fmt.Sprintf("Microsoft %s", pn), // Caption
fmt.Sprintf("%d.%d.%s", nwgi.VersionMajor, nwgi.VersionMinor, bn), // Version
fmt.Sprintf("%d", nwgi.VersionMajor), // Major Version
fmt.Sprintf("%d", nwgi.VersionMinor), // Minor Version
bn, // Build number
)
ch <- prometheus.MustNewConstMetric(
c.PhysicalMemoryFreeBytes,
prometheus.GaugeValue,
float64(dst[0].FreePhysicalMemory*1024), // KiB -> bytes
float64(gmse.AvailPhys),
)
time := dst[0].LocalDateTime
ch <- prometheus.MustNewConstMetric(
c.Time,
prometheus.GaugeValue,
float64(time.Unix()),
float64(currentTime.Unix()),
)
timezoneName, _ := time.Zone()
ch <- prometheus.MustNewConstMetric(
c.Timezone,
prometheus.GaugeValue,
@@ -188,58 +263,64 @@ func (c *OSCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, er
timezoneName,
)
ch <- prometheus.MustNewConstMetric(
c.PagingFreeBytes,
prometheus.GaugeValue,
float64(dst[0].FreeSpaceInPagingFiles*1024), // KiB -> bytes
)
if pagingErr == nil {
ch <- prometheus.MustNewConstMetric(
c.PagingFreeBytes,
prometheus.GaugeValue,
pfb,
)
ch <- prometheus.MustNewConstMetric(
c.PagingLimitBytes,
prometheus.GaugeValue,
fsipf,
)
} else {
_ = 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,
prometheus.GaugeValue,
float64(dst[0].FreeVirtualMemory*1024), // KiB -> bytes
float64(gmse.AvailPageFile),
)
// Windows has no defined limit, and is based off available resources. This currently isn't calculated by WMI and is set to default value.
// https://techcommunity.microsoft.com/t5/windows-blog-archive/pushing-the-limits-of-windows-processes-and-threads/ba-p/723824
// https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-operatingsystem
ch <- prometheus.MustNewConstMetric(
c.ProcessesLimit,
prometheus.GaugeValue,
float64(dst[0].MaxNumberOfProcesses),
float64(4294967295),
)
ch <- prometheus.MustNewConstMetric(
c.ProcessMemoryLimitBytes,
prometheus.GaugeValue,
float64(dst[0].MaxProcessMemorySize*1024), // KiB -> bytes
float64(gmse.TotalVirtual),
)
ch <- prometheus.MustNewConstMetric(
c.Processes,
prometheus.GaugeValue,
float64(dst[0].NumberOfProcesses),
float64(gpi.ProcessCount),
)
ch <- prometheus.MustNewConstMetric(
c.Users,
prometheus.GaugeValue,
float64(dst[0].NumberOfUsers),
)
ch <- prometheus.MustNewConstMetric(
c.PagingLimitBytes,
prometheus.GaugeValue,
float64(dst[0].SizeStoredInPagingFiles*1024), // KiB -> bytes
float64(nwgi.LoggedOnUsers),
)
ch <- prometheus.MustNewConstMetric(
c.VirtualMemoryBytes,
prometheus.GaugeValue,
float64(dst[0].TotalVirtualMemorySize*1024), // KiB -> bytes
float64(gmse.TotalPageFile),
)
ch <- prometheus.MustNewConstMetric(
c.VisibleMemoryBytes,
prometheus.GaugeValue,
float64(dst[0].TotalVisibleMemorySize*1024), // KiB -> bytes
float64(gmse.TotalPhys),
)
return nil, nil

9
collector/os_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkOSCollector(b *testing.B) {
benchmarkCollector(b, "os", newOSCollector)
}

View File

@@ -4,16 +4,16 @@ import (
"fmt"
"reflect"
"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) {
@@ -29,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")
}
@@ -67,10 +67,20 @@ func unmarshalObject(obj *perflib.PerfObject, vs interface{}) error {
if tag == "" {
continue
}
secondValue := false
st := strings.Split(tag, ",")
tag = st[0]
for _, t := range st {
if t == "secondvalue" {
secondValue = true
}
}
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() {
@@ -80,10 +90,18 @@ func unmarshalObject(obj *perflib.PerfObject, vs interface{}) error {
return fmt.Errorf("tagged field %v has wrong type %v, must be float64", f.Name, fieldType)
}
if secondValue {
if !ctr.Def.HasSecondValue {
return fmt.Errorf("tagged field %v expected a SecondValue, which was not present", f.Name)
}
target.Field(i).SetFloat(float64(ctr.SecondValue))
continue
}
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))

View File

@@ -4,13 +4,15 @@ 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 {
ValA float64 `perflib:"Something"`
ValB float64 `perflib:"Something Else"`
ValC float64 `perflib:"Something Else,secondvalue"`
}
func TestUnmarshalPerflib(t *testing.T) {
@@ -36,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,
},
@@ -56,22 +58,24 @@ 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,
Name: "Something Else",
CounterType: perflib.PERF_COUNTER_COUNTER,
HasSecondValue: true,
},
Value: 256,
Value: 256,
SecondValue: 222,
},
},
},
},
},
expectedOutput: []simple{{ValA: 123, ValB: 256}},
expectedOutput: []simple{{ValA: 123, ValB: 256, ValC: 222}},
expectError: false,
},
{
@@ -83,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,
},
@@ -94,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,
},
@@ -109,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)
}

View File

@@ -1,35 +1,44 @@
//go:build windows
// +build windows
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
@@ -42,21 +51,70 @@ type processCollector struct {
PrivateBytes *prometheus.Desc
ThreadCount *prometheus.Desc
VirtualBytes *prometheus.Desc
WorkingSetPrivate *prometheus.Desc
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.",
@@ -65,43 +123,43 @@ func newProcessCollector() (Collector, error) {
),
CPUTimeTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "cpu_time_total"),
"Returns elapsed time that all of the threads of this process used the processor to execute instructions by mode (privileged, user). An instruction is the basic unit of execution in a computer, a thread is the object that executes instructions, and a process is the object created when a program is run. Code executed to handle some hardware interrupts and trap conditions is included in this count.",
"Returns elapsed time that all of the threads of this process used the processor to execute instructions by mode (privileged, user).",
[]string{"process", "process_id", "creating_process_id", "mode"},
nil,
),
HandleCount: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "handle_count"),
prometheus.BuildFQName(Namespace, subsystem, "handles"),
"Total number of handles the process has open. This number is the sum of the handles currently open by each thread in the process.",
[]string{"process", "process_id", "creating_process_id"},
nil,
),
IOBytesTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "io_bytes_total"),
"Bytes issued to I/O operations in different modes (read, write, other). This property counts all I/O activity generated by the process to include file, network, and device I/Os. Read and write mode includes data operations; other mode includes those that do not involve data, such as control operations. ",
"Bytes issued to I/O operations in different modes (read, write, other).",
[]string{"process", "process_id", "creating_process_id", "mode"},
nil,
),
IOOperationsTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "io_operations_total"),
"I/O operations issued in different modes (read, write, other). This property counts all I/O activity generated by the process to include file, network, and device I/Os. Read and write mode includes data operations; other mode includes those that do not involve data, such as control operations. ",
"I/O operations issued in different modes (read, write, other).",
[]string{"process", "process_id", "creating_process_id", "mode"},
nil,
),
PageFaultsTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "page_faults_total"),
"Page faults by the threads executing in this process. A page fault occurs when a thread refers to a virtual memory page that is not in its working set in main memory. This can cause the page not to be fetched from disk if it is on the standby list and hence already in main memory, or if it is in use by another process with which the page is shared.",
"Page faults by the threads executing in this process.",
[]string{"process", "process_id", "creating_process_id"},
nil,
),
PageFileBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "page_file_bytes"),
"Current number of bytes this process has used in the paging file(s). Paging files are used to store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes, and lack of space in paging files can prevent other processes from allocating memory.",
"Current number of bytes this process has used in the paging file(s).",
[]string{"process", "process_id", "creating_process_id"},
nil,
),
PoolBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "pool_bytes"),
"Pool Bytes is the last observed number of bytes in the paged or nonpaged pool. The nonpaged pool is an area of system memory (physical memory used by the operating system) for objects that cannot be written to disk, but must remain in physical memory as long as they are allocated. The paged pool is an area of system memory (physical memory used by the operating system) for objects that can be written to disk when they are not being used. Nonpaged pool bytes is calculated differently than paged pool bytes, so it might not equal the total of paged pool bytes.",
"Pool Bytes is the last observed number of bytes in the paged or nonpaged pool.",
[]string{"process", "process_id", "creating_process_id", "pool"},
nil,
),
@@ -118,25 +176,37 @@ func newProcessCollector() (Collector, error) {
nil,
),
ThreadCount: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "thread_count"),
"Number of threads currently active in this process. An instruction is the basic unit of execution in a processor, and a thread is the object that executes instructions. Every running process has at least one thread.",
prometheus.BuildFQName(Namespace, subsystem, "threads"),
"Number of threads currently active in this process.",
[]string{"process", "process_id", "creating_process_id"},
nil,
),
VirtualBytes: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "virtual_bytes"),
"Current size, in bytes, of the virtual address space that the process is using. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is finite and, by using too much, the process can limit its ability to load libraries.",
"Current size, in bytes, of the virtual address space that the process is using.",
[]string{"process", "process_id", "creating_process_id"},
nil,
),
WorkingSetPrivate: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "working_set_private_bytes"),
"Size of the working set, in bytes, that is use for this process only and not shared nor shareable by other processes.",
[]string{"process", "process_id", "creating_process_id"},
nil,
),
WorkingSetPeak: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "working_set_peak_bytes"),
"Maximum size, in bytes, of the Working Set of this process at any point in time. The Working Set is the set of memory pages touched recently by the threads in the process.",
[]string{"process", "process_id", "creating_process_id"},
nil,
),
WorkingSet: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "working_set"),
"Maximum number of bytes in the working set of this process at any point in time. The working set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the working set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from working sets. If they are needed, they are then soft-faulted back into the working set before they leave main memory.",
prometheus.BuildFQName(Namespace, subsystem, "working_set_bytes"),
"Maximum number of bytes in the working set of this process at any point in time. The working set is the set of memory pages touched recently by the threads in the process.",
[]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
}
@@ -179,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.
@@ -380,6 +450,24 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
cpid,
)
ch <- prometheus.MustNewConstMetric(
c.WorkingSetPrivate,
prometheus.GaugeValue,
process.WorkingSetPrivate,
processName,
pid,
cpid,
)
ch <- prometheus.MustNewConstMetric(
c.WorkingSetPeak,
prometheus.GaugeValue,
process.WorkingSetPeak,
processName,
pid,
cpid,
)
ch <- prometheus.MustNewConstMetric(
c.WorkingSet,
prometheus.GaugeValue,

14
collector/process_test.go Normal file
View File

@@ -0,0 +1,14 @@
package collector
import (
"testing"
)
func BenchmarkProcessCollector(b *testing.B) {
// Include is not set in testing context (kingpin flags not parsed), causing the collector to skip all processes.
localProcessInclude := ".+"
processInclude = &localProcessInclude
// No context name required as collector source is WMI
benchmarkCollector(b, "", newProcessCollector)
}

193
collector/prometheus.go Normal file
View 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
}

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package collector
@@ -5,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
@@ -41,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"),
@@ -60,7 +62,7 @@ func NewRemoteFx() (Collector, error) {
),
CurrentTCPBandwidth: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "net_current_tcp_bandwidth"),
"TCP Bandwidth detected in bytes per seccond.",
"TCP Bandwidth detected in bytes per second.",
[]string{"session_name"},
nil,
),
@@ -157,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
@@ -183,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
}
@@ -273,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
}
@@ -345,7 +347,3 @@ func (c *RemoteFxCollector) collectRemoteFXGraphicsCounters(ctx *ScrapeContext,
return nil, nil
}
func milliSecToSec(t float64) float64 {
return t / 1000
}

View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkRemoteFXCollector(b *testing.B) {
benchmarkCollector(b, "remote_fx", newRemoteFx)
}

401
collector/scheduled_task.go Normal file
View File

@@ -0,0 +1,401 @@
//go:build windows
// +build windows
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/client_golang/prometheus"
)
const (
FlagScheduledTaskOldExclude = "collector.scheduled_task.blacklist"
FlagScheduledTaskOldInclude = "collector.scheduled_task.whitelist"
FlagScheduledTaskExclude = "collector.scheduled_task.exclude"
FlagScheduledTaskInclude = "collector.scheduled_task.include"
)
var (
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
taskIncludePattern *regexp.Regexp
taskExcludePattern *regexp.Regexp
}
// TaskState ...
// https://docs.microsoft.com/en-us/windows/desktop/api/taskschd/ne-taskschd-task_state
type TaskState uint
type TaskResult uint
const (
TASK_STATE_UNKNOWN TaskState = iota
TASK_STATE_DISABLED
TASK_STATE_QUEUED
TASK_STATE_READY
TASK_STATE_RUNNING
TASK_RESULT_SUCCESS TaskResult = 0x0
)
// RegisteredTask ...
type ScheduledTask struct {
Name string
Path string
Enabled bool
State TaskState
MissedRunsCount float64
LastTaskResult TaskResult
}
type ScheduledTasks []ScheduledTask
// 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(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()
err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
if err != nil {
code := err.(*ole.OleError).Code()
if code != ole.S_OK && code != S_FALSE {
return nil, err
}
}
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",
[]string{"task"},
nil,
),
MissedRuns: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "missed_runs"),
"The number of times the registered task missed a scheduled run",
[]string{"task"},
nil,
),
State: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "state"),
"The current state of a scheduled task",
[]string{"task", "state"},
nil,
),
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 {
_ = level.Error(c.logger).Log("failed collecting user metrics", "desc", desc, "err", err)
return err
}
return nil
}
var TASK_STATES = []string{"disabled", "queued", "ready", "running", "unknown"}
func (c *ScheduledTaskCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
scheduledTasks, err := getScheduledTasks()
if err != nil {
return nil, err
}
for _, task := range scheduledTasks {
if c.taskExcludePattern.MatchString(task.Path) ||
!c.taskIncludePattern.MatchString(task.Path) {
continue
}
lastResult := 0.0
if task.LastTaskResult == TASK_RESULT_SUCCESS {
lastResult = 1.0
}
ch <- prometheus.MustNewConstMetric(
c.LastResult,
prometheus.GaugeValue,
lastResult,
task.Path,
)
ch <- prometheus.MustNewConstMetric(
c.MissedRuns,
prometheus.GaugeValue,
task.MissedRunsCount,
task.Path,
)
for _, state := range TASK_STATES {
var stateValue float64
if strings.ToLower(task.State.String()) == state {
stateValue = 1.0
}
ch <- prometheus.MustNewConstMetric(
c.State,
prometheus.GaugeValue,
stateValue,
task.Path,
state,
)
}
}
return nil, nil
}
const SCHEDULED_TASK_PROGRAM_ID = "Schedule.Service.1"
// S_FALSE is returned by CoInitialize if it was already called on this thread.
const S_FALSE = 0x00000001
func getScheduledTasks() (scheduledTasks ScheduledTasks, err error) {
schedClassID, err := ole.ClassIDFrom(SCHEDULED_TASK_PROGRAM_ID)
if err != nil {
return scheduledTasks, err
}
taskSchedulerObj, err := ole.CreateInstance(schedClassID, nil)
if err != nil || taskSchedulerObj == nil {
return scheduledTasks, err
}
defer taskSchedulerObj.Release()
taskServiceObj := taskSchedulerObj.MustQueryInterface(ole.IID_IDispatch)
_, err = oleutil.CallMethod(taskServiceObj, "Connect")
if err != nil {
return scheduledTasks, err
}
defer taskServiceObj.Release()
res, err := oleutil.CallMethod(taskServiceObj, "GetFolder", `\`)
if err != nil {
return scheduledTasks, err
}
rootFolderObj := res.ToIDispatch()
defer rootFolderObj.Release()
err = fetchTasksRecursively(rootFolderObj, &scheduledTasks)
return scheduledTasks, err
}
func fetchTasksInFolder(folder *ole.IDispatch, scheduledTasks *ScheduledTasks) error {
res, err := oleutil.CallMethod(folder, "GetTasks", 1)
if err != nil {
return err
}
tasks := res.ToIDispatch()
defer tasks.Release()
err = oleutil.ForEach(tasks, func(v *ole.VARIANT) error {
task := v.ToIDispatch()
defer task.Release()
parsedTask, err := parseTask(task)
if err != nil {
return err
}
*scheduledTasks = append(*scheduledTasks, parsedTask)
return nil
})
return err
}
func fetchTasksRecursively(folder *ole.IDispatch, scheduledTasks *ScheduledTasks) error {
if err := fetchTasksInFolder(folder, scheduledTasks); err != nil {
return err
}
res, err := oleutil.CallMethod(folder, "GetFolders", 1)
if err != nil {
return err
}
subFolders := res.ToIDispatch()
defer subFolders.Release()
err = oleutil.ForEach(subFolders, func(v *ole.VARIANT) error {
subFolder := v.ToIDispatch()
defer subFolder.Release()
return fetchTasksRecursively(subFolder, scheduledTasks)
})
return err
}
func parseTask(task *ole.IDispatch) (scheduledTask ScheduledTask, err error) {
taskNameVar, err := oleutil.GetProperty(task, "Name")
if err != nil {
return scheduledTask, err
}
defer func() {
if tempErr := taskNameVar.Clear(); tempErr != nil {
err = tempErr
}
}()
taskPathVar, err := oleutil.GetProperty(task, "Path")
if err != nil {
return scheduledTask, err
}
defer func() {
if tempErr := taskPathVar.Clear(); tempErr != nil {
err = tempErr
}
}()
taskEnabledVar, err := oleutil.GetProperty(task, "Enabled")
if err != nil {
return scheduledTask, err
}
defer func() {
if tempErr := taskEnabledVar.Clear(); tempErr != nil {
err = tempErr
}
}()
taskStateVar, err := oleutil.GetProperty(task, "State")
if err != nil {
return scheduledTask, err
}
defer func() {
if tempErr := taskStateVar.Clear(); tempErr != nil {
err = tempErr
}
}()
taskNumberOfMissedRunsVar, err := oleutil.GetProperty(task, "NumberOfMissedRuns")
if err != nil {
return scheduledTask, err
}
defer func() {
if tempErr := taskNumberOfMissedRunsVar.Clear(); tempErr != nil {
err = tempErr
}
}()
taskLastTaskResultVar, err := oleutil.GetProperty(task, "LastTaskResult")
if err != nil {
return scheduledTask, err
}
defer func() {
if tempErr := taskLastTaskResultVar.Clear(); tempErr != nil {
err = tempErr
}
}()
scheduledTask.Name = taskNameVar.ToString()
scheduledTask.Path = strings.ReplaceAll(taskPathVar.ToString(), "\\", "/")
scheduledTask.Enabled = taskEnabledVar.Value().(bool)
scheduledTask.State = TaskState(taskStateVar.Val)
scheduledTask.MissedRunsCount = float64(taskNumberOfMissedRunsVar.Val)
scheduledTask.LastTaskResult = TaskResult(taskLastTaskResultVar.Val)
return scheduledTask, err
}
func (t TaskState) String() string {
switch t {
case TASK_STATE_UNKNOWN:
return "Unknown"
case TASK_STATE_DISABLED:
return "Disabled"
case TASK_STATE_QUEUED:
return "Queued"
case TASK_STATE_READY:
return "Ready"
case TASK_STATE_RUNNING:
return "Running"
default:
return ""
}
}

View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkScheduledTaskCollector(b *testing.B) {
benchmarkCollector(b, "scheduled_task", newScheduledTask)
}

View File

@@ -1,30 +1,36 @@
//go:build windows
// +build windows
package collector
import (
"strconv"
"fmt"
"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"
"gopkg.in/alecthomas/kingpin.v2"
"github.com/yusufpapurcu/wmi"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc/mgr"
)
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()
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
@@ -33,15 +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 {
_ = 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",
@@ -73,9 +97,16 @@ func NewserviceCollector() (Collector, error) {
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *serviceCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
if desc, err := c.collect(ch); err != nil {
log.Error("failed collecting service metrics:", desc, err)
return err
if *useAPI {
if err := c.collectAPI(ch); err != nil {
_ = level.Error(c.logger).Log("msg", "failed collecting API service metrics:", "err", err)
return err
}
} else {
if err := c.collectWMI(ch); err != nil {
_ = level.Error(c.logger).Log("msg", "failed collecting WMI service metrics:", "err", err)
return err
}
}
return nil
}
@@ -103,6 +134,15 @@ var (
"paused",
"unknown",
}
apiStateValues = map[uint]string{
windows.SERVICE_CONTINUE_PENDING: "continue pending",
windows.SERVICE_PAUSE_PENDING: "pause pending",
windows.SERVICE_PAUSED: "paused",
windows.SERVICE_RUNNING: "running",
windows.SERVICE_START_PENDING: "start pending",
windows.SERVICE_STOP_PENDING: "stop pending",
windows.SERVICE_STOPPED: "stopped",
}
allStartModes = []string{
"boot",
"system",
@@ -110,6 +150,13 @@ var (
"manual",
"disabled",
}
apiStartModeValues = map[uint32]string{
windows.SERVICE_AUTO_START: "auto",
windows.SERVICE_BOOT_START: "boot",
windows.SERVICE_DEMAND_START: "manual",
windows.SERVICE_DISABLED: "disabled",
windows.SERVICE_SYSTEM_START: "system",
}
allStatuses = []string{
"ok",
"error",
@@ -126,14 +173,14 @@ var (
}
)
func (c *serviceCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
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 nil, err
return err
}
for _, service := range dst {
pid := strconv.FormatUint(uint64(service.ProcessId), 10)
pid := fmt.Sprintf("%d", uint64(service.ProcessId))
runAs := ""
if service.StartName != nil {
@@ -191,5 +238,95 @@ func (c *serviceCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Des
)
}
}
return nil, nil
return nil
}
func (c *serviceCollector) collectAPI(ch chan<- prometheus.Metric) error {
svcmgrConnection, err := mgr.Connect()
if err != nil {
return err
}
defer svcmgrConnection.Disconnect() //nolint:errcheck
// List All Services from the Services Manager.
serviceList, err := svcmgrConnection.ListServices()
if err != nil {
return err
}
// Iterate through the Services List.
for _, service := range serviceList {
// Get UTF16 service name.
serviceName, err := syscall.UTF16PtrFromString(service)
if err != nil {
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Service %s get name error: %#v", service, err))
continue
}
// Open connection for service handler.
serviceHandle, err := windows.OpenService(svcmgrConnection.Handle, serviceName, windows.GENERIC_READ)
if err != nil {
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Open service %s error: %#v", service, err))
continue
}
// Create handle for each service.
serviceManager := &mgr.Service{Name: service, Handle: serviceHandle}
defer serviceManager.Close()
// Get Service Configuration.
serviceConfig, err := serviceManager.Config()
if err != nil {
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Get ervice %s config error: %#v", service, err))
continue
}
// Get Service Current Status.
serviceStatus, err := serviceManager.Query()
if err != nil {
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Get service %s status error: %#v", service, err))
continue
}
pid := fmt.Sprintf("%d", uint64(serviceStatus.ProcessId))
ch <- prometheus.MustNewConstMetric(
c.Information,
prometheus.GaugeValue,
1.0,
strings.ToLower(service),
serviceConfig.DisplayName,
pid,
serviceConfig.ServiceStartName,
)
for _, state := range apiStateValues {
isCurrentState := 0.0
if state == apiStateValues[uint(serviceStatus.State)] {
isCurrentState = 1.0
}
ch <- prometheus.MustNewConstMetric(
c.State,
prometheus.GaugeValue,
isCurrentState,
strings.ToLower(service),
state,
)
}
for _, startMode := range apiStartModeValues {
isCurrentStartMode := 0.0
if startMode == apiStartModeValues[serviceConfig.StartType] {
isCurrentStartMode = 1.0
}
ch <- prometheus.MustNewConstMetric(
c.StartMode,
prometheus.GaugeValue,
isCurrentStartMode,
strings.ToLower(service),
startMode,
)
}
}
return nil
}

View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkServiceCollector(b *testing.B) {
benchmarkCollector(b, "service", newserviceCollector)
}

View File

@@ -1,25 +1,41 @@
//go:build windows
// +build windows
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
@@ -63,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",
@@ -325,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
}
@@ -334,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
@@ -390,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
}

9
collector/smtp_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkSmtpCollector(b *testing.B) {
benchmarkCollector(b, "smtp", newSMTPCollector)
}

View File

@@ -1,18 +1,18 @@
//go:build windows
// +build windows
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
@@ -21,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)",
@@ -69,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
@@ -88,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
}

9
collector/system_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkSystemCollector(b *testing.B) {
benchmarkCollector(b, "system", newSystemCollector)
}

View File

@@ -1,18 +1,18 @@
//go:build windows
// +build windows
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
@@ -24,19 +24,20 @@ 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"),
prometheus.BuildFQName(Namespace, subsystem, "connection_failures_total"),
"(TCP.ConnectionFailures)",
[]string{"af"},
nil,
),
ConnectionsActive: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "connections_active"),
prometheus.BuildFQName(Namespace, subsystem, "connections_active_total"),
"(TCP.ConnectionsActive)",
[]string{"af"},
nil,
@@ -48,13 +49,13 @@ func NewTCPCollector() (Collector, error) {
nil,
),
ConnectionsPassive: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "connections_passive"),
prometheus.BuildFQName(Namespace, subsystem, "connections_passive_total"),
"(TCP.ConnectionsPassive)",
[]string{"af"},
nil,
),
ConnectionsReset: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "connections_reset"),
prometheus.BuildFQName(Namespace, subsystem, "connections_reset_total"),
"(TCP.ConnectionsReset)",
[]string{"af"},
nil,
@@ -90,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
@@ -172,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 {
@@ -180,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 {

9
collector/tcp_test.go Normal file
View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkTCPCollector(b *testing.B) {
benchmarkCollector(b, "tcp", newTCPCollector)
}

665
collector/teradici_pcoip.go Normal file
View 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
}

View File

@@ -0,0 +1,9 @@
package collector
import (
"testing"
)
func BenchmarkTeradiciPcoipCollector(b *testing.B) {
benchmarkCollector(b, "teradici_pcoip", newTeradiciPcoipCollector)
}

Some files were not shown because too many files have changed in this diff Show More