Compare commits

...

114 Commits

Author SHA1 Message Date
Jan-Otto Kröpke
86e6d12518 performancecounter: Add the possibility to request formatted values (#1830) 2025-01-14 23:32:44 +01:00
dependabot[bot]
4cd9627ebf chore(deps): bump golang.org/x/sys from 0.28.0 to 0.29.0 (#1825)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 10:07:25 +01:00
Jan-Otto Kröpke
81ea4c6223 performancecounter: fix panic with counter names having brackets (#1822)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-12-27 22:12:23 +01:00
Jan-Otto Kröpke
78386557d4 iis: fix panic (#1820)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-12-22 13:13:25 +01:00
Jan-Otto Kröpke
a9f8b3b722 process: Use registry collector for V1 data (#1814)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-12-21 22:58:47 +01:00
dependabot[bot]
39c929eefe chore(deps): bump github.com/prometheus/exporter-toolkit from 0.13.1 to 0.13.2 (#1815)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-16 12:36:11 +01:00
Jan-Otto Kröpke
eea5a50d5c performancecounter: support yaml documents and tolerate collector errors (#1809)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-12-09 19:14:26 +01:00
dependabot[bot]
a9698e27bf chore(deps): bump golang.org/x/sys from 0.27.0 to 0.28.0 (#1811)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-09 15:22:17 +01:00
dependabot[bot]
fac83b3c74 chore(deps): bump github.com/prometheus/common from 0.60.1 to 0.61.0 (#1810)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-09 15:21:43 +01:00
Jan-Otto Kröpke
0fc926c0b0 Update collector.performancecounter.md
Signed-off-by: Jan-Otto Kröpke <github@jkroepke.de>
2024-12-05 09:36:12 +01:00
Jan-Otto Kröpke
57a3e84cec process: fix metric labels for multiple process instances (#1804)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-12-03 18:31:41 +01:00
Jan-Otto Kröpke
2aebd5c2da process: fix metric labels for multiple process instances (#1803)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-12-03 12:07:03 +01:00
Jan-Otto Kröpke
109c34f572 chore: added tests (#1800)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-12-01 21:50:49 +01:00
Jan-Otto Kröpke
0ad8e01e0e mssql: add counter based on server version (#1799)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-12-01 18:20:44 +01:00
Jan-Otto Kröpke
3a3b50f898 chore: update deps (#1796)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-30 18:34:43 +01:00
Jan-Otto Kröpke
f5ff75ebc2 mssql: fix not collecting sql errors (#1793)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-30 13:10:11 +01:00
Jan-Otto Kröpke
71e5e5ec5f iis: Fix label for Default Web Site (#1792)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-30 13:02:00 +01:00
Jan-Otto Kröpke
40ff2f2e57 vmware: fix memory collector (#1791)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-30 12:13:35 +01:00
Jan-Otto Kröpke
9db94aa66a performancecounter: rename collector (#1787)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-30 11:24:01 +01:00
Jan-Otto Kröpke
a359acb3d1 logical_disk: fix volume access with limited permission (#1786)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-29 23:33:18 +01:00
Jan-Otto Kröpke
487de0c20b hyperv: Removed % Guest Idle Time performance counters (introduced in 0.30.0-beta.4) (#1785)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-29 22:19:22 +01:00
Jan-Otto Kröpke
aaa4ce07f6 system: BREAKING rename windows_system_system_up_time to windows_system_boot_time_timestamp_seconds (#1784)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-29 22:19:14 +01:00
Jan-Otto Kröpke
a2db81494e mssql: set windows_exporter_collector_success to 0, if errors occurs (#1777)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-27 00:14:53 +01:00
Jan-Otto Kröpke
64bf0a6551 collector: don't fail if perf counters are empty. (#1776)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-26 23:56:36 +01:00
Jan-Otto Kröpke
40b6f53479 textfile: set windows_exporter_collector_success to 0, if an errors occurs (#1775)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-26 23:47:23 +01:00
Jan-Otto Kröpke
ca04ad8fd2 fix: use log.file=eventlog as default value, if running as windows service (#1771)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-26 21:46:54 +01:00
Jan-Otto Kröpke
fd55ac4894 collector: refactor metrics handler (#1773)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-26 21:13:47 +01:00
Jan-Otto Kröpke
c8eeb595c0 feat: Support OpenMetrics (#1772)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-26 19:43:52 +01:00
Jan-Otto Kröpke
1a4c6c5ce7 feat: Tolerate collector failures (#1769)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-25 21:27:31 +01:00
dependabot[bot]
fd76be38e0 chore(deps): bump github.com/stretchr/testify from 1.9.0 to 1.10.0 (#1770)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-25 14:27:21 +01:00
Jan-Otto Kröpke
eff124250f chore: move exporter binary to cmd package (#1768)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-24 15:53:56 +01:00
Jan-Otto Kröpke
1badb34506 chore: fix copyright headers (#1767)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-24 14:11:14 +01:00
Jan-Otto Kröpke
f9e41294c3 mscluster: fix cluster and network sub collectors (#1759)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-24 13:57:19 +01:00
Jan-Otto Kröpke
86ace68978 msmq: Use Performance Counter instead WMI (#1766)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-24 13:38:24 +01:00
Jan-Otto Kröpke
e812584f27 smb: extend smb share metrics (#1765)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-24 13:18:14 +01:00
Jan-Otto Kröpke
1ecc340659 nps: refactor collector (#1764)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-24 11:38:36 +01:00
Jan-Otto Kröpke
4c0574536f collector: fix wrong perfdata instances (#1763)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-24 01:52:25 +01:00
Jan-Otto Kröpke
26d6dddf25 adfs: fix collector (#1761)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-24 00:39:38 +01:00
Jan-Otto Kröpke
75c6a4c182 collector: remove windows_exporter_perflib_snapshot_duration_seconds metric (#1760)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-22 21:10:00 +01:00
Jan-Otto Kröpke
a602d7be9d logical_disk: revert panic trigger on error (#1755)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-22 17:20:27 +01:00
Jan-Otto Kröpke
4534c2a6ae mssql: fix performance counter with additional server instance (#1753)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-21 22:52:30 +01:00
Jan-Otto Kröpke
3b378136f5 logical_disk: Get Volume ID for NTFS Volume Mounts (#1752)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-21 20:59:11 +01:00
Jan-Otto Kröpke
85845f4780 exchange: Extend Transport Queue metrics (#1749)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-20 02:05:31 +01:00
Jan-Otto Kröpke
fdee2d8613 hyperv: Refactor collector, added DataStore, Virtual SMB and Dynamic Memory Balancer metrics (click PR number for more information) (#1712)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-19 23:36:37 +01:00
Jan-Otto Kröpke
8c90961c10 mssql: expose server version info (#1741)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-19 23:35:55 +01:00
Jan-Otto Kröpke
2335fba18a logicaldisk: fix base counter values (#1747)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-19 21:35:32 +01:00
Jan-Otto Kröpke
c6ee794598 service: fixed buffer too low error (#1745)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-18 17:39:42 +01:00
Jan-Otto Kröpke
9f29fc8a9c service: parallelize api calls (#1744)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-18 02:07:03 +01:00
Jan-Otto Kröpke
e6a15d4ec4 chore: Remove registry based perfdata collector (#1742)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-17 21:51:12 +01:00
Jan-Otto Kröpke
6206b695c6 smb: refactor collector (#1740)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-15 21:27:28 +01:00
Jan-Otto Kröpke
b209ab6d6a smtp: refactor collector (#1739)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-15 20:39:56 +01:00
Jan-Otto Kröpke
78bd720e88 remote_fx: refactor collector (#1738)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-15 19:34:00 +01:00
Jan-Otto Kröpke
a4ec0a96f1 chore: use slog instead gokit for logging style (#1737)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-14 23:12:28 +01:00
Jan-Otto Kröpke
7a9a4e5831 pagefile: BREAKING: move paging metrics from os to dedicated collector (click PR for more information) (#1735)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-14 22:39:59 +01:00
Jan-Otto Kröpke
df8513ab8e Update README.md
Signed-off-by: Jan-Otto Kröpke <github@jkroepke.de>
2024-11-14 22:32:25 +01:00
Jan-Otto Kröpke
1956330ac4 physical_disk: refactor collector (#1734)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-14 22:28:28 +01:00
Jan-Otto Kröpke
baa4dc16ae chore: disable quay.io push, since no credentials are available. (#1733)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-14 20:14:30 +01:00
Jan-Otto Kröpke
d13d726453 chore: Switch to hostprocess base image and add support for Windows Server 2025 on Kubernetes (click PR number for more information) (#1731)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-14 20:01:15 +01:00
Jan-Otto Kröpke
31bcf42473 system: refactor collector (#1730)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-14 00:06:22 +01:00
Jan-Otto Kröpke
f332361723 terminal_services: refactor collector (#1729) 2024-11-13 21:38:31 +01:00
Jan-Otto Kröpke
b4f50c542c time: refactor collector (#1728) 2024-11-13 19:26:47 +01:00
Jan-Otto Kröpke
b53f18bcc6 vmware: refactor collector (#1727) 2024-11-12 23:16:22 +01:00
Jan-Otto Kröpke
eeb7955f5e udp: Added UDP collector (#1725) 2024-11-11 17:17:19 +01:00
dependabot[bot]
55181f5bac chore(deps): bump golang.org/x/sys from 0.26.0 to 0.27.0 (#1724)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-11 13:01:20 +01:00
Jan-Otto Kröpke
e6c9253f15 feat: add perfcounter.engine CLI option as alternative to WINDOWS_EXPORTER_PERF_COUNTERS_ENGINE env (#1723) 2024-11-09 23:41:59 +01:00
Yang Zhao (he/him)
b26ae86992 docs: Update textfile collector defaults inclusion (#1722) 2024-11-08 21:22:46 +00:00
dependabot[bot]
004f8da0ef chore(deps): bump github.com/Microsoft/hcsshim from 0.12.8 to 0.12.9 (#1716)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-04 12:34:07 +01:00
dependabot[bot]
65f41b3582 chore(deps): bump github.com/prometheus/exporter-toolkit from 0.13.0 to 0.13.1 (#1717)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-04 12:33:58 +01:00
Jan-Otto Kröpke
be67d853aa cpu: implement int32 counter for PDH calls as well. (#1715) 2024-11-03 19:24:36 +01:00
Jan-Otto Kröpke
bf233ad3e3 mi: replace all WMI calls with MI calls (#1714) 2024-11-03 17:23:26 +01:00
Jan-Otto Kröpke
45d3eabab9 mi: Revert "replace all WMI calls with MI calls" (#1713) 2024-11-03 11:20:46 +01:00
Jan-Otto Kröpke
c4f5d58a3e mi: replace all WMI calls with MI calls (#1700) 2024-11-03 01:03:34 +01:00
dependabot[bot]
582d8dd29c chore(deps): bump github.com/Microsoft/hcsshim from 0.12.7 to 0.12.8 (#1707)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 13:53:32 +01:00
dependabot[bot]
abc5388cab chore(deps): bump github.com/prometheus/common from 0.60.0 to 0.60.1 (#1708)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 12:40:17 +01:00
dependabot[bot]
fd9eb6d877 chore(deps): bump github.com/prometheus/client_golang from 1.20.4 to 1.20.5 (#1701)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jan-Otto Kröpke <github@jkroepke.de>
2024-10-24 18:57:53 +02:00
poly
bad8ba225a docs: Add log.file argument to README (#1702) 2024-10-23 16:26:09 +02:00
Jan-Otto Kröpke
ce2df385a6 tcp: fix panic on collector (#1699) 2024-10-17 02:29:53 +02:00
Jan-Otto Kröpke
92b7e445e1 fix: fail, if unknown collector is defined in enabled list (#1693) 2024-10-17 01:17:57 +02:00
Jan-Otto Kröpke
332b0a8a1c update: rename updates collector to update (#1692) 2024-10-15 13:55:16 +02:00
Niko Ehrenfeuchter
73755b8bfe docs: add actual Windows Update service name (#1690) 2024-10-15 13:55:07 +02:00
dependabot[bot]
25d90212ce chore(deps): bump github.com/bmatcuk/doublestar/v4 from 4.6.1 to 4.7.1 (#1689)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-14 13:38:02 +02:00
Jan-Otto Kröpke
d1517d8398 logon: BREAKING: replace wmi query by Win32 API calls and expose detailed logon sessions. (click PR for more information) (#1687) 2024-10-13 10:19:41 +02:00
Jan-Otto Kröpke
7500ad6a83 *: Remove teradici_pcoip and vmware_blast collector (#1686) 2024-10-12 21:27:26 +02:00
Jan-Otto Kröpke
a0159b333e exchange: Use new collector interface (#1685) 2024-10-12 18:09:05 +02:00
Jan-Otto Kröpke
22fdb33b4c chore: optimize registry collector (#1683) 2024-10-11 00:18:36 +02:00
Jan-Otto Kröpke
f46f9082f9 memory: Implement perfdata collector (#1676) 2024-10-10 21:48:21 +02:00
Jan-Otto Kröpke
028f7aa823 *: don't exclude resources, if empty exclude is empty. (#1680) 2024-10-10 21:44:04 +02:00
Jan-Otto Kröpke
545bf77326 Update pr-check.yaml
Signed-off-by: Jan-Otto Kröpke <github@jkroepke.de>
2024-10-10 21:06:37 +02:00
Niko Ehrenfeuchter
90ac0b269e chore(docs): fix link to update collector (#1682) 2024-10-10 17:35:36 +02:00
dependabot[bot]
72df5154fc chore(deps): bump github.com/prometheus/common from 0.59.2-0.20240918152650-14bac55a992f to 0.60.0 (#1674)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 14:51:50 +02:00
dependabot[bot]
4ee03c4528 chore(deps): bump golang.org/x/sys from 0.25.0 to 0.26.0 (#1675)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 14:51:29 +02:00
Jan-Otto Kröpke
2ef1a5fdf1 logical_disk: Implement Perfdata collector (#1673) 2024-10-07 00:15:54 +02:00
Jan-Otto Kröpke
efb20b1e31 dns: Implement Perfdata collector (#1672) 2024-10-06 00:22:58 +02:00
Jan-Otto Kröpke
ab33f3c49c dhcp: Use new collector interface (#1671) 2024-10-05 21:55:26 +02:00
Jan-Otto Kröpke
5952c51a39 *: Implement collector interface for registry perfdata (#1670) 2024-10-05 21:33:40 +02:00
Jan-Otto Kröpke
2a9a11bd01 process: fix fallback to V1 collector (#1667) 2024-10-03 23:44:36 +02:00
Jan-Otto Kröpke
79baf9921d process: Implement PDH collector and add support for Process V2 (#1666) 2024-10-03 21:24:17 +02:00
Jan-Otto Kröpke
7e9976efd3 chore: cleanup move private packages to internal (#1665) 2024-10-03 20:34:45 +02:00
Jan-Otto Kröpke
5d95610c84 chore: Move private packages to internal (#1664) 2024-10-03 20:23:56 +02:00
Jan-Otto Kröpke
bcfe6df24d dfsr: Implement PDH collector (#1663) 2024-10-03 19:23:20 +02:00
Jan-Otto Kröpke
70156cd106 cache: Implement PDH collector (#1662) 2024-10-03 14:31:44 +02:00
Jan-Otto Kröpke
e6ef2de40c ad: Implement PDH collector (#1660) 2024-10-03 11:59:10 +02:00
Jan-Otto Kröpke
0a78909cf6 *: replace --collectors.[name].* with --collector.[name].* flags (click PR number for more information) (#1659) 2024-10-02 13:24:58 +02:00
Jan-Otto Kröpke
2155d34779 net: expose network interfaces address (#1635) 2024-10-01 23:44:53 +02:00
astigmata
1caef5cc12 tcp: use GetExtendedTcpTable to display states Closed, Listening, SynSent, SynRcvd, CloseWait, TimeWait ... (#1638)
Co-authored-by: Jan-Otto Kröpke <github@jkroepke.de>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jan-Otto Kröpke <joe@cloudeteer.de>
2024-10-01 23:23:35 +02:00
Jan-Otto Kröpke
14910efd4f updates: add windows update collector (#1652)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-10-01 23:23:23 +02:00
Jan-Otto Kröpke
48e0e11063 cpu: add workaround for counter resets related to % Processor Utility metric (#1637) 2024-10-01 10:53:13 +02:00
Jan-Otto Kröpke
996080c1e9 adfs: Implement PDH collector (#1656) 2024-09-29 13:25:04 +02:00
Jan-Otto Kröpke
e6aaf91df1 initiate: close event log handle (#1654) 2024-09-28 21:23:05 +02:00
Jan-Otto Kröpke
b67b930ffc initiate: fix Cannot create another system semaphore error (#1653) 2024-09-28 19:53:12 +02:00
Jan-Otto Kröpke
a1defadf1e collector: add stack trace, if collector panics (#1650) 2024-09-28 15:57:56 +02:00
Jan-Otto Kröpke
01e809315c scheduled_task: fix memory leaks (#1649) 2024-09-28 15:15:15 +02:00
Jan-Otto Kröpke
798bf32dec adcs: Implement PDH collector (#1648) 2024-09-28 13:23:08 +02:00
Jan-Otto Kröpke
622813343f collector: change log level to info for succeeded (#1644) 2024-09-27 12:01:30 +02:00
388 changed files with 31549 additions and 22103 deletions

View File

@@ -37,7 +37,7 @@ jobs:
- name: check
run: |
PR_TITLE_PREFIX=$(echo "$PR_TITLE" | cut -d':' -f1)
if [[ -d "pkg/collector/$PR_TITLE_PREFIX" ]] ||[[ -d "pkg/$PR_TITLE_PREFIX" ]] || [[ -d "$PR_TITLE_PREFIX" ]] || [[ "$PR_TITLE_PREFIX" == "chore" ]] || [[ "$PR_TITLE_PREFIX" == "chore(docs)" ]] || [[ "$PR_TITLE_PREFIX" == "chore(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "*" ]] || [[ "$PR_TITLE_PREFIX" == "Synchronize common files from prometheus/prometheus" ]]; then
if [[ -d "internal/collector/$PR_TITLE_PREFIX" ]] || [[ -d "internal/$PR_TITLE_PREFIX" ]] || [[ -d "pkg/$PR_TITLE_PREFIX" ]] || [[ -d "$PR_TITLE_PREFIX" ]] || [[ "$PR_TITLE_PREFIX" == "docs" ]] || [[ "$PR_TITLE_PREFIX" == "ci" ]] || [[ "$PR_TITLE_PREFIX" == "revert" ]] || [[ "$PR_TITLE_PREFIX" == "fix" ]] || [[ "$PR_TITLE_PREFIX" == "feat" ]] || [[ "$PR_TITLE_PREFIX" == "chore" ]] || [[ "$PR_TITLE_PREFIX" == "chore(docs)" ]] || [[ "$PR_TITLE_PREFIX" == "chore(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "*" ]] || [[ "$PR_TITLE_PREFIX" == "Synchronize common files from prometheus/prometheus" ]]; then
exit 0
fi

View File

@@ -6,6 +6,7 @@ on:
branches:
- master
pull_request:
workflow_dispatch:
release:
types:
- published
@@ -16,10 +17,7 @@ permissions:
packages: write
env:
VERSION_PROMU: '0.14.0'
VERSION_CONTAINERD: '1.7.21'
VERSION_BUILDKIT: '0.15.2'
VERSION_BUILDX: '0.16.2'
VERSION_PROMU: '0.17.0'
jobs:
build:
@@ -33,27 +31,6 @@ jobs:
with:
go-version-file: 'go.mod'
# https://github.com/pl4nty/Windows-Containers/blob/Main/helpful_tools/Install-BuildKit-GitHubActions/workflow.yaml
- name: Setup containerd
run: |
curl.exe -L https://github.com/containerd/containerd/releases/download/v${{ env.VERSION_CONTAINERD }}/containerd-${{ env.VERSION_CONTAINERD }}-windows-amd64.tar.gz -o containerd.tar.gz
tar.exe xvf containerd.tar.gz
.\bin\containerd.exe --register-service
Start-Service containerd
- name: Setup BuildKit
run: |
curl.exe -L https://github.com/moby/buildkit/releases/download/v${{ env.VERSION_BUILDKIT }}/buildkit-v${{ env.VERSION_BUILDKIT }}.windows-amd64.tar.gz -o buildkit.tar.gz
tar.exe xvf buildkit.tar.gz
.\bin\buildkitd.exe --register-service
Start-Service buildkitd
- name: Setup Docker Buildx
run: |
curl.exe -L https://github.com/docker/buildx/releases/download/v${{ env.VERSION_BUILDX }}/buildx-v${{ env.VERSION_BUILDX }}.windows-amd64.exe -o $env:ProgramData\Docker\cli-plugins\docker-buildx.exe
- uses: docker/setup-buildx-action@v3
with:
driver: remote
endpoint: npipe:////./pipe/buildkitd
- name: Install WiX
run: dotnet tool install --global wix
@@ -75,32 +52,32 @@ jobs:
- name: Build
run: |
$ErrorActionPreference = "Stop"
$Version = git describe --tags --always
$Version = $Version -replace 'v', ''
# '+' symbols are invalid characters in image tags
$Version = $Version -replace '\+', '_'
$Version | Set-Content VERSION -PassThru
make build-all
# GH requires all files to have different names, so add version/arch to differentiate
foreach($Arch in "amd64", "arm64") {
Move-Item output\$Arch\windows_exporter.exe output\windows_exporter-$Version-$Arch.exe
}
Get-ChildItem -Path output
- name: Build Release Artifacts
run: |
$ErrorActionPreference = "Stop"
$Version = Get-Content VERSION
foreach($Arch in "amd64", "arm64") {
Write-Host "Building windows_exporter $Version msi for $Arch"
.\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$Version-$Arch.exe -Version $Version -Arch "$Arch"
}
Move-Item installer\*.msi output\
Get-ChildItem -Path output\
@@ -114,16 +91,27 @@ jobs:
output\windows_exporter-*.exe
output\windows_exporter-*.msi
- name: Build Docker Artifacts
run: make build-all
- name: Release
if: startsWith(github.ref, 'refs/tags/')
env:
VERSION: >-
${{
startsWith(github.ref, 'refs/tags/') && 'latest' ||
(
github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || github.ref_name
)
}}
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 $_}
docker:
name: Build docker images
runs-on: ubuntu-latest
needs:
- build
steps:
- uses: actions/checkout@v4
with:
fetch-depth: '0'
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
name: windows_exporter_binaries
- name: Login to Docker Hub
if: ${{ github.event_name != 'pull_request' }}
@@ -137,8 +125,8 @@ jobs:
# uses: docker/login-action@v3
# with:
# registry: quay.io
# username: 'robot'
# password: ${{ secrets.QUAY_IO_API_TOKEN }}
# username: ${{ secrets.QUAY_USER }}
# password: ${{ secrets.QUAY_PASS }}
- name: Login to GitHub container registry
if: ${{ github.event_name != 'pull_request' }}
@@ -148,19 +136,32 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push Latest image
if: ${{ github.event_name != 'pull_request' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ startsWith(github.ref, 'refs/tags/') && 'latest' || github.ref_name }}
run: |
make push-all
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/prometheus-community/windows-exporter
docker.io/prometheuscommunity/windows-exporter
# quay.io/prometheuscommunity/windows-exporter
tags: |
type=semver,pattern={{version}}
type=ref,event=branch
type=ref,event=pr
labels: |
org.opencontainers.image.title=windows_exporter
org.opencontainers.image.description=A Prometheus exporter for Windows machines.
org.opencontainers.image.vendor=The Prometheus Community
org.opencontainers.image.licenses=MIT
- 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
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: windows/amd64

View File

@@ -23,4 +23,4 @@ jobs:
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
ignore_words_list: calle,Entires

3
.gitignore vendored
View File

@@ -8,4 +8,5 @@ output/
*.syso
installer/*.msi
installer/*.wixpdb
local/
local/
!.idea/inspectionProfiles/Project_Default.xml

View File

@@ -11,11 +11,12 @@ linters:
- exportloopref
- fatcontext
- funlen
- gochecknoglobals
- gocognit
- goconst
- gocyclo
- godot
- gomnd
- paralleltest
- lll
- maintidx
- mnd
@@ -24,16 +25,20 @@ linters:
- wrapcheck
run:
timeout: 5m
timeout: 15m
output:
sort-results: true
linters-settings:
gosec:
excludes:
- G101 # Potential hardcoded credentials
- G115 # integer overflow conversion
gci:
sections:
- prefix(github.com/prometheus-community/windows_exporter/pkg/initiate)
- prefix(github.com/prometheus-community/windows_exporter/internal/windowsservice)
- standard # Standard section: captures all standard packages.
- default # Default section: contains all imports that could not be matched to another section type.
custom-order: true
@@ -48,7 +53,7 @@ linters-settings:
forbidigo:
forbid:
- "^(fmt\\.Print(|f|ln)|print|println)$"
- p: "^syscall\\..*$"
- p: "^syscall\\.(.{1,7}|.{7}[^N]|.{9,})$"
msg: use golang.org/x/sys/windows instead of syscall
- p: "^windows\\.NewLazyDLL$"
msg: use NewLazySystemDLL instead NewLazyDLL
@@ -82,7 +87,3 @@ issues:
- text: "don't use ALL_CAPS in Go names; use CamelCase"
linters:
- revive
- path: pkg/perflib/
linters:
- godox
- stylecheck

View File

@@ -2,11 +2,13 @@ go:
# Whenever the Go version is updated here,
# .github/workflows should also be updated.
version: 1.23
cgo: false
repository:
path: github.com/prometheus-community/windows_exporter
build:
binaries:
- name: windows_exporter
path: ./cmd/windows_exporter
tags:
all:
- trimpath
@@ -21,4 +23,5 @@ tarball:
- LICENSE
crossbuild:
platforms:
- windows
- windows/amd64
- windows/arm64

13
.run/all.run.xml Normal file
View File

@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="all" type="GoApplicationRunConfiguration" factoryName="Go Application" folderName="run">
<module name="windows_exporter" />
<working_directory value="$PROJECT_DIR$" />
<parameters value="--web.listen-address=127.0.0.1:9182 --log.level=info --collectors.enabled=ad,adcs,adfs,cache,container,cpu,cpu_info,cs,dfsr,dhcp,diskdrive,dns,exchange,filetime,fsrmquota,hyperv,iis,license,logical_disk,logon,memory,mscluster,msmq,mssql,net,netframework,nps,os,pagefile,performancecounter,physical_disk,printer,process,remote_fx,scheduled_task,service,smb,smbclient,smtp,system,tcp,terminal_services,thermalzone,time,udp,update,vmware,performancecounter --debug.enabled --collector.performancecounter.objects='[{ &quot;name&quot;: &quot;memory&quot;, &quot;type&quot;: &quot;formatted&quot;, &quot;object&quot;: &quot;Memory&quot;, &quot;counters&quot;: [{ &quot;name&quot;:&quot;Cache Faults/sec&quot;, &quot;type&quot;:&quot;counter&quot; }]}]'" />
<sudo value="true" />
<kind value="PACKAGE" />
<package value="github.com/prometheus-community/windows_exporter/cmd/windows_exporter" />
<directory value="$PROJECT_DIR$" />
<filePath value="$PROJECT_DIR$/exporter.go" />
<method v="2" />
</configuration>
</component>

View File

@@ -1,9 +1,13 @@
# 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:ltsc2022"
# mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0
# Using this image as a base for HostProcess containers has a few advantages over using other base images for Windows containers including:
# - Smaller image size
# - OS compatibility (works on any Windows version that supports containers)
# This image MUST be built with docker buildx build (buildx) command on a Linux system.
# Ref: https://github.com/microsoft/windows-host-process-containers-base-image
ARG BASE="mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0"
FROM $BASE
ENV PATH="C:\Windows\system32;C:\Windows;"
COPY output/amd64/windows_exporter.exe /windows_exporter.exe
COPY windows_exporter*-amd64.exe /windows_exporter.exe
ENTRYPOINT ["windows_exporter.exe"]

View File

@@ -1,22 +0,0 @@
# Build this Docker Image on any platform with
# docker buildx build -t a --platform=windows/amd64 .
ARG BASE=mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0
FROM --platform=$BUILDPLATFORM golang:1.21 as builder
ARG TARGETARCH
ARG TARGETOS
# Get dependencies
WORKDIR /w
COPY go.mod go.sum ./
RUN go mod download
RUN go install github.com/prometheus/promu@latest
# Build windows_exporter
COPY . ./
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH make windows_exporter.exe
FROM $BASE
COPY --from=builder /w/windows_exporter.exe /windows_exporter.exe
ENTRYPOINT ["windows_exporter.exe"]

View File

@@ -29,14 +29,14 @@ test:
go test -v ./...
bench:
go test -v -bench='benchmarkcollector' ./pkg/collector/{cpu,logical_disk,physical_disk,logon,memory,net,printer,process,service,system,tcp,time}
go test -v -bench='benchmarkcollector' ./internal/collectors/{cpu,logical_disk,physical_disk,logon,memory,net,printer,process,service,system,tcp,time}
lint:
golangci-lint -c .golangci.yaml run
.PHONY: e2e-test
e2e-test: windows_exporter.exe
pwsh -NonInteractive -ExecutionPolicy Bypass -File .\tools\end-to-end-test.ps1
powershell -NonInteractive -ExecutionPolicy Bypass -File .\tools\end-to-end-test.ps1
.PHONY: promtool
promtool: windows_exporter.exe
@@ -64,31 +64,19 @@ build-hostprocess:
sub-build-%:
$(MAKE) OS=$* build-image
build-all: $(addprefix sub-build-,$(ALL_OS)) build-hostprocess
push:
set -x; \
for docker_repo in ${DOCKER_REPO}; do \
for osversion in ${ALL_OS}; do \
$(DOCKER) tag local/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion} $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
$(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); \
build-all: crossbuild
@for docker_repo in ${DOCKER_REPO}; do \
echo $(DOCKER) buildx build -f Dockerfile -t $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION) .; \
done
# We can't load the image into the local docker store, so we have to build and push it in one go
push-hostprocess:
set -x; \
for docker_repo in ${DOCKER_REPO}; do \
$(DOCKER) buildx build --push --build-arg=BASE=mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0 -f Dockerfile -t $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-hostprocess .; \
push:
@for docker_repo in ${DOCKER_REPO}; do \
echo $(DOCKER) buildx build --push -f Dockerfile -t $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION) .; \
done
.PHONY: push-all
push-all: build-all
$(MAKE) DOCKER_REPO="$(ALL_DOCKER_REPOS)" push # push-hostprocess - disabled until it works on Windows
$(MAKE) DOCKER_REPO="$(ALL_DOCKER_REPOS)" push
# Mandatory target for container description sync action
.PHONY: docker-repo-name

View File

@@ -1,6 +1,12 @@
# windows_exporter
![Build Status](https://github.com/prometheus-community/windows_exporter/workflows/windows_exporter%20CI/CD/badge.svg)
[![CI](https://github.com/prometheus-community/windows_exporter/actions/workflows/release.yml/badge.svg)](https://github.com/prometheus-community/windows_exporter)
[![Linting](https://github.com/prometheus-community/windows_exporter/actions/workflows/lint.yml/badge.svg)](https://github.com/prometheus-community/windows_exporter)
[![GitHub license](https://img.shields.io/github/license/prometheus-community/windows_exporter)](https://github.com/prometheus-community/windows_exporter/blob/master/LICENSE.txt)
[![Current Release](https://img.shields.io/github/release/prometheus-community/windows_exporter.svg?logo=github)](https://github.com/prometheus-community/windows_exporter/releases/latest)
[![GitHub Repo stars](https://img.shields.io/github/stars/prometheus-community/windows_exporter?style=flat&logo=github)](https://github.com/prometheus-community/windows_exporter/stargazers)
[![GitHub all releases](https://img.shields.io/github/downloads/prometheus-community/windows_exporter/total?logo=github)](https://github.com/prometheus-community/windows_exporter/releases/latest)
[![Go Report Card](https://goreportcard.com/badge/github.com/prometheus-community/windows_exporter)](https://goreportcard.com/report/github.com/prometheus-community/windows_exporter)
A Prometheus exporter for Windows machines.
@@ -35,6 +41,8 @@ Name | Description | Enabled by default
[netframework](docs/collector.netframework.md) | .NET Framework metrics |
[net](docs/collector.net.md) | Network interface I/O | &#10003;
[os](docs/collector.os.md) | OS metrics (memory, processes, users) | &#10003;
[pagefile](docs/collector.pagefile.md) | pagefile metrics |
[performancecounter](docs/collector.performancecounter.md) | Custom performance counter metrics |
[physical_disk](docs/collector.physical_disk.md) | physical disk metrics | &#10003;
[printer](docs/collector.printer.md) | Printer metrics |
[process](docs/collector.process.md) | Per-process metrics |
@@ -46,12 +54,12 @@ Name | Description | Enabled by default
[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 |
[vmware_blast](docs/collector.vmware_blast.md) | VMware Blast session metrics |
[thermalzone](docs/collector.thermalzone.md) | Thermal information |
[time](docs/collector.time.md) | Windows Time Service |
[udp](docs/collector.udp.md) | UDP connections |
[update](docs/collector.update.md) | Windows Update Service |
[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.
@@ -75,17 +83,18 @@ This can be useful for having different Prometheus servers collect specific metr
windows_exporter accepts flags to configure certain behaviours. The ones configuring the global behaviour of the exporter are listed below, while collector-specific ones are documented in the respective collector documentation above.
| Flag | Description | Default value |
|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
| `--web.listen-address` | host:port for exporter. | `:9182` |
| `--telemetry.path` | URL path for surfacing collected metrics. | `/metrics` |
| `--telemetry.max-requests` | Maximum number of concurrent requests. 0 to disable. | `5` |
| `--collectors.enabled` | Comma-separated list of collectors to use. Use `[defaults]` as a placeholder which gets expanded containing all the collectors enabled by default." | `[defaults]` |
| `--collectors.print` | If true, print available collectors and exit. | |
| `--scrape.timeout-margin` | Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads. | `0.5` |
| `--web.config.file` | A [web config][web_config] for setting up TLS and Auth | None |
| `--config.file` | [Using a config file](#using-a-configuration-file) from path or URL | None |
| `--config.file.insecure-skip-verify` | Skip TLS when loading config file from URL | false |
| Flag | Description | Default value |
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
| `--web.listen-address` | host:port for exporter. | `:9182` |
| `--telemetry.path` | URL path for surfacing collected metrics. | `/metrics` |
| `--telemetry.max-requests` | Maximum number of concurrent requests. 0 to disable. | `5` |
| `--collectors.enabled` | Comma-separated list of collectors to use. Use `[defaults]` as a placeholder which gets expanded containing all the collectors enabled by default." | `[defaults]` |
| `--collectors.print` | If true, print available collectors and exit. | |
| `--scrape.timeout-margin` | Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads. | `0.5` |
| `--web.config.file` | A [web config][web_config] for setting up TLS and Auth | None |
| `--config.file` | [Using a config file](#using-a-configuration-file) from path or URL | None |
| `--config.file.insecure-skip-verify` | Skip TLS when loading config file from URL | false |
| `--log.file` | Output file of log messages. One of [stdout, stderr, eventlog, \<path to log file>]<br>**NOTE:** The MSI installer will add a default argument to the installed service setting this to eventlog | stderr |
## Installation
@@ -190,6 +199,14 @@ Windows Server 2012 and 2012R2 are supported as best-effort only, but not guaran
The prometheus metrics will be exposed on [localhost:9182](http://localhost:9182)
### HTTP Endpoints
windows_exporter provides the following HTTP endpoints:
* `/metrics`: Exposes metrics in the [Prometheus text format](https://prometheus.io/docs/instrumenting/exposition_formats/).
* `/health`: Returns 200 OK when the exporter is running.
* `/debug/pprof/`: Exposes the [pprof](https://golang.org/pkg/net/http/pprof/) endpoints. Only, if `--debug.enabled` is set.
## Examples
### Enable only service collector and specify a custom query

195
cmd/windows_exporter/doc.go Normal file
View File

@@ -0,0 +1,195 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
The main package for the windows_exporter executable.
usage: windows_exporter [<flags>]
A metrics collector for Windows.
Flags:
-h, --[no-]help Show context-sensitive help (also try
--help-long and --help-man).
--config.file=CONFIG.FILE YAML configuration file to use. Values set in
this file will be overridden by CLI flags.
--[no-]config.file.insecure-skip-verify
Skip TLS verification in loading YAML
configuration.
--web.listen-address=:9182 ...
Addresses on which to expose metrics and web
interface. Repeatable for multiple addresses.
Examples: `:9100` or `[::1]:9100` for http,
`vsock://:9100` for vsock
--web.config.file="" Path to configuration file that can
enable TLS or authentication. See:
https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md
--telemetry.path="/metrics"
URL path for surfacing collected metrics.
--[no-]web.disable-exporter-metrics
Exclude metrics about the exporter itself
(promhttp_*, process_*, go_*).
--telemetry.max-requests=5
Maximum number of concurrent requests. 0 to
disable.
--collectors.enabled="cpu,cs,memory,logical_disk,physical_disk,net,os,service,system"
Comma-separated list of collectors to use.
Use '[defaults]' as a placeholder for all the
collectors enabled by default.
--scrape.timeout-margin=0.5
Seconds to subtract from the timeout allowed by
the client. Tune to allow for overhead or high
loads.
--[no-]debug.enabled If true, windows_exporter will expose debug
endpoints under /debug/pprof.
--process.priority="normal"
Priority of the exporter process. Higher
priorities may improve exporter responsiveness
during periods of system load. Can be one of
["realtime", "high", "abovenormal", "normal",
"belownormal", "low"]
--log.level=info Only log messages with the given severity or
above. One of: [debug, info, warn, error]
--log.format=logfmt Output format of log messages. One of: [logfmt,
json]
--log.file=stderr Output file of log messages. One of [stdout,
stderr, eventlog, <path to log file>]
--[no-]version Show application version.
--collector.scheduled_task.exclude=""
Regexp of tasks to exclude. Task path must
both match include and not match exclude to be
included.
--collector.scheduled_task.include=".+"
Regexp of tasks to include. Task path must
both match include and not match exclude to be
included.
--[no-]collector.updates.online
Whether to search for updates online.
--collector.updates.scrape-interval=6h0m0s
Define the interval of scraping Windows Update
information.
--[no-]collector.exchange.list
List the collectors along with their perflib
object name/ids
--collector.exchange.enabled="ADAccessProcesses,TransportQueues,HttpProxy,ActiveSync,AvailabilityService,OutlookWebAccess,Autodiscover,WorkloadManagement,RpcClientAccess,MapiHttpEmsmdb"
Comma-separated list of collectors to use.
Defaults to all, if not specified.
--collector.net.nic-exclude=""
Regexp of NIC:s to exclude. NIC name must
both match include and not match exclude to be
included.
--collector.net.nic-include=".+"
Regexp of NIC:s to include. NIC name must
both match include and not match exclude to be
included.
--collector.net.enabled="metrics,nic_addresses"
Comma-separated list of collectors to use.
Defaults to all, if not specified.
--collector.mscluster.enabled="cluster,network,node,resource,resourcegroup"
Comma-separated list of collectors to use.
--collector.mssql.enabled="accessmethods,availreplica,bufman,databases,dbreplica,genstats,locks,memmgr,sqlerrors,sqlstats,transactions,waitstats"
Comma-separated list of collectors to use.
--collector.mssql.port=1433
Port of MSSQL server used for
windows_mssql_info metric.
--collector.physical_disk.disk-exclude=""
Regexp of disks to exclude. Disk number must
both match include and not match exclude to be
included.
--collector.physical_disk.disk-include=".+"
Regexp of disks to include. Disk number must
both match include and not match exclude to be
included.
--collector.textfile.directories="C:\\Users\\Jan\\GolandProjects\\windows_exporter\\textfile_inputs"
Directory or Directories to read text files
with metrics from.
--collector.filetime.file-patterns=""
Comma-separated list of file patterns.
Each pattern is a glob pattern that can
contain `*`, `?`, and `**` (recursive). See
https://github.com/bmatcuk/doublestar#patterns
--collector.iis.app-exclude=""
Regexp of apps to exclude. App name must both
match include and not match exclude to be
included.
--collector.iis.app-include=".+"
Regexp of apps to include. App name must both
match include and not match exclude to be
included.
--collector.iis.site-exclude=""
Regexp of sites to exclude. Site name must
both match include and not match exclude to be
included.
--collector.iis.site-include=".+"
Regexp of sites to include. Site name must
both match include and not match exclude to be
included.
--collector.perfdata.objects=""
Objects of performance data to observe.
See docs for more information on how to use
this flag. By default, no objects are observed.
--collector.printer.include=".+"
Regular expression to match printers to collect
metrics for
--collector.printer.exclude=""
Regular expression to match printers to exclude
--collector.process.exclude=""
Regexp of processes to exclude. Process name
must both match include and not match exclude
to be included.
--collector.process.include=".+"
Regexp of processes to include. Process name
must both match include and not match exclude
to be included.
--[no-]collector.process.iis
Enable IIS worker process name queries.
May cause the collector to leak memory.
--collector.hyperv.enabled="datastore,dynamic_memory_balancer,dynamic_memory_vm,hypervisor_logical_processor,hypervisor_root_partition,hypervisor_root_virtual_processor,hypervisor_virtual_processor,legacy_network_adapter,virtual_machine_health_summary,virtual_machine_vid_partition,virtual_network_adapter,virtual_network_adapter_drop_reasons,virtual_smb,virtual_storage_device,virtual_switch"
Comma-separated list of collectors to use.
--collector.logical_disk.volume-exclude=""
Regexp of volumes to exclude. Volume name must
both match include and not match exclude to be
included.
--collector.logical_disk.volume-include=".+"
Regexp of volumes to include. Volume name must
both match include and not match exclude to be
included.
--collector.smtp.server-exclude=""
Regexp of virtual servers to exclude. Server
name must both match include and not match
exclude to be included.
--collector.smtp.server-include=".+"
Regexp of virtual servers to include. Server
name must both match include and not match
exclude to be included.
--collector.tcp.enabled="metrics,connections_state"
Comma-separated list of collectors to use.
Defaults to all, if not specified.
--collector.dfsr.sources-enabled="connection,folder,volume"
Comma-separated list of DFSR Perflib sources to
use.
--collector.service.exclude=""
Regexp of service to exclude. Service name (not
the display name!) must both match include and
not match exclude to be included.
--collector.service.include=".+"
Regexp of service to include. Process name (not
the display name!) must both match include and
not match exclude to be included.
--collector.time.enabled="system_time,ntp"
Comma-separated list of collectors to use.
Defaults to all, if not specified. ntp may not
available on all systems.
*/
package main

View File

@@ -1,3 +1,16 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
//go:generate go run github.com/tc-hib/go-winres@v0.3.3 make --product-version=git-tag --file-version=git-tag --arch=amd64,arm64
@@ -8,7 +21,7 @@ package main
//nolint:gofumpt
import (
// Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts.
"github.com/prometheus-community/windows_exporter/pkg/initiate"
"github.com/prometheus-community/windows_exporter/internal/windowsservice"
"context"
"errors"
@@ -20,39 +33,42 @@ import (
"os/signal"
"os/user"
"runtime"
"sort"
"runtime/debug"
"slices"
"strings"
"time"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/config"
"github.com/prometheus-community/windows_exporter/internal/httphandler"
"github.com/prometheus-community/windows_exporter/internal/log"
"github.com/prometheus-community/windows_exporter/internal/log/flag"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus-community/windows_exporter/pkg/collector"
"github.com/prometheus-community/windows_exporter/pkg/config"
"github.com/prometheus-community/windows_exporter/pkg/httphandler"
winlog "github.com/prometheus-community/windows_exporter/pkg/log"
"github.com/prometheus-community/windows_exporter/pkg/log/flag"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/pkg/utils"
"github.com/prometheus/common/version"
"github.com/prometheus/exporter-toolkit/web"
webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag"
"golang.org/x/sys/windows"
)
// Mapping of priority names to uin32 values required by windows.SetPriorityClass.
var priorityStringToInt = map[string]uint32{
"realtime": windows.REALTIME_PRIORITY_CLASS,
"high": windows.HIGH_PRIORITY_CLASS,
"abovenormal": windows.ABOVE_NORMAL_PRIORITY_CLASS,
"normal": windows.NORMAL_PRIORITY_CLASS,
"belownormal": windows.BELOW_NORMAL_PRIORITY_CLASS,
"low": windows.IDLE_PRIORITY_CLASS,
}
func main() {
os.Exit(run())
exitCode := run()
// If we are running as a service, we need to signal the service control manager that we are done.
if !windowsservice.IsService {
os.Exit(exitCode)
}
windowsservice.ExitCodeCh <- exitCode
// Wait for the service control manager to signal that we are done.
<-windowsservice.StopCh
}
func run() int {
startTime := time.Now()
ctx := context.Background()
app := kingpin.New("windows_exporter", "A metrics collector for Windows.")
var (
@@ -73,18 +89,10 @@ func run() int {
"web.disable-exporter-metrics",
"Exclude metrics about the exporter itself (promhttp_*, process_*, go_*).",
).Bool()
maxRequests = app.Flag(
"telemetry.max-requests",
"Maximum number of concurrent requests. 0 to disable.",
).Default("5").Int()
enabledCollectors = app.Flag(
"collectors.enabled",
"Comma-separated list of collectors to use. Use '[defaults]' as a placeholder for all the collectors enabled by default.").
Default(types.DefaultCollectors).String()
printCollectors = app.Flag(
"collectors.print",
"If true, print available collectors and exit.",
).Bool()
Default(collector.DefaultCollectors).String()
timeoutMargin = app.Flag(
"scrape.timeout-margin",
"Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads.",
@@ -97,10 +105,21 @@ func run() int {
"process.priority",
"Priority of the exporter process. Higher priorities may improve exporter responsiveness during periods of system load. Can be one of [\"realtime\", \"high\", \"abovenormal\", \"normal\", \"belownormal\", \"low\"]",
).Default("normal").String()
memoryLimit = app.Flag(
"process.memory-limit",
"Limit memory usage in bytes. This is a soft-limit and not guaranteed. 0 means no limit. Read more at https://pkg.go.dev/runtime/debug#SetMemoryLimit .",
).Default("200000000").Int64()
)
winlogConfig := &winlog.Config{}
flag.AddFlags(app, winlogConfig)
logFile := &log.AllowedFile{}
_ = logFile.Set("stdout")
if windowsservice.IsService {
_ = logFile.Set("eventlog")
}
logConfig := &log.Config{File: logFile}
flag.AddFlags(app, logConfig)
app.Version(version.Print("windows_exporter"))
app.HelpFlag.Short('h')
@@ -119,7 +138,9 @@ func run() int {
return 1
}
logger, err := winlog.New(winlogConfig)
debug.SetMemoryLimit(*memoryLimit)
logger, err := log.New(logConfig)
if err != nil {
//nolint:sloglint // we do not have an logger yet
slog.Error("failed to create logger",
@@ -130,7 +151,7 @@ func run() int {
}
if *configFile != "" {
resolver, err := config.NewResolver(*configFile, logger, *insecureSkipVerify)
resolver, err := config.NewResolver(ctx, *configFile, logger, *insecureSkipVerify)
if err != nil {
logger.Error("could not load config file",
slog.Any("err", err),
@@ -140,7 +161,7 @@ func run() int {
}
if err = resolver.Bind(app, os.Args[1:]); err != nil {
logger.Error("Failed to bind configuration",
logger.ErrorContext(ctx, "failed to bind configuration",
slog.Any("err", err),
)
@@ -154,14 +175,14 @@ func run() int {
// Parse flags once more to include those discovered in configuration file(s).
if _, err = app.Parse(os.Args[1:]); err != nil {
logger.Error("Failed to parse CLI args from YAML file",
logger.ErrorContext(ctx, "failed to parse CLI args from YAML file",
slog.Any("err", err),
)
return 1
}
logger, err = winlog.New(winlogConfig)
logger, err = log.New(logConfig)
if err != nil {
//nolint:sloglint // we do not have an logger yet
slog.Error("failed to create logger",
@@ -172,20 +193,29 @@ func run() int {
}
}
logger.Debug("Logging has Started")
logger.LogAttrs(ctx, slog.LevelDebug, "logging has Started")
if *printCollectors {
printCollectorsToStdout()
if err = setPriorityWindows(logger, os.Getpid(), *processPriority); err != nil {
logger.Error("failed to set process priority",
slog.Any("err", err),
)
return 0
return 1
}
// Only set process priority if a non-default and valid value has been set
if priority, ok := priorityStringToInt[*processPriority]; ok && priority != windows.NORMAL_PRIORITY_CLASS {
logger.Debug("setting process priority to " + *processPriority)
enabledCollectorList := expandEnabledCollectors(*enabledCollectors)
if err := collectors.Enable(enabledCollectorList); err != nil {
logger.Error("couldn't enable collectors",
slog.Any("err", err),
)
if err = setPriorityWindows(os.Getpid(), priority); err != nil {
logger.Error("failed to set process priority",
return 1
}
// Initialize collectors before loading
if err = collectors.Build(logger); err != nil {
for _, err := range utils.SplitError(err) {
logger.Error("couldn't initialize collector",
slog.Any("err", err),
)
@@ -193,33 +223,9 @@ func run() int {
}
}
enabledCollectorList := utils.ExpandEnabledCollectors(*enabledCollectors)
collectors.Enable(enabledCollectorList)
// Initialize collectors before loading
if err = collectors.Build(logger); err != nil {
logger.Error("Couldn't load collectors",
slog.Any("err", err),
)
return 1
}
if err = collectors.SetPerfCounterQuery(logger); err != nil {
logger.Error("Couldn't set performance counter query",
slog.Any("err", err),
)
return 1
}
logCurrentUser(logger)
logger.Info("Enabled collectors: " + strings.Join(enabledCollectorList, ", "))
if utils.PDHEnabled() {
logger.Info("Using performance data helper from PHD.dll for performance counter collection. This is in experimental state.")
}
logger.InfoContext(ctx, "Enabled collectors: "+strings.Join(enabledCollectorList, ", "))
mux := http.NewServeMux()
mux.Handle("GET /health", httphandler.NewHealthHandler())
@@ -227,7 +233,6 @@ func run() int {
mux.Handle("GET "+*metricsPath, httphandler.New(logger, collectors, &httphandler.Options{
DisableExporterMetrics: *disableExporterMetrics,
TimeoutMargin: *timeoutMargin,
MaxRequests: *maxRequests,
}))
if *debugEnabled {
@@ -238,7 +243,7 @@ func run() int {
mux.HandleFunc("GET /debug/pprof/trace", pprof.Trace)
}
logger.Info("Starting windows_exporter",
logger.LogAttrs(ctx, slog.LevelInfo, fmt.Sprintf("starting windows_exporter in %s", time.Since(startTime)),
slog.String("version", version.Version),
slog.String("branch", version.Branch),
slog.String("revision", version.GetRevision()),
@@ -262,20 +267,20 @@ func run() int {
errCh <- err
}
errCh <- nil
close(errCh)
}()
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
ctx, stop := signal.NotifyContext(ctx, os.Interrupt, os.Kill)
defer stop()
select {
case <-ctx.Done():
logger.Info("Shutting down windows_exporter via kill signal")
case <-initiate.StopCh:
case <-windowsservice.StopCh:
logger.Info("Shutting down windows_exporter via service control")
case err := <-errCh:
if err != nil {
logger.Error("Failed to start windows_exporter",
logger.ErrorContext(ctx, "Failed to start windows_exporter",
slog.Any("err", err),
)
@@ -288,37 +293,49 @@ func run() int {
_ = server.Shutdown(ctx)
logger.Info("windows_exporter has shut down")
logger.InfoContext(ctx, "windows_exporter has shut down")
return 0
}
func printCollectorsToStdout() {
collectorNames := collector.Available()
sort.Strings(collectorNames)
fmt.Println("Available collectors:") //nolint:forbidigo
for _, n := range collectorNames {
fmt.Printf(" - %s\n", n) //nolint:forbidigo
}
}
func logCurrentUser(logger *slog.Logger) {
if u, err := user.Current(); err == nil {
logger.Info("Running as " + u.Username)
if strings.Contains(u.Username, "ContainerAdministrator") || strings.Contains(u.Username, "ContainerUser") {
logger.Warn("Running as a preconfigured Windows Container user. This may mean you do not have Windows HostProcess containers configured correctly and some functionality will not work as expected.")
}
u, err := user.Current()
if err != nil {
logger.Warn("Unable to determine which user is running this exporter. More info: https://github.com/golang/go/issues/37348",
slog.Any("err", err),
)
return
}
logger.Warn("Unable to determine which user is running this exporter. More info: https://github.com/golang/go/issues/37348")
logger.Info("Running as " + u.Username)
if strings.Contains(u.Username, "ContainerAdministrator") || strings.Contains(u.Username, "ContainerUser") {
logger.Warn("Running as a preconfigured Windows Container user. This may mean you do not have Windows HostProcess containers configured correctly and some functionality will not work as expected.")
}
}
func setPriorityWindows(pid int, priority uint32) error {
// setPriorityWindows sets the priority of the current process to the specified value.
func setPriorityWindows(logger *slog.Logger, pid int, priority string) error {
// Mapping of priority names to uin32 values required by windows.SetPriorityClass.
priorityStringToInt := map[string]uint32{
"realtime": windows.REALTIME_PRIORITY_CLASS,
"high": windows.HIGH_PRIORITY_CLASS,
"abovenormal": windows.ABOVE_NORMAL_PRIORITY_CLASS,
"normal": windows.NORMAL_PRIORITY_CLASS,
"belownormal": windows.BELOW_NORMAL_PRIORITY_CLASS,
"low": windows.IDLE_PRIORITY_CLASS,
}
winPriority, ok := priorityStringToInt[priority]
// Only set process priority if a non-default and valid value has been set
if !ok || winPriority != windows.NORMAL_PRIORITY_CLASS {
return nil
}
logger.LogAttrs(context.Background(), slog.LevelDebug, "setting process priority to "+priority)
// https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
handle, err := windows.OpenProcess(
windows.STANDARD_RIGHTS_REQUIRED|windows.SYNCHRONIZE|windows.SPECIFIC_RIGHTS_ALL,
@@ -328,7 +345,7 @@ func setPriorityWindows(pid int, priority uint32) error {
return fmt.Errorf("failed to open own process: %w", err)
}
if err = windows.SetPriorityClass(handle, priority); err != nil {
if err = windows.SetPriorityClass(handle, winPriority); err != nil {
return fmt.Errorf("failed to set priority class: %w", err)
}
@@ -338,3 +355,9 @@ func setPriorityWindows(pid int, priority uint32) error {
return nil
}
func expandEnabledCollectors(enabled string) []string {
expanded := strings.ReplaceAll(enabled, "[defaults]", collector.DefaultCollectors)
return slices.Compact(strings.Split(expanded, ","))
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,56 @@
{
"RT_GROUP_ICON": {
"APP": {
"0000": [
"icon.png"
]
}
},
"RT_MANIFEST": {
"#1": {
"0409": {
"description": "A Prometheus exporter for Windows machines.",
"minimum-os": "win7",
"execution-level": "as invoker",
"ui-access": false,
"auto-elevate": false,
"dpi-awareness": "system",
"disable-theming": false,
"disable-window-filtering": false,
"high-resolution-scrolling-aware": false,
"ultra-high-resolution-scrolling-aware": false,
"long-path-aware": false,
"printer-driver-isolation": false,
"gdi-scaling": false,
"segment-heap": false,
"use-common-controls-v6": false
}
}
},
"RT_VERSION": {
"#1": {
"0000": {
"fixed": {
"file_version": "0.0.0.0",
"product_version": "0.0.0.0"
},
"info": {
"0409": {
"Comments": "",
"CompanyName": "Prometheus Community",
"FileDescription": "A Prometheus exporter for Windows machines.",
"FileVersion": "",
"InternalName": "windows_exporter",
"LegalCopyright": "",
"LegalTrademarks": "",
"OriginalFilename": "",
"PrivateBuild": "",
"ProductName": "windows_exporter",
"ProductVersion": "",
"SpecialBuild": ""
}
}
}
}
}
}

View File

@@ -1,7 +1,23 @@
# example configuration file for windows_exporter
collectors:
enabled: cpu,cpu_info,exchange,iis,logical_disk,logon,memory,net,os,process,remote_fx,service,system,tcp,time,terminal_services,textfile
enabled: cpu,cpu_info,exchange,iis,logical_disk,logon,memory,net,os,performancecounter,process,remote_fx,service,system,tcp,time,terminal_services,textfile
collector:
service:
include: "windows_exporter"
performancecounter:
objects: |-
- name: photon_udp
object: "Photon Socket Server: UDP"
instances: ["*"]
counters:
- name: "UDP: Datagrams in"
metric: "photon_udp_datagrams"
labels:
direction: "in"
- name: "UDP: Datagrams out"
metric: "photon_udp_datagrams"
labels:
direction: "out"
log:
level: warn

View File

@@ -1,140 +0,0 @@
{{ template "head" . }}
{{ template "prom_content_head" . }}
<h1>Node Overview - {{ reReplaceAll "(.*?://)([^:/]+?)(:\\d+)?/.*" "$2" .Params.instance }}</h1>
<h3>CPU Usage</h3>
<div id="cpuGraph"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#cpuGraph"),
expr: "sum by (mode)(irate(windows_cpu_time_total{job='node',instance='{{ .Params.instance }}',mode!='idle'}[5m]))",
renderer: 'area',
max: {{ with printf "count(count by (cpu)(windows_cpu_time_total{job='node',instance='%s'}))" .Params.instance | query }}{{ . | first | value }}{{ else}}undefined{{end}},
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yTitle: 'Cores'
})
</script>
<h3>Network Utilization</h3>
<div id="networkioGraph"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#networkioGraph"),
expr: [
"irate(windows_net_bytes_sent_total{job='node',instance='{{ .Params.instance }}',nic!~'^isatap_ec2_internal'}[5m])",
"irate(windows_net_bytes_received_total{job='node',instance='{{ .Params.instance }}',nic!~'^isatap_ec2_internal'}[5m])",
],
min: 0,
name: [ 'sent', 'received' ],
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "B",
yTitle: 'Network IO'
})
</script>
<h3>Disk I/O Utilization</h3>
<div id="diskioGraph"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#diskioGraph"),
expr: [
"100 - irate(windows_logical_disk_idle_seconds_total{job='node',instance='{{ .Params.instance }}',volume!~'^HarddiskVolume.*$'}[5m]) * 100",
],
min: 0,
name: '[[ volume ]]',
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "%",
yTitle: 'Disk I/O Utilization'
})
</script>
<h3>Memory</h3>
<div id="memoryGraph"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#memoryGraph"),
renderer: 'area',
expr: [
"windows_cs_physical_memory_bytes{job='node',instance='{{ .Params.instance }}'}",
"windows_os_physical_memory_free_bytes{job='node',instance='{{ .Params.instance }}'}",
"windows_cs_physical_memory__bytes{job='node',instance='{{ .Params.instance }}'} - windows_os_physical_memory_free_bytes{job='node',instance='{{.Params.instance}}'}",
"windows_os_virtual_memory_bytes{job='node',instance='{{ .Params.instance }}'}",
],
name: ["Physical", "Free", "Used", "Virtual"],
min: 0,
yUnits: "B",
yAxisFormatter: PromConsole.NumberFormatter.humanize1024,
yHoverFormatter: PromConsole.NumberFormatter.humanize1024,
yTitle: 'Memory'
})
</script>
{{ template "prom_right_table_head" }}
<tr><th colspan="2">Overview</th></tr>
<tr>
<td>User CPU</td>
<td>{{ template "prom_query_drilldown" (args (printf "sum(irate(windows_cpu_time_total{job='node',instance='%s',mode='user'}[5m])) * 100 / count(count by (cpu)(windows_cpu_time_total{job='node',instance='%s'}))" .Params.instance .Params.instance) "%" "printf.1f") }}</td>
</tr>
<tr>
<td>Privileged CPU</td>
<td>{{ template "prom_query_drilldown" (args (printf "sum(irate(windows_cpu_time_total{job='node',instance='%s',mode='privileged'}[5m])) * 100 / count(count by (cpu)(windows_cpu_time_total{job='node',instance='%s'}))" .Params.instance .Params.instance) "%" "printf.1f") }}</td>
</tr>
<tr>
<td>Memory Total</td>
<td>{{ template "prom_query_drilldown" (args (printf "windows_cs_physical_memory_bytes{job='node',instance='%s'}" .Params.instance) "B" "humanize1024") }}</td>
</tr>
<tr>
<td>Memory Free</td>
<td>{{ template "prom_query_drilldown" (args (printf "windows_os_physical_memory_free_bytes{job='node',instance='%s'}" .Params.instance) "B" "humanize1024") }}</td>
</tr>
<tr>
<th colspan="2">Network</th>
</tr>
{{ range printf "windows_net_bytes_received_total{job='node',instance='%s',nic!='isatap_ec2_internal'}" .Params.instance | query | sortByLabel "nic" }}
<tr>
<td>{{ .Labels.nic }} Received</td>
<td>{{ template "prom_query_drilldown" (args (printf "irate(windows_net_bytes_received_total{job='node',instance='%s',nic='%s'}[5m])" .Labels.instance .Labels.nic) "B/s" "humanize") }}</td>
</tr>
<tr>
<td>{{ .Labels.nic }} Transmitted</td>
<td>{{ template "prom_query_drilldown" (args (printf "irate(windows_net_bytes_sent_total{job='node',instance='%s',nic='%s'}[5m])" .Labels.instance .Labels.nic) "B/s" "humanize") }}</td>
</tr>
{{ end }}
</tr>
<tr>
<th colspan="2">Disks</th>
</tr>
{{ range printf "windows_logical_disk_size_bytes{job='node',instance='%s',volume!~'^HarddiskVolume.*$'}" .Params.instance | query | sortByLabel "volume" }}
<tr>
<td>{{ .Labels.volume }} Utilization</td>
<td>{{ template "prom_query_drilldown" (args (printf "100 - irate(windows_logical_disk_idle_seconds_total{job='node',instance='%s',volume='%s'}[5m]) * 100" .Labels.instance .Labels.volume) "%" "printf.1f") }}</td>
</tr>
{{ end }}
{{ range printf "windows_logical_disk_size_bytes{job='node',instance='%s',volume!~'^HarddiskVolume.*$'}" .Params.instance | query | sortByLabel "volume" }}
<tr>
<td>{{ .Labels.volume }} Throughput</td>
<td>{{ template "prom_query_drilldown" (args (printf "irate(windows_logical_disk_read_bytes_total{job='node',instance='%s',volume='%s'}[5m]) + irate(windows_logical_disk_write_bytes_total{job='node',instance='%s',volume='%s'}[5m])" .Labels.instance .Labels.volume .Labels.instance .Labels.volume) "B/s" "humanize") }}</td>
</tr>
{{ end }}
<tr>
<th colspan="2">Filesystem Fullness</th>
</tr>
{{ define "roughlyNearZero" }}
{{ if gt .1 . }}~0{{ else }}{{ printf "%.1f" . }}{{ end }}
{{ end }}
{{ range printf "windows_logical_disk_size_bytes{job='node',instance='%s',volume!~'^HarddiskVolume.*$'}" .Params.instance | query | sortByLabel "volume" }}
<tr>
<td>{{ .Labels.volume }}</td>
<td>{{ template "prom_query_drilldown" (args (printf "100 - windows_logical_disk_free_bytes{job='node',instance='%s',volume='%s'} / windows_logical_disk_size_bytes{job='node'} * 100" .Labels.instance .Labels.volume) "%" "roughlyNearZero") }}</td>
</tr>
{{ end }}
</tr>
{{ template "prom_right_table_tail" }}
{{ template "prom_content_tail" . }}
{{ template "tail" }}

View File

@@ -18,6 +18,7 @@ This directory contains documentation of the collectors in the windows_exporter,
- [`fsrmquota`](collector.fsrmquota.md)
- [`hyperv`](collector.hyperv.md)
- [`iis`](collector.iis.md)
- [`license`](collector.license.md)
- [`logical_disk`](collector.logical_disk.md)
- [`logon`](collector.logon.md)
- [`memory`](collector.memory.md)
@@ -28,19 +29,23 @@ This directory contains documentation of the collectors in the windows_exporter,
- [`netframework`](collector.netframework.md)
- [`nps`](collector.nps.md)
- [`os`](collector.os.md)
- [`pagefile`](collector.pagefile.md)
- [`performancecounter`](collector.performancecounter.md)
- [`physical_disk`](collector.physical_disk.md)
- [`printer`](collector.printer.md)
- [`process`](collector.process.md)
- [`remote_fx`](collector.remote_fx.md)
- [`scheduled_task`](collector.scheduled_task.md)
- [`service`](collector.service.md)
- [`smb`](collector.smb.md)
- [`smbclient`](collector.smbclient.md)
- [`smtp`](collector.smtp.md)
- [`system`](collector.system.md)
- [`tcp`](collector.tcp.md)
- [`teradici_pcoip`](collector.teradici_pcoip.md)
- [`terminal_services`](collector.terminal_services.md)
- [`textfile`](collector.textfile.md)
- [`thermalzone`](collector.thermalzone.md)
- [`time`](collector.time.md)
- [`udp`](collector.udp.md)
- [`update`](collector.update.md)
- [`vmware`](collector.vmware.md)
- [`vmware_blast`](collector.vmware_blast.md)

View File

@@ -1,14 +1,13 @@
# exchange collector
The exchange collector collects metrics from MS Exchange hosts through perflib
The exchange collector collects metrics from MS Exchange hosts through Performance Counter
=======
|||
-|-
Metric name prefix | `exchange`
Classes | [Win32_PerfRawData_MSExchangeADAccess_MSExchangeADAccessProcesses](https://docs.microsoft.com/en-us/exchange/)<br/> [Win32_PerfRawData_MSExchangeTransportQueues_MSExchangeTransportQueues](https://docs.microsoft.com/en-us/exchange/)<br/> [Win32_PerfRawData_ESE_MSExchangeDatabaseInstances](https://docs.microsoft.com/en-us/exchange/)<br/> [Win32_PerfRawData_MSExchangeHttpProxy_MSExchangeHttpProxy](https://docs.microsoft.com/en-us/exchange/)<br/> [Win32_PerfRawData_MSExchangeActiveSync_MSExchangeActiveSync](https://docs.microsoft.com/en-us/exchange/)<br/> [Win32_PerfRawData_MSExchangeAvailabilityService_MSExchangeAvailabilityService](https://docs.microsoft.com/en-us/exchange/)<br/> [Win32_PerfRawData_MSExchangeOWA_MSExchangeOWA](https://docs.microsoft.com/en-us/exchange/)<br/> [Win32_PerfRawData_MSExchangeAutodiscover_MSExchangeAutodiscover](https://docs.microsoft.com/en-us/exchange/)<br/> [Win32_PerfRawData_MSExchangeWorkloadManagementWorkloads_MSExchangeWorkloadManagementWorkloads](https://docs.microsoft.com/en-us/exchange/)<br/> [Win32_PerfRawData_MSExchangeRpcClientAccess_MSExchangeRpcClientAccess](https://docs.microsoft.com/en-us/exchange/)<br/>
Enabled by default? | No
| | |
|---------------------|---------------------|
| Metric name prefix | `exchange` |
| Source | Performance Counter |
| Enabled by default? | No |
## Flags
@@ -19,45 +18,56 @@ Lists the Perflib Objects that are queried for data along with the perlfib objec
Comma-separated list of collectors to use, for example: `--collectors.exchange.enabled=AvailabilityService,OutlookWebAccess`. Matching is case-sensitive. Depending on the exchange installation not all performance counters are available. Use `--collectors.exchange.list` to obtain a list of supported collectors.
## Metrics
Name | Description
--------------|---------------
`windows_exchange_rpc_avg_latency_sec` | The latency (sec), averaged for the past 1024 packets
`windows_exchange_rpc_requests` | Number of client requests currently being processed by the RPC Client Access service
`windows_exchange_rpc_active_user_count` | Number of unique users that have shown some kind of activity in the last 2 minutes
`windows_exchange_rpc_connection_count` | Total number of client connections maintained
`windows_exchange_rpc_operations_total` | The rate at which RPC operations occur
`windows_exchange_rpc_user_count` | Number of users
`windows_exchange_ldap_read_time_sec` | Time (sec) to send an LDAP read request and receive a response
`windows_exchange_ldap_search_time_sec` | Time (sec) to send an LDAP search request and receive a response
`windows_exchange_ldap_write_time_sec` | Time (sec) to send an LDAP Add/Modify/Delete request and receive a response
`windows_exchange_ldap_timeout_errors_total` | Total number of LDAP timeout errors
`windows_exchange_ldap_long_running_ops_per_sec` | Long Running LDAP operations per second
`windows_exchange_transport_queues_external_active_remote_delivery` | External Active Remote Delivery Queue length
`windows_exchange_transport_queues_internal_active_remote_delivery` | Internal Active Remote Delivery Queue length
`windows_exchange_transport_queues_active_mailbox_delivery` | Active Mailbox Delivery Queue length
`windows_exchange_transport_queues_retry_mailbox_delivery` | Retry Mailbox Delivery Queue length
`windows_exchange_transport_queues_unreachable` | Unreachable Queue length
`windows_exchange_transport_queues_external_largest_delivery` | External Largest Delivery Queue length
`windows_exchange_transport_queues_internal_largest_delivery` | Internal Largest Delivery Queue length
`windows_exchange_transport_queues_poison` | Poison Queue length
`windows_exchange_http_proxy_mailbox_server_locator_avg_latency_sec` | Average latency (sec) of MailboxServerLocator web service calls
`windows_exchange_http_proxy_avg_auth_latency` | Average time spent authenticating CAS requests over the last 200 samples
`windows_exchange_http_proxy_outstanding_proxy_requests` | Number of concurrent outstanding proxy requests
`windows_exchange_http_proxy_requests_total` | Number of proxy requests processed each second
`windows_exchange_avail_service_requests_per_sec` | Number of requests serviced per second
`windows_exchange_owa_current_unique_users` | Number of unique users currently logged on to Outlook Web App
`windows_exchange_owa_requests_total` | Number of requests handled by Outlook Web App per second
`windows_exchange_autodiscover_requests_total` | Number of autodiscover service requests processed each second
`windows_exchange_workload_active_tasks` | Number of active tasks currently running in the background for workload management
`windows_exchange_workload_completed_tasks` | Number of workload management tasks that have been completed
`windows_exchange_workload_queued_tasks` | Number of workload management tasks that are currently queued up waiting to be processed
`windows_exchange_workload_yielded_tasks` | The total number of tasks that have been yielded by a workload
`windows_exchange_workload_is_active` | Active indicates whether the workload is in an active (1) or paused (0) state
`windows_exchange_activesync_requests_total` | Num HTTP requests received from the client via ASP.NET per sec. Shows Current user load
`windows_exchange_http_proxy_avg_cas_proccessing_latency_sec` | Average latency (sec) of CAS processing time over the last 200 reqs
`windows_exchange_http_proxy_mailbox_proxy_failure_rate` | % of failures between this CAS and MBX servers over the last 200 sample
`windows_exchange_activesync_ping_cmds_pending` | Number of ping commands currently pending in the queue
`windows_exchange_activesync_sync_cmds_total` | Number of sync commands processed per second. Clients use this command to synchronize items within a folder
| Name | Description |
|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------|
| `windows_exchange_rpc_avg_latency_sec` | The latency (sec), averaged for the past 1024 packets |
| `windows_exchange_rpc_requests` | Number of client requests currently being processed by the RPC Client Access service |
| `windows_exchange_rpc_active_user_count` | Number of unique users that have shown some kind of activity in the last 2 minutes |
| `windows_exchange_rpc_connection_count` | Total number of client connections maintained |
| `windows_exchange_rpc_operations_total` | The rate at which RPC operations occur |
| `windows_exchange_rpc_user_count` | Number of users |
| `windows_exchange_ldap_read_time_sec` | Time (sec) to send an LDAP read request and receive a response |
| `windows_exchange_ldap_search_time_sec` | Time (sec) to send an LDAP search request and receive a response |
| `windows_exchange_ldap_write_time_sec` | Time (sec) to send an LDAP Add/Modify/Delete request and receive a response |
| `windows_exchange_ldap_timeout_errors_total` | Total number of LDAP timeout errors |
| `windows_exchange_ldap_long_running_ops_per_sec` | Long Running LDAP operations per second |
| `windows_exchange_transport_queues_external_active_remote_delivery` | External Active Remote Delivery Queue length |
| `windows_exchange_transport_queues_internal_active_remote_delivery` | Internal Active Remote Delivery Queue length |
| `windows_exchange_transport_queues_active_mailbox_delivery` | Active Mailbox Delivery Queue length |
| `windows_exchange_transport_queues_retry_mailbox_delivery` | Retry Mailbox Delivery Queue length |
| `windows_exchange_transport_queues_unreachable` | Unreachable Queue length |
| `windows_exchange_transport_queues_external_largest_delivery` | External Largest Delivery Queue length |
| `windows_exchange_transport_queues_internal_largest_delivery` | Internal Largest Delivery Queue length |
| `windows_exchange_transport_queues_poison` | Poison Queue length |
| `windows_exchange_transport_queues_messages_queued_for_delivery_total` | Messages Queued For Delivery Total |
| `windows_exchange_transport_queues_messages_submitted_total` | Messages Submitted Total |
| `windows_exchange_transport_queues_messages_delayed_total` | Messages Delayed Total |
| `windows_exchange_transport_queues_messages_completed_delivery_total` | Messages Completed Delivery Total |
| `windows_exchange_transport_queues_shadow_queue_length` | Shadow Queue Length |
| `windows_exchange_transport_queues_submission_queue_length` | Submission Queue Length |
| `windows_exchange_transport_queues_delay_queue_length` | Delay Queue Length |
| `windows_exchange_transport_queues_items_completed_delivery_total` | Items Completed Delivery Total |
| `windows_exchange_transport_queues_items_queued_for_delivery_expired_total` | Items Queued For Delivery Expired Total |
| `windows_exchange_transport_queues_items_queued_for_delivery_total` | Items Queued For Delivery Total |
| `windows_exchange_transport_queues_items_resubmitted_total` | Items Resubmitted Total |
| `windows_exchange_http_proxy_mailbox_server_locator_avg_latency_sec` | Average latency (sec) of MailboxServerLocator web service calls |
| `windows_exchange_http_proxy_avg_auth_latency` | Average time spent authenticating CAS requests over the last 200 samples |
| `windows_exchange_http_proxy_outstanding_proxy_requests` | Number of concurrent outstanding proxy requests |
| `windows_exchange_http_proxy_requests_total` | Number of proxy requests processed each second |
| `windows_exchange_avail_service_requests_per_sec` | Number of requests serviced per second |
| `windows_exchange_owa_current_unique_users` | Number of unique users currently logged on to Outlook Web App |
| `windows_exchange_owa_requests_total` | Number of requests handled by Outlook Web App per second |
| `windows_exchange_autodiscover_requests_total` | Number of autodiscover service requests processed each second |
| `windows_exchange_workload_active_tasks` | Number of active tasks currently running in the background for workload management |
| `windows_exchange_workload_completed_tasks` | Number of workload management tasks that have been completed |
| `windows_exchange_workload_queued_tasks` | Number of workload management tasks that are currently queued up waiting to be processed |
| `windows_exchange_workload_yielded_tasks` | The total number of tasks that have been yielded by a workload |
| `windows_exchange_workload_is_active` | Active indicates whether the workload is in an active (1) or paused (0) state |
| `windows_exchange_activesync_requests_total` | Num HTTP requests received from the client via ASP.NET per sec. Shows Current user load |
| `windows_exchange_http_proxy_avg_cas_proccessing_latency_sec` | Average latency (sec) of CAS processing time over the last 200 reqs |
| `windows_exchange_http_proxy_mailbox_proxy_failure_rate` | % of failures between this CAS and MBX servers over the last 200 sample |
| `windows_exchange_activesync_ping_cmds_pending` | Number of ping commands currently pending in the queue |
| `windows_exchange_activesync_sync_cmds_total` | Number of sync commands processed per second. Clients use this command to synchronize items within a folder |
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_

View File

@@ -2,110 +2,262 @@
The hyperv collector exposes metrics about the Hyper-V hypervisor
|||
-|-
Metric name prefix | `hyperv`
Classes | `Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary`<br/>`Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition`<br/>`Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition`<br/>`Win32_PerfRawData_HvStats_HyperVHypervisor`<br/>`Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor`<br/>`Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor`<br/>`Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor`<br/>`Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch`<br/>`Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter`<br/>`Win32_PerfRawData_Counters_HyperVVirtualStorageDevice`<br/>`Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter`
Enabled by default? | No
| | |
|---------------------|----------------------|
| Metric name prefix | `hyperv` |
| Source | Performance counters |
| Enabled by default? | No |
## Flags
None
### `--collectors.hyperv.enabled`
Comma-separated list of collectors to use, for example:
`--collectors.hyperv.enabled=dynamic_memory_balancer,dynamic_memory_vm,hypervisor_logical_processor,hypervisor_root_partition,hypervisor_root_virtual_processor,hypervisor_virtual_processor,legacy_network_adapter,virtual_machine_health_summary,virtual_machine_vid_partition,virtual_network_adapter,virtual_storage_device,virtual_switch`.
Matching is case-sensitive.
## Metrics
Name | Description | Type | Labels
-----|-------------|------|-------
`windows_hyperv_health_critical` | _Not yet documented_ | counter | None
`windows_hyperv_health_ok` | _Not yet documented_ | counter | None
`windows_hyperv_vid_physical_pages_allocated` | _Not yet documented_ | counter | `vm`
`windows_hyperv_vid_preferred_numa_node_index` | _Not yet documented_ | counter | `vm`
`windows_hyperv_vid_remote_physical_pages` | _Not yet documented_ | counter | `vm`
`windows_hyperv_root_partition_address_spaces` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_attached_devices` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_deposited_pages` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_device_dma_errors` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_device_interrupt_errors` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_device_interrupt_mappings` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_device_interrupt_throttle_events` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_preferred_numa_node_index` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_gpa_space_modifications` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_io_tlb_flush_cost` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_io_tlb_flush` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_recommended_virtual_tlb_size` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_physical_pages_allocated` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_1G_device_pages` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_1G_gpa_pages` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_2M_device_pages` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_2M_gpa_pages` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_4K_device_pages` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_4K_gpa_pages` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_virtual_tlb_flush_entires` | _Not yet documented_ | counter | None
`windows_hyperv_root_partition_virtual_tlb_pages` | _Not yet documented_ | counter | None
`windows_hyperv_hypervisor_virtual_processors` | _Not yet documented_ | counter | None
`windows_hyperv_hypervisor_logical_processors` | _Not yet documented_ | counter | None
`windows_hyperv_host_lp_guest_run_time_percent` | _Not yet documented_ | counter | `core`
`windows_hyperv_host_lp_hypervisor_run_time_percent` | _Not yet documented_ | counter | `core`
`windows_hyperv_host_lp_total_run_time_percent` | _Not yet documented_ | counter | `core`
`windows_hyperv_host_cpu_guest_run_time` | _Not yet documented_ | counter | `core`
`windows_hyperv_host_cpu_hypervisor_run_time` | _Not yet documented_ | counter | `core`
`windows_hyperv_host_cpu_remote_run_time` | _Not yet documented_ | counter | `core`
`windows_hyperv_host_cpu_total_run_time` | _Not yet documented_ | counter | `core`
`windows_hyperv_host_cpu_wait_time_per_dispatch_total` | _Not yet documented_ | counter | `core`
`windows_hyperv_vm_cpu_guest_run_time` | _Not yet documented_ | counter | `vm`, `core`
`windows_hyperv_vm_cpu_hypervisor_run_time` | _Not yet documented_ | counter | `vm`, `core`
`windows_hyperv_vm_cpu_remote_run_time` | _Not yet documented_ | counter | `vm`, `core`
`windows_hyperv_vm_cpu_wait_time_per_dispatch_total` | _Not yet documented_ | counter | `vm`, `core`
`windows_hyperv_vm_memory_added_total` | _Not yet documented_ | counter | `vm`
`windows_hyperv_vm_memory_pressure_average` | _Not yet documented_ | gauge | `vm`
`windows_hyperv_vm_memory_pressure_current` | _Not yet documented_ | counter | `vm`
`windows_hyperv_vm_memory_physical_guest_visible` | _Not yet documented_ | gauge | `vm`
`windows_hyperv_vm_memory_pressure_maximum` | _Not yet documented_ | gauge | `vm`
`windows_hyperv_vm_memory_add_operations_total` | _Not yet documented_ | counter | `vm`
`windows_hyperv_vm_memory_remove_operations_total` | _Not yet documented_ | counter | `vm`
`windows_hyperv_vm_memory_pressure_minumim` | _Not yet documented_ | gauge | `vm`
`windows_hyperv_vm_memory_physical` | _Not yet documented_ | gauge | `vm`
`windows_hyperv_vm_memory_removed_total` | _Not yet documented_ | counter | `vm`
`windows_hyperv_vm_cpu_total_run_time` | _Not yet documented_ | counter | `vm`, `core`
`windows_hyperv_vswitch_broadcast_packets_received_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_broadcast_packets_sent_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_bytes_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_bytes_received_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_bytes_sent_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_directed_packets_received_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_directed_packets_send_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_dropped_packets_incoming_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_dropped_packets_outcoming_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_extensions_dropped_packets_incoming_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_extensions_dropped_packets_outcoming_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_learned_mac_addresses_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_multicast_packets_received_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_multicast_packets_sent_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_number_of_send_channel_moves_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_number_of_vmq_moves_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_packets_flooded_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_packets_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_packets_received_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_packets_sent_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_vswitch_purged_mac_addresses_total` | _Not yet documented_ | counter | `vswitch`
`windows_hyperv_ethernet_bytes_dropped` | _Not yet documented_ | counter | `adapter`
`windows_hyperv_ethernet_bytes_received` | _Not yet documented_ | counter | `adapter`
`windows_hyperv_ethernet_bytes_sent` | _Not yet documented_ | counter | `adapter`
`windows_hyperv_ethernet_frames_dropped` | _Not yet documented_ | counter | `adapter`
`windows_hyperv_ethernet_frames_received` | _Not yet documented_ | counter | `adapter`
`windows_hyperv_ethernet_frames_sent` | _Not yet documented_ | counter | `adapter`
`windows_hyperv_vm_device_error_count` | _Not yet documented_ | counter | `vm_device`
`windows_hyperv_vm_device_queue_length` | _Not yet documented_ | counter | `vm_device`
`windows_hyperv_vm_device_bytes_read` | _Not yet documented_ | counter | `vm_device`
`windows_hyperv_vm_device_operations_read` | _Not yet documented_ | counter | `vm_device`
`windows_hyperv_vm_device_bytes_written` | _Not yet documented_ | counter | `vm_device`
`windows_hyperv_vm_device_operations_written` | _Not yet documented_ | counter | `vm_device`
`windows_hyperv_vm_interface_bytes_received` | _Not yet documented_ | counter | `vm_interface`
`windows_hyperv_vm_interface_bytes_sent` | _Not yet documented_ | counter | `vm_interface`
`windows_hyperv_vm_interface_packets_incoming_dropped` | _Not yet documented_ | counter | `vm_interface`
`windows_hyperv_vm_interface_packets_outgoing_dropped` | _Not yet documented_ | counter | `vm_interface`
`windows_hyperv_vm_interface_packets_received` | _Not yet documented_ | counter | `vm_interface`
`windows_hyperv_vm_interface_packets_sent` | _Not yet documented_ | counter | `vm_interface`
### Hyper-V Datastore
### Hyper-V Datastore Metrics Documentation
This documentation outlines the available metrics for monitoring Hyper-V Datastore performance and resource usage using Prometheus. All metrics are prefixed with `windows_hyperv_datastore`.
| Metric Name | Description | Type | Labels |
|------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------|-----------|
| `windows_hyperv_datastore_fragmentation_ratio` | Represents the fragmentation ratio of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_sector_size_bytes` | Represents the sector size of the DataStore in bytes. | gauge | datastore |
| `windows_hyperv_datastore_data_alignment_bytes` | Represents the data alignment of the DataStore in bytes. | gauge | datastore |
| `windows_hyperv_datastore_current_replay_log_size_bytes` | Represents the current replay log size of the DataStore in bytes. | gauge | datastore |
| `windows_hyperv_datastore_available_entries` | Represents the number of available entries inside object tables. | gauge | datastore |
| `windows_hyperv_datastore_empty_entries` | Represents the number of empty entries inside object tables. | gauge | datastore |
| `windows_hyperv_datastore_free_bytes` | Represents the number of free bytes inside key tables. | gauge | datastore |
| `windows_hyperv_datastore_data_end_bytes` | Represents the data end of the DataStore in bytes. | gauge | datastore |
| `windows_hyperv_datastore_file_objects` | Represents the number of file objects in the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_object_tables` | Represents the number of object tables in the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_key_tables` | Represents the number of key tables in the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_file_data_size_bytes` | Represents the file data size in bytes of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_table_data_size_bytes` | Represents the table data size in bytes of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_names_size_bytes` | Represents the names size in bytes of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_number_of_keys` | Represents the number of keys in the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_reconnect_latency_microseconds` | Represents the reconnect latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_disconnect_count` | Represents the disconnect count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_write_to_file_byte_latency_microseconds` | Represents the write-to-file byte latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_write_to_file_byte_count` | Represents the write-to-file byte count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_write_to_file_count` | Represents the write-to-file count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_read_from_file_byte_latency_microseconds` | Represents the read-from-file byte latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_read_from_file_byte_count` | Represents the read-from-file byte count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_read_from_file_count` | Represents the read-from-file count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_write_to_storage_byte_latency_microseconds` | Represents the write-to-storage byte latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_write_to_storage_byte_count` | Represents the write-to-storage byte count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_write_to_storage_count` | Represents the write-to-storage count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_read_from_storage_byte_latency_microseconds` | Represents the read-from-storage byte latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_read_from_storage_byte_count` | Represents the read-from-storage byte count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_read_from_storage_count` | Represents the read-from-storage count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_commit_byte_latency_microseconds` | Represents the commit byte latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_commit_byte_count` | Represents the commit byte count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_commit_count` | Represents the commit count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_cache_update_operation_latency_microseconds` | Represents the cache update operation latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_cache_update_operation_count` | Represents the cache update operation count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_commit_operation_latency_microseconds` | Represents the commit operation latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_commit_operation_count` | Represents the commit operation count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_compact_operation_latency_microseconds` | Represents the compact operation latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_compact_operation_count` | Represents the compact operation count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_load_file_operation_latency_microseconds` | Represents the load file operation latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_load_file_operation_count` | Represents the load file operation count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_remove_operation_latency_microseconds` | Represents the remove operation latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_remove_operation_count` | Represents the remove operation count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_query_size_operation_latency_microseconds` | Represents the query size operation latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_query_size_operation_count` | Represents the query size operation count of the DataStore. | counter | datastore |
| `windows_hyperv_datastore_set_operation_latency_microseconds` | Represents the set operation latency in microseconds of the DataStore. | gauge | datastore |
| `windows_hyperv_datastore_set_operation_count` | Represents the set operation count of the DataStore. | counter | datastore |
### Hyper-V Dynamic Memory Balancer
Some metrics explained: https://learn.microsoft.com/en-us/archive/blogs/chrisavis/monitoring-dynamic-memory-in-windows-server-hyper-v-2012
| Name | Description | Type | Labels |
|-------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|-------|------------|
| `windows_hyperv_dynamic_memory_balancer_available_memory_bytes` | Represents the amount of memory left on the node. | gauge | `balancer` |
| `windows_hyperv_dynamic_memory_balancer_available_memory_for_balancing_bytes` | Represents the available memory for balancing purposes. | gauge | `balancer` |
| `windows_hyperv_dynamic_memory_balancer_average_pressure_ratio` | Represents the average system pressure on the balancer node among all balanced objects. | gauge | `balancer` |
| `windows_hyperv_dynamic_memory_balancer_system_current_pressure_ratio` | Represents the current pressure in the system. | gauge | `balancer` |
### Hyper-V Dynamic Memory VM
| Name | Description | Type | Labels |
|------------------------------------------------------------------------|-----------------------------------------------------------------------------------|---------|--------|
| `windows_hyperv_dynamic_memory_vm_added_bytes_total` | Represents the cumulative amount of memory added to the VM. | counter | `vm` |
| `windows_hyperv_dynamic_memory_vm_pressure_current_ratio` | Represents the current pressure in the VM. | gauge | `vm` |
| `windows_hyperv_dynamic_memory_vm_guest_available_bytes` | Represents the current amount of available memory in the VM (reported by the VM). | gauge | `vm` |
| `windows_hyperv_dynamic_memory_vm_guest_visible_physical_memory_bytes` | Represents the amount of memory visible in the VM | gauge | `vm` |
| `windows_hyperv_dynamic_memory_vm_pressure_maximum_ratio` | Represents the maximum pressure band in the VM. | gauge | `vm` |
| `windows_hyperv_dynamic_memory_vm_add_operations_total` | Represents the total number of add operations for the VM. | counter | `vm` |
| `windows_hyperv_dynamic_memory_vm_remove_operations_total` | Represents the total number of remove operations for the VM. | counter | `vm` |
| `windows_hyperv_dynamic_memory_vm_pressure_minimum_ratio` | Represents the minimum pressure band in the VM. | gauge | `vm` |
| `windows_hyperv_dynamic_memory_vm_physical` | Represents the current amount of memory in the VM. | gauge | `vm` |
| `windows_hyperv_dynamic_memory_vm_removed_bytes_total` | Represents the cumulative amount of memory removed from the VM. | counter | `vm` |
### Hyper-V Hypervisor Logical Processor
| Name | Description | Type | Labels |
|----------------------------------------------------------------------|------------------------------------------------------------------------|---------|----------------|
| `windows_hyperv_hypervisor_logical_processor_time_total` | Time that processor spent in different modes (hypervisor, guest, idle) | counter | `core`.`state` |
| `windows_hyperv_hypervisor_logical_processor_context_switches_total` | The rate of virtual processor context switches on the processor. | counter | `core` |
### Hyper-V Hypervisor Root Partition
| Name | Description | Type | Labels |
|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
| `windows_hyperv_root_partition_address_spaces` | The number of address spaces in the virtual TLB of the partition | gauge | None |
| `windows_hyperv_root_partition_attached_devices` | The number of devices attached to the partition | gauge | None |
| `windows_hyperv_root_partition_deposited_pages` | The number of pages deposited into the partition | gauge | None |
| `windows_hyperv_root_partition_device_dma_errors` | An indicator of illegal DMA requests generated by all devices assigned to the partition | gauge | None |
| `windows_hyperv_root_partition_device_interrupt_errors` | An indicator of illegal interrupt requests generated by all devices assigned to the partition | gauge | None |
| `windows_hyperv_root_partition_device_interrupt_mappings` | The number of device interrupt mappings used by the partition | gauge | None |
| `windows_hyperv_root_partition_device_interrupt_throttle_events` | The number of times an interrupt from a device assigned to the partition was temporarily throttled because the device was generating too many interrupts | gauge | None |
| `windows_hyperv_root_partition_preferred_numa_node_index` | The number of pages present in the GPA space of the partition (zero for root partition) | gauge | None |
| `windows_hyperv_root_partition_gpa_space_modifications` | The rate of modifications to the GPA space of the partition | counter | None |
| `windows_hyperv_root_partition_io_tlb_flush_cost` | The average time (in nanoseconds) spent processing an I/O TLB flush | gauge | None |
| `windows_hyperv_root_partition_io_tlb_flush` | The rate of flushes of I/O TLBs of the partition | counter | None |
| `windows_hyperv_root_partition_recommended_virtual_tlb_size` | The recommended number of pages to be deposited for the virtual TLB | gauge | None |
| `windows_hyperv_root_partition_physical_pages_allocated` | The number of timer interrupts skipped for the partition | gauge | None |
| `windows_hyperv_root_partition_1G_device_pages` | The number of 1G pages present in the device space of the partition | gauge | None |
| `windows_hyperv_root_partition_1G_gpa_pages` | The number of 1G pages present in the GPA space of the partition | gauge | None |
| `windows_hyperv_root_partition_2M_device_pages` | The number of 2M pages present in the device space of the partition | gauge | None |
| `windows_hyperv_root_partition_2M_gpa_pages` | The number of 2M pages present in the GPA space of the partition | gauge | None |
| `windows_hyperv_root_partition_4K_device_pages` | The number of 4K pages present in the device space of the partition | gauge | None |
| `windows_hyperv_root_partition_4K_gpa_pages` | The number of 4K pages present in the GPA space of the partition | gauge | None |
| `windows_hyperv_root_partition_virtual_tlb_flush_entries` | The rate of flushes of the entire virtual TLB | counter | None |
| `windows_hyperv_root_partition_virtual_tlb_pages` | The number of pages used by the virtual TLB of the partition | gauge | None |
### Hyper-V Hypervisor Root Virtual Processor
| Name | Description | Type | Labels |
|---------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|---------|----------------|
| `windows_hyperv_hypervisor_root_virtual_processor_time_total` | Time that processor spent in different modes (hypervisor, guest_run, guest_idle, remote, total) | counter | `core`.`state` |
| `windows_hyperv_hypervisor_root_virtual_cpu_wait_time_per_dispatch_total` | The average time (in nanoseconds) spent waiting for a virtual processor to be dispatched onto a logical processor | counter | `core` |
### Hyper-V Legacy Network Adapter
| Name | Description | Type | Labels |
|---------------------------------------------------------------|-------------------------------------------------------------------------|---------|-----------|
| `windows_hyperv_legacy_network_adapter_bytes_dropped_total` | Bytes Dropped is the number of bytes dropped on the network adapter | counter | `adapter` |
| `windows_hyperv_legacy_network_adapter_bytes_received_total` | Bytes received is the number of bytes received on the network adapter | counter | `adapter` |
| `windows_hyperv_legacy_network_adapter_bytes_sent_total` | Bytes sent is the number of bytes sent over the network adapter | counter | `adapter` |
| `windows_hyperv_legacy_network_adapter_frames_dropped_total` | Frames Dropped is the number of frames dropped on the network adapter | counter | `adapter` |
| `windows_hyperv_legacy_network_adapter_frames_received_total` | Frames received is the number of frames received on the network adapter | counter | `adapter` |
| `windows_hyperv_legacy_network_adapter_frames_sent_total` | Frames sent is the number of frames sent over the network adapter | counter | `adapter` |
### Hyper-V Hypervisor Virtual Processor
| Name | Description | Type | Labels |
|--------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|---------|--------------|
| `windows_hyperv_hypervisor_virtual_processor_time_total` | Time that processor spent in different modes (hypervisor, guest_run, guest_idle, remote) | counter | `vm`, `core` |
| `windows_hyperv_hypervisor_virtual_processor_total_run_time_total` | Time that processor spent | counter | `vm`, `core` |
| `windows_hyperv_hypervisor_virtual_processor_cpu_wait_time_per_dispatch_total` | The average time (in nanoseconds) spent waiting for a virtual processor to be dispatched onto a logical processor. | counter | `vm`, `core` |
### Hyper-V Virtual Network Adapter
| Name | Description | Type | Labels |
|-------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|---------|-----------|
| `windows_hyperv_virtual_network_adapter_received_bytes_total` | Represents the total number of bytes received per second by the network adapter | counter | `adapter` |
| `windows_hyperv_virtual_network_adapter_sent_bytes_total` | Represents the total number of bytes sent per second by the network adapter | counter | `adapter` |
| `windows_hyperv_virtual_network_adapter_incoming_dropped_packets_total` | Represents the total number of dropped packets per second in the incoming direction of the network adapter | counter | `adapter` |
| `windows_hyperv_virtual_network_adapter_outgoing_dropped_packets_total` | Represents the total number of dropped packets per second in the outgoing direction of the network adapter | counter | `adapter` |
| `windows_hyperv_virtual_network_adapter_received_packets_total` | Represents the total number of packets received per second by the network adapter | counter | `adapter` |
| `windows_hyperv_virtual_network_adapter_sent_packets_total` | Represents the total number of packets sent per second by the network adapter | counter | `adapter` |
### Hyper-V Virtual Network Adapter Drop Reasons
| Name | Description | Type | Labels |
|-------------------------------------------------------|----------------------------------------------|---------|--------------------------------|
| `windows_hyperv_virtual_network_adapter_drop_reasons` | Hyper-V Virtual Network Adapter Drop Reasons | counter | `adapter`,`direction`,`reason` |
### Hyper-V Virtual SMB
| Name | Description | Type | Labels |
|-------------------------------------------------------|-----------------------------------------------------------------------------------|---------|------------|
| `windows_hyperv_virtual_smb_direct_mapped_sections` | Represents the number of direct-mapped sections in the virtual SMB` | gauge | `instance` |
| `windows_hyperv_virtual_smb_direct_mapped_pages` | Represents the number of direct-mapped pages in the virtual SMB` | gauge | `instance` |
| `windows_hyperv_virtual_smb_write_bytes_rdma` | Represents the number of bytes written per second using RDMA in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_write_bytes` | Represents the number of bytes written per second in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_read_bytes_rdma` | Represents the number of bytes read per second using RDMA in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_read_bytes` | Represents the number of bytes read per second in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_flush_requests` | Represents the number of flush requests per second in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_write_requests_rdma` | Represents the number of write requests per second using RDMA in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_write_requests` | Represents the number of write requests per second in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_read_requests_rdma` | Represents the number of read requests per second using RDMA in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_read_requests` | Represents the number of read requests per second in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_current_pending_requests` | Represents the current number of pending requests in the virtual SMB` | gauge | `instance` |
| `windows_hyperv_virtual_smb_current_open_file_count` | Represents the current number of open files in the virtual SMB` | gauge | `instance` |
| `windows_hyperv_virtual_smb_tree_connect_count` | Represents the number of tree connects in the virtual SMB` | gauge | `instance` |
| `windows_hyperv_virtual_smb_requests` | Represents the number of requests per second in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_sent_bytes` | Represents the number of bytes sent per second in the virtual SMB` | counter | `instance` |
| `windows_hyperv_virtual_smb_received_bytes` | Represents the number of bytes received per second in the virtual SMB` | counter | `instance` |
### Hyper-V Virtual Switch
| Name | Description | Type | Labels |
|---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|---------|-----------|
| `windows_hyperv_vswitch_broadcast_packets_received_total` | Represents the total number of broadcast packets received per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_broadcast_packets_sent_total` | Represents the total number of broadcast packets sent per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_bytes_total` | Represents the total number of bytes per second traversing the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_bytes_received_total` | Represents the total number of bytes received per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_bytes_sent_total` | Represents the total number of bytes sent per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_directed_packets_received_total` | Represents the total number of directed packets received per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_directed_packets_send_total` | Represents the total number of directed packets sent per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_dropped_packets_incoming_total` | Represents the total number of packet dropped per second by the virtual switch in the incoming direction | counter | `vswitch` |
| `windows_hyperv_vswitch_dropped_packets_outcoming_total` | Represents the total number of packet dropped per second by the virtual switch in the outgoing direction | counter | `vswitch` |
| `windows_hyperv_vswitch_extensions_dropped_packets_incoming_total` | Represents the total number of packet dropped per second by the virtual switch extensions in the incoming direction | counter | `vswitch` |
| `windows_hyperv_vswitch_extensions_dropped_packets_outcoming_total` | Represents the total number of packet dropped per second by the virtual switch extensions in the outgoing direction | counter | `vswitch` |
| `windows_hyperv_vswitch_learned_mac_addresses_total` | Represents the total number of learned MAC addresses of the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_multicast_packets_received_total` | Represents the total number of multicast packets received per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_multicast_packets_sent_total` | Represents the total number of multicast packets sent per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_number_of_send_channel_moves_total` | Represents the total number of send channel moves per second on this virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_number_of_vmq_moves_total` | Represents the total number of VMQ moves per second on this virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_packets_flooded_total` | Represents the total number of packets flooded by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_packets_total` | Represents the total number of packets per second traversing the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_packets_received_total` | Represents the total number of packets received per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_packets_sent_total` | Represents the total number of packets send per second by the virtual switch | counter | `vswitch` |
| `windows_hyperv_vswitch_purged_mac_addresses_total` | Represents the total number of purged MAC addresses of the virtual switch | counter | `vswitch` |
### Hyper-V Virtual Storage Device
| Name | Description | Type | Labels |
|---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|---------|----------|
| `windows_hyperv_virtual_storage_device_error_count_total` | Represents the total number of errors that have occurred on this virtual device. | counter | `device` |
| `windows_hyperv_virtual_storage_device_queue_length` | Represents the average queue length on this virtual device. | gauge | `device` |
| `windows_hyperv_virtual_storage_device_bytes_read` | Represents the total number of bytes that have been read on this virtual device. | counter | `device` |
| `windows_hyperv_virtual_storage_device_operations_read_total` | Represents the total number of read operations that have occurred on this virtual device. | counter | `device` |
| `windows_hyperv_virtual_storage_device_bytes_written` | Represents the total number of bytes that have been written on this virtual device. | counter | `device` |
| `windows_hyperv_virtual_storage_device_operations_written_total` | Represents the total number of write operations that have occurred on this virtual device. | counter | `device` |
| `windows_hyperv_virtual_storage_device_latency_seconds` | Represents the average IO transfer latency for this virtual device. | gauge | `device` |
| `windows_hyperv_virtual_storage_device_throughput` | Represents the average number of 8KB IO transfers completed by this virtual device. | gauge | `device` |
| `windows_hyperv_virtual_storage_device_normalized_throughput` | Represents the average number of IO transfers completed by this virtual device. | gauge | `device` |
| `windows_hyperv_virtual_storage_device_lower_queue_length` | Represents the average queue length on the underlying storage subsystem for this device. | gauge | `device` |
| `windows_hyperv_virtual_storage_device_lower_latency_seconds` | Represents the average IO transfer latency on the underlying storage subsystem for this virtual device. | gauge | `device` |
| `windows_hyperv_virtual_storage_device_io_quota_replenishment_rate` | Represents the IO quota replenishment rate for this virtual device. | gauge | `device` |
### Hyper-V VM Vid Partition
| Name | Description | Type | Labels |
|------------------------------------------------|-------------------------------------------------------------------------|-------|--------|
| `windows_hyperv_vid_physical_pages_allocated` | The number of physical pages allocated | gauge | `vm` |
| `windows_hyperv_vid_preferred_numa_node_index` | The preferred NUMA node index associated with this partition | gauge | `vm` |
| `windows_hyperv_vid_remote_physical_pages` | The number of physical pages not allocated from the preferred NUMA node | gauge | `vm` |
### Hyper-V Virtual Machine Health Summary
| Name | Description | Type | Labels |
|------------------------------------------------------|-------------------------------------------------------|-------|--------|
| `windows_hyperv_virtual_machine_health_total_count` | Represents the number of virtual machines with health | gauge | None |
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_
@@ -113,19 +265,19 @@ _This collector does not yet have explained examples, we would appreciate your h
## Useful queries
Percent of physical CPU resources used per VM (on instance "localhost")
```
(sum (rate(windows_hyperv_vm_cpu_hypervisor_run_time{instance="localhost"}[1m]))) / ignoring(vm) group_left max (windows_cs_logical_processors{instance="localhost"}) / 100000
(sum (rate(windows_hyperv_hypervisor_virtual_processor_time_total{state="hypervisor",instance="localhost"}[1m]))) / ignoring(state,vm) group_left max (windows_cpu_logical_processor{instance="localhost"}) / 100000
```
Percent of physical CPU resources used by all VMs (on all monitored hosts)
```
(sum by (instance)(rate(windows_hyperv_vm_cpu_total_run_time{}[1m]))) / max by (instance)(windows_cs_logical_processors{}) / 100000
(sum by (instance)(rate(windows_hyperv_hypervisor_virtual_processor_total_run_time_total{}[1m]))) / max by (instance)(windows_cpu_logical_processor{}) / 100000
```
Percent of physical CPU resources by the hosts themselves (on all monitored hosts)
```
(sum by (instance)(rate(windows_hyperv_host_cpu_total_run_time{}[1m]))) / sum by (instance)(windows_cs_logical_processors{}) / 100000
(sum by (instance)(rate(windows_hyperv_hypervisor_root_virtual_processor_total_run_time_total{state="total"}[1m]))) / sum by (instance)(windows_cpu_logical_processor{}) / 100000
```
Percent of physical CPU resources by the hypervisor (on all monitored hosts)
```
(sum by (instance)(rate(windows_hyperv_host_lp_total_run_time_percent{}[1m]))) / sum by (instance)(windows_hyperv_hypervisor_logical_processors{}) / 100000
(sum by (instance)(rate(windows_hyperv_hypervisor_logical_processor_total_run_time_total{}[1m]))) / sum by (instance)(windows_cpu_logical_processor{}) / 100000
```
## Alerting examples

View File

@@ -2,13 +2,11 @@
The logon collector exposes metrics detailing the active user logon sessions.
|||
-|-
Metric name prefix | `logon`
Classes | [`Win32_LogonSession`](https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-logonsession)
Enabled by default? | No
> :warning: **On some deployments, this collector seems to have some memory/timeout issues**: See [#583](https://github.com/prometheus-community/windows_exporter/issues/583)
| | |
|---------------------|-----------|
| Metric name prefix | `logon` |
| Source | Win32 API |
| Enabled by default? | No |
## Flags
@@ -16,21 +14,65 @@ None
## Metrics
Name | Description | Type | Labels
-----|-------------|------|-------
`windows_logon_logon_type` | Number of active user logon sessions | gauge | status
| Name | Description | Type | Labels |
|-------------------------------------------|--------------------------------------------|-------|------------------------------------|
| `windows_logon_session_logon_timestamp_seconds` | timestamp of the logon session in seconds. | gauge | `domain`, `id`, `type`, `username` |
### Example metric
Query the total number of interactive logon sessions
```
windows_logon_logon_type{status="interactive"}
# HELP windows_logon_session_logon_timestamp_seconds timestamp of the logon session in seconds.
# TYPE windows_logon_session_logon_timestamp_seconds gauge
windows_logon_session_logon_timestamp_seconds{domain="",id="0x0:0x8c54",type="System",username=""} 1.72876928e+09
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x991a",type="Interactive",username="UMFD-1"} 1.728769282e+09
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x9933",type="Interactive",username="UMFD-0"} 1.728769282e+09
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x994a",type="Interactive",username="UMFD-0"} 1.728769282e+09
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x999d",type="Interactive",username="UMFD-1"} 1.728769282e+09
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0xbf25a",type="Interactive",username="UMFD-2"} 1.728769532e+09
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0xbf290",type="Interactive",username="UMFD-2"} 1.728769532e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x130241",type="Network",username="vm-jok-dev$"} 1.728769625e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x24f7c9",type="Network",username="vm-jok-dev$"} 1.728770121e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x276846",type="Network",username="vm-jok-dev$"} 1.728770195e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x3e4",type="Service",username="vm-jok-dev$"} 1.728769283e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x3e7",type="System",username="vm-jok-dev$"} 1.728769279e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x71d0f",type="Network",username="vm-jok-dev$"} 1.728769324e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x720a3",type="Network",username="vm-jok-dev$"} 1.728769324e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x725cb",type="Network",username="vm-jok-dev$"} 1.728769324e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x753d8",type="Network",username="vm-jok-dev$"} 1.728769325e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0xa3913",type="Network",username="vm-jok-dev$"} 1.728769385e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0xbe7f2",type="Network",username="jok"} 1.728769531e+09
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0xc76c4",type="RemoteInteractive",username="jok"} 1.728769533e+09
windows_logon_session_logon_timestamp_seconds{domain="NT AUTHORITY",id="0x0:0x3e3",type="Service",username="IUSR"} 1.728769295e+09
windows_logon_session_logon_timestamp_seconds{domain="NT AUTHORITY",id="0x0:0x3e5",type="Service",username="LOCAL SERVICE"} 1.728769283e+09
windows_logon_session_logon_timestamp_seconds{domain="NT Service",id="0x0:0xae4c7",type="Service",username="MSSQLSERVER"} 1.728769425e+09
windows_logon_session_logon_timestamp_seconds{domain="NT Service",id="0x0:0xb42f1",type="Service",username="SQLTELEMETRY"} 1.728769431e+09
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xbfbac",type="Interactive",username="DWM-2"} 1.728769532e+09
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xbfc72",type="Interactive",username="DWM-2"} 1.728769532e+09
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xdedd",type="Interactive",username="DWM-1"} 1.728769283e+09
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xdefd",type="Interactive",username="DWM-1"} 1.728769283e+09
```
### Possible values for `type`
- System
- Interactive
- Network
- Batch
- Service
- Proxy
- Unlock
- NetworkCleartext
- NewCredentials
- RemoteInteractive
- CachedInteractive
- CachedRemoteInteractive
- CachedUnlock
## Useful queries
Query the total number of local and remote (I.E. Terminal Services) interactive sessions.
```
windows_logon_logon_type{status=~"interactive|remote_interactive"}
count(windows_logon_logon_type{type=~"Interactive|RemoteInteractive"}) by (type)
```
## Alerting examples
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
_This collector doesnt yet have alerting examples, we would appreciate your help adding them!_

View File

@@ -2,26 +2,22 @@
The msmq collector exposes metrics about the queues on a MSMQ server
|||
-|-
Metric name prefix | `msmq`
Classes | `Win32_PerfRawData_MSMQ_MSMQQueue`
Enabled by default? | No
| | |
|---------------------|----------------------|
| Metric name prefix | `msmq` |
| Spource | Performance Counters |
| Enabled by default? | No |
## Flags
### `--collector.msmq.msmq-where`
A WMI filter on which queues to include. `%` is a wildcard, and can be used to match on substrings.
## Metrics
Name | Description | Type | Labels
-----|-------------|------|-------
`windows_msmq_bytes_in_journal_queue` | Size of queue journal in bytes | gauge | `name`
`windows_msmq_bytes_in_queue` | Size of queue in bytes | gauge | `name`
`windows_msmq_messages_in_journal_queue` | Count messages in queue journal | gauge | `name`
`windows_msmq_messages_in_queue` | Count messages in queue | gauge | `name`
| Name | Description | Type | Labels |
|------------------------------------------|---------------------------------|-------|--------|
| `windows_msmq_bytes_in_journal_queue` | Size of queue journal in bytes | gauge | `name` |
| `windows_msmq_bytes_in_queue` | Size of queue in bytes | gauge | `name` |
| `windows_msmq_messages_in_journal_queue` | Count messages in queue journal | gauge | `name` |
| `windows_msmq_messages_in_queue` | Count messages in queue | gauge | `name` |
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_

View File

@@ -16,246 +16,247 @@ Comma-separated list of MSSQL WMI classes to use. Supported values are `accessme
### `--collectors.mssql.class-print`
If true, print available mssql WMI classes and exit. Only displays if the mssql collector is enabled.
If true, print available mssql WMI classes and exit. Only displays if the mssql collector is enabled.fman`, `databases`, `dbreplica`, `genstats`, `locks`, `memmgr`, `sqlstats`, `sqlerrors`, `transactions`, and `waitstats`.
## Metrics
Name | Description | Type | Labels
-----|-------------|------|-------
`windows_mssql_collector_duration_seconds` | The time taken for each sub-collector to return | gauge | `collector`, `mssql_instance`
`windows_mssql_collector_success` | 1 if sub-collector succeeded, 0 otherwise | gauge | `collector`, `mssql_instance`
`windows_mssql_accessmethods_au_batch_cleanups` | The total number of batches that were completed successfully by the background task that cleans up deferred dropped allocation units | counter | `mssql_instance`
`windows_mssql_accessmethods_au_cleanups` | The total number of allocation units that were successfully dropped the background task that cleans up deferred dropped allocation units. Each allocation unit drop requires multiple batches | counter | `mssql_instance`
`windows_mssql_accessmethods_by_reference_lob_creates` | The total count of large object (lob) values that were passed by reference. By-reference lobs are used in certain bulk operations to avoid the cost of passing them by value | counter | `mssql_instance`
`windows_mssql_accessmethods_by_reference_lob_uses` | The total count of by-reference lob values that were used. By-reference lobs are used in certain bulk operations to avoid the cost of passing them by-value | counter | `mssql_instance`
`windows_mssql_accessmethods_lob_read_aheads` | The total count of lob pages on which readahead was issued | counter | `mssql_instance`
`windows_mssql_accessmethods_column_value_pulls` | The total count of column values that were pulled in-row from off-row | counter | `mssql_instance`
`windows_mssql_accessmethods_column_value_pushes` | The total count of column values that were pushed from in-row to off-row | counter | `mssql_instance`
`windows_mssql_accessmethods_deferred_dropped_aus` | The total number of allocation units waiting to be dropped by the background task that cleans up deferred dropped allocation units | gauge | `mssql_instance`
`windows_mssql_accessmethods_deferred_dropped_rowsets` | The number of rowsets created as a result of aborted online index build operations that are waiting to be dropped by the background task that cleans up deferred dropped rowsets | gauge | `mssql_instance`
`windows_mssql_accessmethods_dropped_rowset_cleanups` | The number of rowsets per second created as a result of aborted online index build operations that were successfully dropped by the background task that cleans up deferred dropped rowsets | counter | `mssql_instance`
`windows_mssql_accessmethods_dropped_rowset_skips` | The number of rowsets per second created as a result of aborted online index build operations that were skipped by the background task that cleans up deferred dropped rowsets created | counter | `mssql_instance`
`windows_mssql_accessmethods_extent_deallocations` | Number of extents deallocated per second in all databases in this instance of SQL Server | counter | `mssql_instance`
`windows_mssql_accessmethods_extent_allocations` | Number of extents allocated per second in all databases in this instance of SQL Server | counter | `mssql_instance`
`windows_mssql_accessmethods_au_batch_cleanup_failures` | The number of batches per second that failed and required retry, by the background task that cleans up deferred dropped allocation units. Failure could be due to lack of memory or disk space, hardware failure and other reasons | counter | `mssql_instance`
`windows_mssql_accessmethods_leaf_page_cookie_failures` | The number of times that a leaf page cookie could not be used during an index search since changes happened on the leaf page. The cookie is used to speed up index search | counter | `mssql_instance`
`windows_mssql_accessmethods_tree_page_cookie_failures` | The number of times that a tree page cookie could not be used during an index search since changes happened on the parent pages of those tree pages. The cookie is used to speed up index search | counter | `mssql_instance`
`windows_mssql_accessmethods_forwarded_records` | Number of records per second fetched through forwarded record pointers | counter | `mssql_instance`
`windows_mssql_accessmethods_free_space_page_fetches` | Number of pages fetched per second by free space scans. These scans search for free space within pages already allocated to an allocation unit, to satisfy requests to insert or modify record fragments | counter | `mssql_instance`
`windows_mssql_accessmethods_free_space_scans` | Number of scans per second that were initiated to search for free space within pages already allocated to an allocation unit to insert or modify record fragment. Each scan may find multiple pages | counter | `mssql_instance`
`windows_mssql_accessmethods_full_scans` | Number of unrestricted full scans per second. These can be either base-table or full-index scans | counter | `mssql_instance`
`windows_mssql_accessmethods_index_searches` | Number of index searches per second. These are used to start a range scan, reposition a range scan, revalidate a scan point, fetch a single index record, and search down the index to locate where to insert a new row | counter | `mssql_instance`
`windows_mssql_accessmethods_insysxact_waits` | Number of times a reader needs to wait for a page because the InSysXact bit is set | counter | `mssql_instance`
`windows_mssql_accessmethods_lob_handle_creates` | Count of temporary lobs created | counter | `mssql_instance`
`windows_mssql_accessmethods_lob_handle_destroys` | Count of temporary lobs destroyed | counter | `mssql_instance`
`windows_mssql_accessmethods_lob_ss_provider_creates` | Count of LOB Storage Service Providers (LobSSP) created. One worktable created per LobSSP | counter | `mssql_instance`
`windows_mssql_accessmethods_lob_ss_provider_destroys` | Count of LobSSP destroyed | counter | `mssql_instance`
`windows_mssql_accessmethods_lob_ss_provider_truncations` | Count of LobSSP truncated | counter | `mssql_instance`
`windows_mssql_accessmethods_mixed_page_allocations` | Number of pages allocated per second from mixed extents. These could be used for storing the IAM pages and the first eight pages that are allocated to an allocation unit | counter | `mssql_instance`
`windows_mssql_accessmethods_page_compression_attempts` | Number of pages evaluated for page-level compression. Includes pages that were not compressed because significant savings could be achieved. Includes all objects in the instance of SQL Server | counter | `mssql_instance`
`windows_mssql_accessmethods_page_deallocations` | Number of pages deallocated per second in all databases in this instance of SQL Server. These include pages from mixed extents and uniform extents | counter | `mssql_instance`
`windows_mssql_accessmethods_page_allocations` | Number of pages allocated per second in all databases in this instance of SQL Server. These include pages allocations from both mixed extents and uniform extents | counter | `mssql_instance`
`windows_mssql_accessmethods_page_compressions` | Number of data pages that are compressed by using PAGE compression. Includes all objects in the instance of SQL Server | counter | `mssql_instance`
`windows_mssql_accessmethods_page_splits` | Number of page splits per second that occur as the result of overflowing index pages | counter | `mssql_instance`
`windows_mssql_accessmethods_probe_scans` | Number of probe scans per second that are used to find at most one single qualified row in an index or base table directly | counter | `mssql_instance`
`windows_mssql_accessmethods_range_scans` | Number of qualified range scans through indexes per second | counter | `mssql_instance`
`windows_mssql_accessmethods_scan_point_revalidations` | Number of times per second that the scan point had to be revalidated to continue the scan | counter | `mssql_instance`
`windows_mssql_accessmethods_ghost_record_skips` | Number of ghosted records per second skipped during scans | counter | `mssql_instance`
`windows_mssql_accessmethods_table_lock_escalations` | Number of times locks on a table were escalated to the TABLE or HoBT granularity | counter | `mssql_instance`
`windows_mssql_accessmethods_leaf_page_cookie_uses` | Number of times a leaf page cookie is used successfully during an index search since no change happened on the leaf page. The cookie is used to speed up index search | counter | `mssql_instance`
`windows_mssql_accessmethods_tree_page_cookie_uses` | Number of times a tree page cookie is used successfully during an index search since no change happened on the parent page of the tree page. The cookie is used to speed up index search | counter | `mssql_instance`
`windows_mssql_accessmethods_workfile_creates` | Number of work files created per second. For example, work files could be used to store temporary results for hash joins and hash aggregates | counter | `mssql_instance`
`windows_mssql_accessmethods_worktables_creates` | Number of work tables created per second. For example, work tables could be used to store temporary results for query spool, lob variables, XML variables, and cursors | counter | `mssql_instance`
`windows_mssql_accessmethods_worktables_from_cache_ratio` | Percentage of work tables created where the initial two pages of the work table were not allocated but were immediately available from the work table cache | counter | `mssql_instance`
`windows_mssql_availreplica_received_from_replica_bytes` | Number of bytes received from the availability replica per second. Pings and status updates will generate network traffic even on databases with no user updates | counter | `mssql_instance`, `replica`
`windows_mssql_availreplica_sent_to_replica_bytes` | Number of bytes sent to the remote availability replica per second. On the primary replica this is the number of bytes sent to the secondary replica. On the secondary replica this is the number of bytes sent to the primary replica | counter | `mssql_instance`, `replica`
`windows_mssql_availreplica_sent_to_transport_bytes` | Actual number of bytes sent per second over the network to the remote availability replica. On the primary replica this is the number of bytes sent to the secondary replica. On the secondary replica this is the number of bytes sent to the primary replica | counter | `mssql_instance`, `replica`
`windows_mssql_availreplica_initiated_flow_controls` | Time in milliseconds that log stream messages waited for send flow control, in the last second | counter | `mssql_instance`, `replica`
`windows_mssql_availreplica_flow_control_wait_seconds` | Number of times flow-control initiated in the last second. Flow Control Time (ms/sec) divided by Flow Control/sec is the average time per wait | counter | `mssql_instance`, `replica`
`windows_mssql_availreplica_receives_from_replica` | Number of Always On messages received from thereplica per second | counter | `mssql_instance`, `replica`
`windows_mssql_availreplica_resent_messages` | Number of Always On messages resent in the last second | counter | `mssql_instance`, `replica`
`windows_mssql_availreplica_sends_to_replica` | Number of Always On messages sent to this availability replica per second | counter | `mssql_instance`, `replica`
`windows_mssql_availreplica_sends_to_transport` | Actual number of Always On messages sent per second over the network to the remote availability replica | counter | `mssql_instance`, `replica`
`windows_mssql_bufman_background_writer_pages` | Number of pages flushed to enforce the recovery interval settings | counter | `mssql_instance`
`windows_mssql_bufman_buffer_cache_hit_ratio` | Indicates the percentage of pages found in the buffer cache without having to read from disk. The ratio is the total number of cache hits divided by the total number of cache lookups over the last few thousand page accesses | gauge | `mssql_instance`
`windows_mssql_bufman_checkpoint_pages` | Indicates the number of pages flushed to disk per second by a checkpoint or other operation that require all dirty pages to be flushed | counter | `mssql_instance`
`windows_mssql_bufman_database_pages` | Indicates the number of pages in the buffer pool with database content | gauge | `mssql_instance`
`windows_mssql_bufman_extension_allocated_pages` | Total number of non-free cache pages in the buffer pool extension file | gauge | `mssql_instance`
`windows_mssql_bufman_extension_free_pages` | Total number of free cache pages in the buffer pool extension file | gauge | `mssql_instance`
`windows_mssql_bufman_extension_in_use_as_percentage` | _Not yet documented_ | gauge | `mssql_instance`
`windows_mssql_bufman_extension_outstanding_io` | Percentage of the buffer pool extension paging file occupied by buffer manager pages | gauge | `mssql_instance`
`windows_mssql_bufman_extension_page_evictions` | Number of pages evicted from the buffer pool extension file per second | counter | `mssql_instance`
`windows_mssql_bufman_extension_page_reads` | Number of pages read from the buffer pool extension file per second | counter | `mssql_instance`
`windows_mssql_bufman_extension_page_unreferenced_seconds` | Average seconds a page will stay in the buffer pool extension without references to it | gauge | `mssql_instance`
`windows_mssql_bufman_extension_page_writes` | Number of pages written to the buffer pool extension file per second | counter | `mssql_instance`
`windows_mssql_bufman_free_list_stalls` | Indicates the number of requests per second that had to wait for a free page | counter | `mssql_instance`
`windows_mssql_bufman_integral_controller_slope` | The slope that integral controller for the buffer pool last used, times -10 billion | gauge | `mssql_instance`
`windows_mssql_bufman_lazywrites` | Indicates the number of buffers written per second by the buffer manager's lazy writer | counter | `mssql_instance`
`windows_mssql_bufman_page_life_expectancy_seconds` | Indicates the number of seconds a page will stay in the buffer pool without references | gauge | `mssql_instance`
`windows_mssql_bufman_page_lookups` | Indicates the number of requests per second to find a page in the buffer pool | counter | `mssql_instance`
`windows_mssql_bufman_page_reads` | Indicates the number of physical database page reads that are issued per second | counter | `mssql_instance`
`windows_mssql_bufman_page_writes` | Indicates the number of physical database page writes that are issued per second | counter | `mssql_instance`
`windows_mssql_bufman_read_ahead_pages` | Indicates the number of pages read per second in anticipation of use | counter | `mssql_instance`
`windows_mssql_bufman_read_ahead_issuing_seconds` | Time (microseconds) spent issuing readahead | counter | `mssql_instance`
`windows_mssql_bufman_target_pages` | Ideal number of pages in the buffer pool | gauge | `mssql_instance`
`windows_mssql_dbreplica_database_flow_control_wait_seconds` | _Not yet documented_ | gauge | `mssql_instance`, `replica`
`windows_mssql_dbreplica_database_initiated_flow_controls` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_received_file_bytes` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_group_commits` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_group_commit_stall_seconds` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_apply_pending_queue` | _Not yet documented_ | gauge | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_apply_ready_queue` | _Not yet documented_ | gauge | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_compressed_bytes` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_decompressed_bytes` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_received_bytes` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_compression_cachehits` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_compression_cachemisses` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_compressions` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_decompressions` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_remaining_for_undo` | The amount of log, in bytes, remaining to complete the undo phase | gauge | `mssql_instance`, `replica`
`windows_mssql_dbreplica_log_send_queue` | Amount of log records in the log files of the primary database, in kilobytes, that haven't been sent to the secondary replica | gauge | `mssql_instance`, `replica`
`windows_mssql_dbreplica_mirrored_write_transactions` | Number of transactions that were written to the primary database and then waited to commit until the log was sent to the secondary database, in the last second | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_recovery_queue_records` | Amount of log records in the log files of the secondary replica that have not been redone | gauge | `mssql_instance`, `replica`
`windows_mssql_dbreplica_redo_blocks` | Number of times the redo thread was blocked on locks held by readers of the database | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_redo_remaining_bytes` | The amount of log, in kilobytes, remaining to be redone to finish the reverting phase | gauge | `mssql_instance`, `replica`
`windows_mssql_dbreplica_redone_bytes` | Amount of log records redone on the secondary database in the last second | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_redones` | _Not yet documented_ | counter | `mssql_instance`, `replica`
`windows_mssql_dbreplica_total_log_requiring_undo` | Total kilobytes of log that must be undone | gauge | `mssql_instance`, `replica`
`windows_mssql_dbreplica_transaction_delay_seconds` | Delay in waiting for unterminated commit acknowledgment for all the current transactions | gauge | `mssql_instance`, `replica`
`windows_mssql_databases_active_transactions` | Number of active transactions for the database | gauge | `mssql_instance`, `database`
`windows_mssql_databases_backup_restore_operations` | Read/write throughput for backup and restore operations of a database per second | counter | `mssql_instance`, `database`
`windows_mssql_databases_bulk_copy_rows` | Number of rows bulk copied per second | counter | `mssql_instance`, `database`
`windows_mssql_databases_bulk_copy_bytes` | Amount of data bulk copied (in kilobytes) per second | counter | `mssql_instance`, `database`
`windows_mssql_databases_commit_table_entries` | he size (row count) of the in-memory portion of the commit table for the database | gauge | `mssql_instance`, `database`
`windows_mssql_databases_data_files_size_bytes` | Cumulative size (in kilobytes) of all the data files in the database including any automatic growth. Monitoring this counter is useful, for example, for determining the correct size of tempdb | gauge | `mssql_instance`, `database`
`windows_mssql_databases_dbcc_logical_scan_bytes` | Number of logical read scan bytes per second for database console commands (DBCC) | counter | `mssql_instance`, `database`
`windows_mssql_databases_group_commit_stall_seconds` | Group stall time (microseconds) per second | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_flushed_bytes` | Total number of log bytes flushed | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_cache_hit_ratio` | Percentage of log cache reads satisfied from the log cache | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_cache_reads` | Reads performed per second through the log manager cache | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_files_size_bytes` | Cumulative size (in kilobytes) of all the transaction log files in the database | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_files_used_size_bytes` | The cumulative used size of all the log files in the database | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_flushes` | Total wait time (in milliseconds) to flush the log. On an Always On secondary database, this value indicates the wait time for log records to be hardened to disk | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_flush_waits` | Number of commits per second waiting for the log flush | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_flush_wait_seconds` | Number of commits per second waiting for the log flush | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_flush_write_seconds` | Time in milliseconds for performing writes of log flushes that were completed in the last second | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_growths` | Total number of times the transaction log for the database has been expanded | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_cache_misses` | Number of requests for which the log block was not available in the log pool | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_disk_reads` | Number of disk reads that the log pool issued to fetch log blocks | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_hash_deletes` | Rate of raw hash entry deletes from the Log Pool | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_hash_inserts` | Rate of raw hash entry inserts into the Log Pool | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_invalid_hash_entries` | Rate of hash lookups failing due to being invalid | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_log_scan_pushes` | Rate of Log block pushes by log scans, which may come from disk or memory | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_log_writer_pushes` | Rate of Log block pushes by log writer thread | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_empty_free_pool_pushes` | Rate of Log block push fails due to empty free pool | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_low_memory_pushes` | Rate of Log block push fails due to being low on memory | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_no_free_buffer_pushes` | Rate of Log block push fails due to free buffer unavailable | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_req_behind_trunc` | Log pool cache misses due to block requested being behind truncation LSN | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_requests_old_vlf` | Log Pool requests that were not in the last VLF of the log | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_requests` | The number of log-block requests processed by the log pool | counter | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_total_active_log_bytes` | Current total active log stored in the shared cache buffer manager in bytes | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_pool_total_shared_pool_bytes` | Current total memory usage of the shared cache buffer manager in bytes | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_shrinks` | Total number of log shrinks for this database | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_truncations` | The number of times the transaction log has been truncated (in Simple Recovery Model) | gauge | `mssql_instance`, `database`
`windows_mssql_databases_log_used_percent` | Percentage of space in the log that is in use | gauge | `mssql_instance`, `database`
`windows_mssql_databases_pending_repl_transactions` | Number of transactions in the transaction log of the publication database marked for replication, but not yet delivered to the distribution database | gauge | `mssql_instance`, `database`
`windows_mssql_databases_repl_transactions` | Number of transactions per second read out of the transaction log of the publication database and delivered to the distribution database | counter | `mssql_instance`, `database`
`windows_mssql_databases_shrink_data_movement_bytes` | Amount of data being moved per second by autoshrink operations, or DBCC SHRINKDATABASE or DBCC SHRINKFILE statements | counter | `mssql_instance`, `database`
`windows_mssql_databases_tracked_transactions` | Number of committed transactions recorded in the commit table for the database | counter | `mssql_instance`, `database`
`windows_mssql_databases_transactions` | Number of transactions started for the database per second | counter | `mssql_instance`, `database`
`windows_mssql_databases_write_transactions` | Number of transactions that wrote to the database and committed, in the last second | counter | `mssql_instance`, `database`
`windows_mssql_databases_xtp_controller_dlc_fetch_latency_seconds` | Average latency in microseconds between log blocks entering the Direct Log Consumer and being retrieved by the XTP controller, per second | gauge | `mssql_instance`, `database`
`windows_mssql_databases_xtp_controller_dlc_peak_latency_seconds` | The largest recorded latency, in microseconds, of a fetch from the Direct Log Consumer by the XTP controller | gauge | `mssql_instance`, `database`
`windows_mssql_databases_xtp_controller_log_processed_bytes` | The amount of log bytes processed by the XTP controller thread, per second | counter | `mssql_instance`, `database`
`windows_mssql_databases_xtp_memory_used_bytes` | The amount of memory used by XTP in the database | gauge | `mssql_instance`, `database`
`windows_mssql_genstats_active_temp_tables` | Number of temporary tables/table variables in use | gauge | `mssql_instance`
`windows_mssql_genstats_connection_resets` | Total number of logins started from the connection pool | counter | `mssql_instance`
`windows_mssql_genstats_event_notifications_delayed_drop` | Number of event notifications waiting to be dropped by a system thread | gauge | `mssql_instance`
`windows_mssql_genstats_http_authenticated_requests` | Number of authenticated HTTP requests started per second | gauge | `mssql_instance`
`windows_mssql_genstats_logical_connections` | Number of logical connections to the system | gauge | `mssql_instance`
`windows_mssql_genstats_logins` | Total number of logins started per second. This does not include pooled connections | counter | `mssql_instance`
`windows_mssql_genstats_logouts` | Total number of logout operations started per second | counter | `mssql_instance`
`windows_mssql_genstats_mars_deadlocks` | Number of MARS deadlocks detected | gauge | `mssql_instance`
`windows_mssql_genstats_non_atomic_yields` | Number of non-atomic yields per second | counter | `mssql_instance`
`windows_mssql_genstats_blocked_processes` | Number of currently blocked processes | gauge | `mssql_instance`
`windows_mssql_genstats_soap_empty_requests` | Number of empty SOAP requests started per second | gauge | `mssql_instance`
`windows_mssql_genstats_soap_method_invocations` | Number of SOAP method invocations started per second | gauge | `mssql_instance`
`windows_mssql_genstats_soap_session_initiate_requests` | Number of SOAP Session initiate requests started per second | gauge | `mssql_instance`
`windows_mssql_genstats_soap_session_terminate_requests` | Number of SOAP Session terminate requests started per second | gauge | `mssql_instance`
`windows_mssql_genstats_soapsql_requests` | Number of SOAP SQL requests started per second | gauge | `mssql_instance`
`windows_mssql_genstats_soapwsdl_requests` | Number of SOAP Web Service Description Language requests started per second | gauge | `mssql_instance`
`windows_mssql_genstats_sql_trace_io_provider_lock_waits` | Number of waits for the File IO Provider lock per second | gauge | `mssql_instance`
`windows_mssql_genstats_tempdb_recovery_unit_ids_generated` | Number of duplicate tempdb recovery unit id generated | gauge | `mssql_instance`
`windows_mssql_genstats_tempdb_rowset_ids_generated` | Number of duplicate tempdb rowset id generated | gauge | `mssql_instance`
`windows_mssql_genstats_temp_tables_creations` | Number of temporary tables/table variables created per second | counter | `mssql_instance`
`windows_mssql_genstats_temp_tables_awaiting_destruction` | Number of temporary tables/table variables waiting to be destroyed by the cleanup system thread | gauge | `mssql_instance`
`windows_mssql_genstats_trace_event_notification_queue_size` | Number of trace event notification instances waiting in the internal queue to be sent through Service Broker | gauge | `mssql_instance`
`windows_mssql_genstats_transactions` | Number of transaction enlistments (local, DTC, bound all combined) | gauge | `mssql_instance`
`windows_mssql_genstats_user_connections` | Counts the number of users currently connected to SQL Server | gauge | `mssql_instance`
`windows_mssql_locks_average_wait_seconds` | Average amount of wait time (in milliseconds) for each lock request that resulted in a wait | gauge | `mssql_instance`, `resource`
`windows_mssql_locks_lock_requests` | Number of new locks and lock conversions per second requested from the lock manager | counter | `mssql_instance`, `resource`
`windows_mssql_locks_lock_timeouts` | Number of lock requests per second that timed out, including requests for NOWAIT locks | counter | `mssql_instance`, `resource`
`windows_mssql_locks_lock_timeouts_excluding_NOWAIT` | Number of lock requests per second that timed out, but excluding requests for NOWAIT locks | counter | `mssql_instance`, `resource`
`windows_mssql_locks_lock_waits` | Total wait time (in milliseconds) for locks in the last second | counter | `mssql_instance`, `resource`
`windows_mssql_locks_lock_wait_seconds` | Number of lock requests per second that required the caller to wait | gauge | `mssql_instance`, `resource`
`windows_mssql_locks_deadlocks` | Number of lock requests per second that resulted in a deadlock | counter | `mssql_instance`, `resource`
`windows_mssql_memmgr_connection_memory_bytes` | Specifies the total amount of dynamic memory the server is using for maintaining connections | gauge | `mssql_instance`
`windows_mssql_memmgr_database_cache_memory_bytes` | Specifies the amount of memory the server is currently using for the database pages cache | gauge | `mssql_instance`
`windows_mssql_memmgr_external_benefit_of_memory` | An internal estimation of the performance benefit from adding memory to a specific cache | gauge | `mssql_instance`
`windows_mssql_memmgr_free_memory_bytes` | Specifies the amount of committed memory currently not used by the server | gauge | `mssql_instance`
`windows_mssql_memmgr_granted_workspace_memory_bytes` | Specifies the total amount of memory currently granted to executing processes, such as hash, sort, bulk copy, and index creation operations | gauge | `mssql_instance`
`windows_mssql_memmgr_lock_blocks` | Specifies the current number of lock blocks in use on the server (refreshed periodically). A lock block represents an individual locked resource, such as a table, page, or row | gauge | `mssql_instance`
`windows_mssql_memmgr_allocated_lock_blocks` | Specifies the current number of allocated lock blocks. At server startup, the number of allocated lock blocks plus the number of allocated lock owner blocks depends on the SQL Server Locks configuration option. If more lock blocks are needed, the value increases | gauge | `mssql_instance`
`windows_mssql_memmgr_lock_memory_bytes` | Specifies the total amount of dynamic memory the server is using for locks | gauge | `mssql_instance`
`windows_mssql_memmgr_lock_owner_blocks` | Specifies the current number of allocated lock owner blocks. At server startup, the number of allocated lock owner blocks and the number of allocated lock blocks depend on the SQL Server Locks configuration option. If more lock owner blocks are needed, the value increases dynamically | gauge | `mssql_instance`
`windows_mssql_memmgr_allocated_lock_owner_blocks` | _Not yet documented_ | gauge | `mssql_instance`
`windows_mssql_memmgr_log_pool_memory_bytes` | Total amount of dynamic memory the server is using for Log Pool | gauge | `mssql_instance`
`windows_mssql_memmgr_maximum_workspace_memory_bytes` | Indicates the maximum amount of memory available for executing processes, such as hash, sort, bulk copy, and index creation operations | gauge | `mssql_instance`
`windows_mssql_memmgr_outstanding_memory_grants` | Specifies the total number of processes that have successfully acquired a workspace memory grant | gauge | `mssql_instance`
`windows_mssql_memmgr_pending_memory_grants` | Specifies the total number of processes waiting for a workspace memory grant | gauge | `mssql_instance`
`windows_mssql_memmgr_optimizer_memory_bytes` | Specifies the total amount of dynamic memory the server is using for query optimization | gauge | `mssql_instance`
`windows_mssql_memmgr_reserved_server_memory_bytes` | ndicates the amount of memory the server has reserved for future usage. This counter shows the current unused amount of memory initially granted that is shown in Granted Workspace Memory | gauge | `mssql_instance`
`windows_mssql_memmgr_sql_cache_memory_bytes` | Specifies the total amount of dynamic memory the server is using for the dynamic SQL cache | gauge | `mssql_instance`
`windows_mssql_memmgr_stolen_server_memory_bytes` | Specifies the amount of memory the server is using for purposes other than database pages | gauge | `mssql_instance`
`windows_mssql_memmgr_target_server_memory_bytes` | Indicates the ideal amount of memory the server can consume | gauge | `mssql_instance`
`windows_mssql_memmgr_total_server_memory_bytes` | Specifies the amount of memory the server has committed using the memory manager | gauge | `mssql_instance`
`windows_mssql_sqlstats_auto_parameterization_attempts` | Number of failed auto-parameterization attempts per second. This should be small. Note that auto-parameterizations are also known as simple parameterizations in later versions of SQL Server | counter | `mssql_instance`
`windows_mssql_sqlstats_batch_requests` | _Not yet documented_ | counter | `mssql_instance`
`windows_mssql_sqlstats_failed_auto_parameterization_attempts` | _Not yet documented_ | counter | `mssql_instance`
`windows_mssql_sqlstats_forced_parameterizations` | Number of successful forced parameterizations per second | counter | `mssql_instance`
`windows_mssql_sqlstats_guided_plan_executions` | Number of plan executions per second in which the query plan has been generated by using a plan guide | counter | `mssql_instance`
`windows_mssql_sqlstats_misguided_plan_executions` | Number of plan executions per second in which a plan guide could not be honored during plan generation | counter | `mssql_instance`
`windows_mssql_sqlstats_safe_auto_parameterization_attempts` | Number of safe auto-parameterization attempts per second | counter | `mssql_instance`
`windows_mssql_sqlstats_sql_attentions` | Number of attentions per second | counter | `mssql_instance`
`windows_mssql_sqlstats_sql_compilations` | Number of SQL compilations per second | counter | `mssql_instance`
`windows_mssql_sqlstats_sql_recompilations` | Number of statement recompiles per second | counter | `mssql_instance`
`windows_mssql_sqlstats_unsafe_auto_parameterization_attempts` | Number of unsafe auto-parameterization attempts per second. | counter | `mssql_instance`
`windows_mssql_sql_errors_total` | Information for all errors | counter | `mssql_instance`, `resource`
`windows_mssql_transactions_tempdb_free_space_bytes` | The amount of space (in kilobytes) available in tempdb | gauge | `mssql_instance`
`windows_mssql_transactions_longest_transaction_running_seconds` | The length of time (in seconds) since the start of the transaction that has been active longer than any other current transaction | gauge | `mssql_instance`
`windows_mssql_transactions_nonsnapshot_version_active_total` | The number of currently active transactions that are not using snapshot isolation level and have made data modifications that have generated row versions in the tempdb version store | counter | `mssql_instance`
`windows_mssql_transactions_snapshot_active_total` | The number of currently active transactions using the snapshot isolation level | counter | `mssql_instance`
`windows_mssql_transactions_active` | The number of currently active transactions of all types | gauge | `mssql_instance`
`windows_mssql_transactions_update_conflicts_total` | The percentage of those transactions using the snapshot isolation level that have encountered update conflicts within the last second | counter | `mssql_instance`
`windows_mssql_transactions_update_snapshot_active_total` | The number of currently active transactions using the snapshot isolation level and have modified data | counter | `mssql_instance`
`windows_mssql_transactions_version_cleanup_rate_bytes` | The rate (in kilobytes per second) at which row versions are removed from the snapshot isolation version store in tempdb | gauge | `mssql_instance`
`windows_mssql_transactions_version_generation_rate_bytes` | The rate (in kilobytes per second) at which new row versions are added to the snapshot isolation version store in tempdb | gauge | `mssql_instance`
`windows_mssql_transactions_version_store_size_bytes` | he amount of space (in kilobytes) in tempdb being used to store snapshot isolation level row versions | gauge | `mssql_instance`
`windows_mssql_transactions_version_store_units` | The number of active allocation units in the snapshot isolation version store in tempdb | counter | `mssql_instance`
`windows_mssql_transactions_version_store_creation_units` | The number of allocation units that have been created in the snapshot isolation store since the instance of the Database Engine was started | counter | `mssql_instance`
`windows_mssql_transactions_version_store_truncation_units` | The number of allocation units that have been removed from the snapshot isolation store since the instance of the Database Engine was started | counter | `mssql_instance`
`windows_mssql_waitstats_lock_waits` | Statistics for processes waiting on a lock | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_memory_grant_queue_waits` | Statistics for processes waiting for memory grant to become available | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_thread_safe_memory_objects_waits` | Statistics for processes waiting on thread-safe memory allocators | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_log_write_waits` | Statistics for processes waiting for log buffer to be written | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_log_buffer_waits` | Statistics for processes waiting for log buffer to be available | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_network_io_waits` | Statistics relevant to wait on network I/O | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_page_io_latch_waits` | Statistics relevant to page I/O latches | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_page_latch_waits` | Statistics relevant to page latches, not including I/O latches | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_nonpage_latch_waits` | Statistics relevant to non-page latches | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_wait_for_the_worker_waits` | Statistics relevant to processes waiting for worker to become available | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_workspace_synchronization_waits` | Statistics relevant to processes synchronizing access to workspace | gauge | `mssql_instance`, `item`
`windows_mssql_waitstats_transaction_ownership_waits` | Statistics relevant to processes synchronizing access to transaction | gauge | `mssql_instance`, `item`
| Name | Description | Type | Labels |
|--------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-------------------------------|
| `windows_mssql_collector_duration_seconds` | The time taken for each sub-collector to return | gauge | `collector`, `mssql_instance` |
| `windows_mssql_collector_success` | 1 if sub-collector succeeded, 0 otherwise | gauge | `collector`, `mssql_instance` |
| `windows_mssql_accessmethods_au_batch_cleanups` | The total number of batches that were completed successfully by the background task that cleans up deferred dropped allocation units | counter | `mssql_instance` |
| `windows_mssql_accessmethods_au_cleanups` | The total number of allocation units that were successfully dropped the background task that cleans up deferred dropped allocation units. Each allocation unit drop requires multiple batches | counter | `mssql_instance` |
| `windows_mssql_accessmethods_by_reference_lob_creates` | The total count of large object (lob) values that were passed by reference. By-reference lobs are used in certain bulk operations to avoid the cost of passing them by value | counter | `mssql_instance` |
| `windows_mssql_accessmethods_by_reference_lob_uses` | The total count of by-reference lob values that were used. By-reference lobs are used in certain bulk operations to avoid the cost of passing them by-value | counter | `mssql_instance` |
| `windows_mssql_accessmethods_lob_read_aheads` | The total count of lob pages on which readahead was issued | counter | `mssql_instance` |
| `windows_mssql_accessmethods_column_value_pulls` | The total count of column values that were pulled in-row from off-row | counter | `mssql_instance` |
| `windows_mssql_accessmethods_column_value_pushes` | The total count of column values that were pushed from in-row to off-row | counter | `mssql_instance` |
| `windows_mssql_accessmethods_deferred_dropped_aus` | The total number of allocation units waiting to be dropped by the background task that cleans up deferred dropped allocation units | gauge | `mssql_instance` |
| `windows_mssql_accessmethods_deferred_dropped_rowsets` | The number of rowsets created as a result of aborted online index build operations that are waiting to be dropped by the background task that cleans up deferred dropped rowsets | gauge | `mssql_instance` |
| `windows_mssql_accessmethods_dropped_rowset_cleanups` | The number of rowsets per second created as a result of aborted online index build operations that were successfully dropped by the background task that cleans up deferred dropped rowsets | counter | `mssql_instance` |
| `windows_mssql_accessmethods_dropped_rowset_skips` | The number of rowsets per second created as a result of aborted online index build operations that were skipped by the background task that cleans up deferred dropped rowsets created | counter | `mssql_instance` |
| `windows_mssql_accessmethods_extent_deallocations` | Number of extents deallocated per second in all databases in this instance of SQL Server | counter | `mssql_instance` |
| `windows_mssql_accessmethods_extent_allocations` | Number of extents allocated per second in all databases in this instance of SQL Server | counter | `mssql_instance` |
| `windows_mssql_accessmethods_au_batch_cleanup_failures` | The number of batches per second that failed and required retry, by the background task that cleans up deferred dropped allocation units. Failure could be due to lack of memory or disk space, hardware failure and other reasons | counter | `mssql_instance` |
| `windows_mssql_accessmethods_leaf_page_cookie_failures` | The number of times that a leaf page cookie could not be used during an index search since changes happened on the leaf page. The cookie is used to speed up index search | counter | `mssql_instance` |
| `windows_mssql_accessmethods_tree_page_cookie_failures` | The number of times that a tree page cookie could not be used during an index search since changes happened on the parent pages of those tree pages. The cookie is used to speed up index search | counter | `mssql_instance` |
| `windows_mssql_accessmethods_forwarded_records` | Number of records per second fetched through forwarded record pointers | counter | `mssql_instance` |
| `windows_mssql_accessmethods_free_space_page_fetches` | Number of pages fetched per second by free space scans. These scans search for free space within pages already allocated to an allocation unit, to satisfy requests to insert or modify record fragments | counter | `mssql_instance` |
| `windows_mssql_accessmethods_free_space_scans` | Number of scans per second that were initiated to search for free space within pages already allocated to an allocation unit to insert or modify record fragment. Each scan may find multiple pages | counter | `mssql_instance` |
| `windows_mssql_accessmethods_full_scans` | Number of unrestricted full scans per second. These can be either base-table or full-index scans | counter | `mssql_instance` |
| `windows_mssql_accessmethods_index_searches` | Number of index searches per second. These are used to start a range scan, reposition a range scan, revalidate a scan point, fetch a single index record, and search down the index to locate where to insert a new row | counter | `mssql_instance` |
| `windows_mssql_accessmethods_insysxact_waits` | Number of times a reader needs to wait for a page because the InSysXact bit is set | counter | `mssql_instance` |
| `windows_mssql_accessmethods_lob_handle_creates` | Count of temporary lobs created | counter | `mssql_instance` |
| `windows_mssql_accessmethods_lob_handle_destroys` | Count of temporary lobs destroyed | counter | `mssql_instance` |
| `windows_mssql_accessmethods_lob_ss_provider_creates` | Count of LOB Storage Service Providers (LobSSP) created. One worktable created per LobSSP | counter | `mssql_instance` |
| `windows_mssql_accessmethods_lob_ss_provider_destroys` | Count of LobSSP destroyed | counter | `mssql_instance` |
| `windows_mssql_accessmethods_lob_ss_provider_truncations` | Count of LobSSP truncated | counter | `mssql_instance` |
| `windows_mssql_accessmethods_mixed_page_allocations` | Number of pages allocated per second from mixed extents. These could be used for storing the IAM pages and the first eight pages that are allocated to an allocation unit | counter | `mssql_instance` |
| `windows_mssql_accessmethods_page_compression_attempts` | Number of pages evaluated for page-level compression. Includes pages that were not compressed because significant savings could be achieved. Includes all objects in the instance of SQL Server | counter | `mssql_instance` |
| `windows_mssql_accessmethods_page_deallocations` | Number of pages deallocated per second in all databases in this instance of SQL Server. These include pages from mixed extents and uniform extents | counter | `mssql_instance` |
| `windows_mssql_accessmethods_page_allocations` | Number of pages allocated per second in all databases in this instance of SQL Server. These include pages allocations from both mixed extents and uniform extents | counter | `mssql_instance` |
| `windows_mssql_accessmethods_page_compressions` | Number of data pages that are compressed by using PAGE compression. Includes all objects in the instance of SQL Server | counter | `mssql_instance` |
| `windows_mssql_accessmethods_page_splits` | Number of page splits per second that occur as the result of overflowing index pages | counter | `mssql_instance` |
| `windows_mssql_accessmethods_probe_scans` | Number of probe scans per second that are used to find at most one single qualified row in an index or base table directly | counter | `mssql_instance` |
| `windows_mssql_accessmethods_range_scans` | Number of qualified range scans through indexes per second | counter | `mssql_instance` |
| `windows_mssql_accessmethods_scan_point_revalidations` | Number of times per second that the scan point had to be revalidated to continue the scan | counter | `mssql_instance` |
| `windows_mssql_accessmethods_ghost_record_skips` | Number of ghosted records per second skipped during scans | counter | `mssql_instance` |
| `windows_mssql_accessmethods_table_lock_escalations` | Number of times locks on a table were escalated to the TABLE or HoBT granularity | counter | `mssql_instance` |
| `windows_mssql_accessmethods_leaf_page_cookie_uses` | Number of times a leaf page cookie is used successfully during an index search since no change happened on the leaf page. The cookie is used to speed up index search | counter | `mssql_instance` |
| `windows_mssql_accessmethods_tree_page_cookie_uses` | Number of times a tree page cookie is used successfully during an index search since no change happened on the parent page of the tree page. The cookie is used to speed up index search | counter | `mssql_instance` |
| `windows_mssql_accessmethods_workfile_creates` | Number of work files created per second. For example, work files could be used to store temporary results for hash joins and hash aggregates | counter | `mssql_instance` |
| `windows_mssql_accessmethods_worktables_creates` | Number of work tables created per second. For example, work tables could be used to store temporary results for query spool, lob variables, XML variables, and cursors | counter | `mssql_instance` |
| `windows_mssql_accessmethods_worktables_from_cache_ratio` | Percentage of work tables created where the initial two pages of the work table were not allocated but were immediately available from the work table cache | counter | `mssql_instance` |
| `windows_mssql_availreplica_received_from_replica_bytes` | Number of bytes received from the availability replica per second. Pings and status updates will generate network traffic even on databases with no user updates | counter | `mssql_instance`, `replica` |
| `windows_mssql_availreplica_sent_to_replica_bytes` | Number of bytes sent to the remote availability replica per second. On the primary replica this is the number of bytes sent to the secondary replica. On the secondary replica this is the number of bytes sent to the primary replica | counter | `mssql_instance`, `replica` |
| `windows_mssql_availreplica_sent_to_transport_bytes` | Actual number of bytes sent per second over the network to the remote availability replica. On the primary replica this is the number of bytes sent to the secondary replica. On the secondary replica this is the number of bytes sent to the primary replica | counter | `mssql_instance`, `replica` |
| `windows_mssql_availreplica_initiated_flow_controls` | Time in milliseconds that log stream messages waited for send flow control, in the last second | counter | `mssql_instance`, `replica` |
| `windows_mssql_availreplica_flow_control_wait_seconds` | Number of times flow-control initiated in the last second. Flow Control Time (ms/sec) divided by Flow Control/sec is the average time per wait | counter | `mssql_instance`, `replica` |
| `windows_mssql_availreplica_receives_from_replica` | Number of Always On messages received from thereplica per second | counter | `mssql_instance`, `replica` |
| `windows_mssql_availreplica_resent_messages` | Number of Always On messages resent in the last second | counter | `mssql_instance`, `replica` |
| `windows_mssql_availreplica_sends_to_replica` | Number of Always On messages sent to this availability replica per second | counter | `mssql_instance`, `replica` |
| `windows_mssql_availreplica_sends_to_transport` | Actual number of Always On messages sent per second over the network to the remote availability replica | counter | `mssql_instance`, `replica` |
| `windows_mssql_bufman_background_writer_pages` | Number of pages flushed to enforce the recovery interval settings | counter | `mssql_instance` |
| `windows_mssql_bufman_buffer_cache_hit_ratio` | Indicates the percentage of pages found in the buffer cache without having to read from disk. The ratio is the total number of cache hits divided by the total number of cache lookups over the last few thousand page accesses | gauge | `mssql_instance` |
| `windows_mssql_bufman_checkpoint_pages` | Indicates the number of pages flushed to disk per second by a checkpoint or other operation that require all dirty pages to be flushed | counter | `mssql_instance` |
| `windows_mssql_bufman_database_pages` | Indicates the number of pages in the buffer pool with database content | gauge | `mssql_instance` |
| `windows_mssql_bufman_extension_allocated_pages` | Total number of non-free cache pages in the buffer pool extension file | gauge | `mssql_instance` |
| `windows_mssql_bufman_extension_free_pages` | Total number of free cache pages in the buffer pool extension file | gauge | `mssql_instance` |
| `windows_mssql_bufman_extension_in_use_as_percentage` | _Not yet documented_ | gauge | `mssql_instance` |
| `windows_mssql_bufman_extension_outstanding_io` | Percentage of the buffer pool extension paging file occupied by buffer manager pages | gauge | `mssql_instance` |
| `windows_mssql_bufman_extension_page_evictions` | Number of pages evicted from the buffer pool extension file per second | counter | `mssql_instance` |
| `windows_mssql_bufman_extension_page_reads` | Number of pages read from the buffer pool extension file per second | counter | `mssql_instance` |
| `windows_mssql_bufman_extension_page_unreferenced_seconds` | Average seconds a page will stay in the buffer pool extension without references to it | gauge | `mssql_instance` |
| `windows_mssql_bufman_extension_page_writes` | Number of pages written to the buffer pool extension file per second | counter | `mssql_instance` |
| `windows_mssql_bufman_free_list_stalls` | Indicates the number of requests per second that had to wait for a free page | counter | `mssql_instance` |
| `windows_mssql_bufman_integral_controller_slope` | The slope that integral controller for the buffer pool last used, times -10 billion | gauge | `mssql_instance` |
| `windows_mssql_bufman_lazywrites` | Indicates the number of buffers written per second by the buffer manager's lazy writer | counter | `mssql_instance` |
| `windows_mssql_bufman_page_life_expectancy_seconds` | Indicates the number of seconds a page will stay in the buffer pool without references | gauge | `mssql_instance` |
| `windows_mssql_bufman_page_lookups` | Indicates the number of requests per second to find a page in the buffer pool | counter | `mssql_instance` |
| `windows_mssql_bufman_page_reads` | Indicates the number of physical database page reads that are issued per second | counter | `mssql_instance` |
| `windows_mssql_bufman_page_writes` | Indicates the number of physical database page writes that are issued per second | counter | `mssql_instance` |
| `windows_mssql_bufman_read_ahead_pages` | Indicates the number of pages read per second in anticipation of use | counter | `mssql_instance` |
| `windows_mssql_bufman_read_ahead_issuing_seconds` | Time (microseconds) spent issuing readahead | counter | `mssql_instance` |
| `windows_mssql_bufman_target_pages` | Ideal number of pages in the buffer pool | gauge | `mssql_instance` |
| `windows_mssql_dbreplica_database_flow_control_wait_seconds` | _Not yet documented_ | gauge | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_database_initiated_flow_controls` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_received_file_bytes` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_group_commits` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_group_commit_stall_seconds` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_apply_pending_queue` | _Not yet documented_ | gauge | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_apply_ready_queue` | _Not yet documented_ | gauge | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_compressed_bytes` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_decompressed_bytes` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_received_bytes` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_compression_cachehits` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_compression_cachemisses` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_compressions` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_decompressions` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_remaining_for_undo` | The amount of log, in bytes, remaining to complete the undo phase | gauge | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_log_send_queue` | Amount of log records in the log files of the primary database, in kilobytes, that haven't been sent to the secondary replica | gauge | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_mirrored_write_transactions` | Number of transactions that were written to the primary database and then waited to commit until the log was sent to the secondary database, in the last second | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_recovery_queue_records` | Amount of log records in the log files of the secondary replica that have not been redone | gauge | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_redo_blocks` | Number of times the redo thread was blocked on locks held by readers of the database | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_redo_remaining_bytes` | The amount of log, in kilobytes, remaining to be redone to finish the reverting phase | gauge | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_redone_bytes` | Amount of log records redone on the secondary database in the last second | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_redones` | _Not yet documented_ | counter | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_total_log_requiring_undo` | Total kilobytes of log that must be undone | gauge | `mssql_instance`, `replica` |
| `windows_mssql_dbreplica_transaction_delay_seconds` | Delay in waiting for unterminated commit acknowledgment for all the current transactions | gauge | `mssql_instance`, `replica` |
| `windows_mssql_databases_active_transactions` | Number of active transactions for the database | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_backup_restore_operations` | Read/write throughput for backup and restore operations of a database per second | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_bulk_copy_rows` | Number of rows bulk copied per second | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_bulk_copy_bytes` | Amount of data bulk copied (in kilobytes) per second | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_commit_table_entries` | he size (row count) of the in-memory portion of the commit table for the database | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_data_files_size_bytes` | Cumulative size (in kilobytes) of all the data files in the database including any automatic growth. Monitoring this counter is useful, for example, for determining the correct size of tempdb | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_dbcc_logical_scan_bytes` | Number of logical read scan bytes per second for database console commands (DBCC) | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_group_commit_stall_seconds` | Group stall time (microseconds) per second | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_flushed_bytes` | Total number of log bytes flushed | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_cache_hit_ratio` | Percentage of log cache reads satisfied from the log cache | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_cache_reads` | Reads performed per second through the log manager cache | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_files_size_bytes` | Cumulative size (in kilobytes) of all the transaction log files in the database | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_files_used_size_bytes` | The cumulative used size of all the log files in the database | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_flushes` | Total wait time (in milliseconds) to flush the log. On an Always On secondary database, this value indicates the wait time for log records to be hardened to disk | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_flush_waits` | Number of commits per second waiting for the log flush | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_flush_wait_seconds` | Number of commits per second waiting for the log flush | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_flush_write_seconds` | Time in milliseconds for performing writes of log flushes that were completed in the last second | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_growths` | Total number of times the transaction log for the database has been expanded | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_cache_misses` | Number of requests for which the log block was not available in the log pool | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_disk_reads` | Number of disk reads that the log pool issued to fetch log blocks | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_hash_deletes` | Rate of raw hash entry deletes from the Log Pool | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_hash_inserts` | Rate of raw hash entry inserts into the Log Pool | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_invalid_hash_entries` | Rate of hash lookups failing due to being invalid | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_log_scan_pushes` | Rate of Log block pushes by log scans, which may come from disk or memory | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_log_writer_pushes` | Rate of Log block pushes by log writer thread | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_empty_free_pool_pushes` | Rate of Log block push fails due to empty free pool | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_low_memory_pushes` | Rate of Log block push fails due to being low on memory | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_no_free_buffer_pushes` | Rate of Log block push fails due to free buffer unavailable | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_req_behind_trunc` | Log pool cache misses due to block requested being behind truncation LSN | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_requests_old_vlf` | Log Pool requests that were not in the last VLF of the log | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_requests` | The number of log-block requests processed by the log pool | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_total_active_log_bytes` | Current total active log stored in the shared cache buffer manager in bytes | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_pool_total_shared_pool_bytes` | Current total memory usage of the shared cache buffer manager in bytes | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_shrinks` | Total number of log shrinks for this database | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_truncations` | The number of times the transaction log has been truncated (in Simple Recovery Model) | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_log_used_percent` | Percentage of space in the log that is in use | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_pending_repl_transactions` | Number of transactions in the transaction log of the publication database marked for replication, but not yet delivered to the distribution database | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_repl_transactions` | Number of transactions per second read out of the transaction log of the publication database and delivered to the distribution database | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_shrink_data_movement_bytes` | Amount of data being moved per second by autoshrink operations, or DBCC SHRINKDATABASE or DBCC SHRINKFILE statements | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_tracked_transactions` | Number of committed transactions recorded in the commit table for the database | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_transactions` | Number of transactions started for the database per second | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_write_transactions` | Number of transactions that wrote to the database and committed, in the last second | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_xtp_controller_dlc_fetch_latency_seconds` | Average latency in microseconds between log blocks entering the Direct Log Consumer and being retrieved by the XTP controller, per second | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_xtp_controller_dlc_peak_latency_seconds` | The largest recorded latency, in microseconds, of a fetch from the Direct Log Consumer by the XTP controller | gauge | `mssql_instance`, `database` |
| `windows_mssql_databases_xtp_controller_log_processed_bytes` | The amount of log bytes processed by the XTP controller thread, per second | counter | `mssql_instance`, `database` |
| `windows_mssql_databases_xtp_memory_used_bytes` | The amount of memory used by XTP in the database | gauge | `mssql_instance`, `database` |
| `windows_mssql_genstats_active_temp_tables` | Number of temporary tables/table variables in use | gauge | `mssql_instance` |
| `windows_mssql_genstats_connection_resets` | Total number of logins started from the connection pool | counter | `mssql_instance` |
| `windows_mssql_genstats_event_notifications_delayed_drop` | Number of event notifications waiting to be dropped by a system thread | gauge | `mssql_instance` |
| `windows_mssql_genstats_http_authenticated_requests` | Number of authenticated HTTP requests started per second | gauge | `mssql_instance` |
| `windows_mssql_genstats_logical_connections` | Number of logical connections to the system | gauge | `mssql_instance` |
| `windows_mssql_genstats_logins` | Total number of logins started per second. This does not include pooled connections | counter | `mssql_instance` |
| `windows_mssql_genstats_logouts` | Total number of logout operations started per second | counter | `mssql_instance` |
| `windows_mssql_genstats_mars_deadlocks` | Number of MARS deadlocks detected | gauge | `mssql_instance` |
| `windows_mssql_genstats_non_atomic_yields` | Number of non-atomic yields per second | counter | `mssql_instance` |
| `windows_mssql_genstats_blocked_processes` | Number of currently blocked processes | gauge | `mssql_instance` |
| `windows_mssql_genstats_soap_empty_requests` | Number of empty SOAP requests started per second | gauge | `mssql_instance` |
| `windows_mssql_genstats_soap_method_invocations` | Number of SOAP method invocations started per second | gauge | `mssql_instance` |
| `windows_mssql_genstats_soap_session_initiate_requests` | Number of SOAP Session initiate requests started per second | gauge | `mssql_instance` |
| `windows_mssql_genstats_soap_session_terminate_requests` | Number of SOAP Session terminate requests started per second | gauge | `mssql_instance` |
| `windows_mssql_genstats_soapsql_requests` | Number of SOAP SQL requests started per second | gauge | `mssql_instance` |
| `windows_mssql_genstats_soapwsdl_requests` | Number of SOAP Web Service Description Language requests started per second | gauge | `mssql_instance` |
| `windows_mssql_genstats_sql_trace_io_provider_lock_waits` | Number of waits for the File IO Provider lock per second | gauge | `mssql_instance` |
| `windows_mssql_genstats_tempdb_recovery_unit_ids_generated` | Number of duplicate tempdb recovery unit id generated | gauge | `mssql_instance` |
| `windows_mssql_genstats_tempdb_rowset_ids_generated` | Number of duplicate tempdb rowset id generated | gauge | `mssql_instance` |
| `windows_mssql_genstats_temp_tables_creations` | Number of temporary tables/table variables created per second | counter | `mssql_instance` |
| `windows_mssql_genstats_temp_tables_awaiting_destruction` | Number of temporary tables/table variables waiting to be destroyed by the cleanup system thread | gauge | `mssql_instance` |
| `windows_mssql_genstats_trace_event_notification_queue_size` | Number of trace event notification instances waiting in the internal queue to be sent through Service Broker | gauge | `mssql_instance` |
| `windows_mssql_genstats_transactions` | Number of transaction enlistments (local, DTC, bound all combined) | gauge | `mssql_instance` |
| `windows_mssql_genstats_user_connections` | Counts the number of users currently connected to SQL Server | gauge | `mssql_instance` |
| `windows_mssql_instance_info ` | Returns information about the MSSQL server running on port 1433 | gauge | `version` |
| `windows_mssql_locks_average_wait_seconds` | Average amount of wait time (in milliseconds) for each lock request that resulted in a wait | gauge | `mssql_instance`, `resource` |
| `windows_mssql_locks_lock_requests` | Number of new locks and lock conversions per second requested from the lock manager | counter | `mssql_instance`, `resource` |
| `windows_mssql_locks_lock_timeouts` | Number of lock requests per second that timed out, including requests for NOWAIT locks | counter | `mssql_instance`, `resource` |
| `windows_mssql_locks_lock_timeouts_excluding_NOWAIT` | Number of lock requests per second that timed out, but excluding requests for NOWAIT locks | counter | `mssql_instance`, `resource` |
| `windows_mssql_locks_lock_waits` | Total wait time (in milliseconds) for locks in the last second | counter | `mssql_instance`, `resource` |
| `windows_mssql_locks_lock_wait_seconds` | Number of lock requests per second that required the caller to wait | gauge | `mssql_instance`, `resource` |
| `windows_mssql_locks_deadlocks` | Number of lock requests per second that resulted in a deadlock | counter | `mssql_instance`, `resource` |
| `windows_mssql_memmgr_connection_memory_bytes` | Specifies the total amount of dynamic memory the server is using for maintaining connections | gauge | `mssql_instance` |
| `windows_mssql_memmgr_database_cache_memory_bytes` | Specifies the amount of memory the server is currently using for the database pages cache | gauge | `mssql_instance` |
| `windows_mssql_memmgr_external_benefit_of_memory` | An internal estimation of the performance benefit from adding memory to a specific cache | gauge | `mssql_instance` |
| `windows_mssql_memmgr_free_memory_bytes` | Specifies the amount of committed memory currently not used by the server | gauge | `mssql_instance` |
| `windows_mssql_memmgr_granted_workspace_memory_bytes` | Specifies the total amount of memory currently granted to executing processes, such as hash, sort, bulk copy, and index creation operations | gauge | `mssql_instance` |
| `windows_mssql_memmgr_lock_blocks` | Specifies the current number of lock blocks in use on the server (refreshed periodically). A lock block represents an individual locked resource, such as a table, page, or row | gauge | `mssql_instance` |
| `windows_mssql_memmgr_allocated_lock_blocks` | Specifies the current number of allocated lock blocks. At server startup, the number of allocated lock blocks plus the number of allocated lock owner blocks depends on the SQL Server Locks configuration option. If more lock blocks are needed, the value increases | gauge | `mssql_instance` |
| `windows_mssql_memmgr_lock_memory_bytes` | Specifies the total amount of dynamic memory the server is using for locks | gauge | `mssql_instance` |
| `windows_mssql_memmgr_lock_owner_blocks` | Specifies the current number of allocated lock owner blocks. At server startup, the number of allocated lock owner blocks and the number of allocated lock blocks depend on the SQL Server Locks configuration option. If more lock owner blocks are needed, the value increases dynamically | gauge | `mssql_instance` |
| `windows_mssql_memmgr_allocated_lock_owner_blocks` | _Not yet documented_ | gauge | `mssql_instance` |
| `windows_mssql_memmgr_log_pool_memory_bytes` | Total amount of dynamic memory the server is using for Log Pool | gauge | `mssql_instance` |
| `windows_mssql_memmgr_maximum_workspace_memory_bytes` | Indicates the maximum amount of memory available for executing processes, such as hash, sort, bulk copy, and index creation operations | gauge | `mssql_instance` |
| `windows_mssql_memmgr_outstanding_memory_grants` | Specifies the total number of processes that have successfully acquired a workspace memory grant | gauge | `mssql_instance` |
| `windows_mssql_memmgr_pending_memory_grants` | Specifies the total number of processes waiting for a workspace memory grant | gauge | `mssql_instance` |
| `windows_mssql_memmgr_optimizer_memory_bytes` | Specifies the total amount of dynamic memory the server is using for query optimization | gauge | `mssql_instance` |
| `windows_mssql_memmgr_reserved_server_memory_bytes` | ndicates the amount of memory the server has reserved for future usage. This counter shows the current unused amount of memory initially granted that is shown in Granted Workspace Memory | gauge | `mssql_instance` |
| `windows_mssql_memmgr_sql_cache_memory_bytes` | Specifies the total amount of dynamic memory the server is using for the dynamic SQL cache | gauge | `mssql_instance` |
| `windows_mssql_memmgr_stolen_server_memory_bytes` | Specifies the amount of memory the server is using for purposes other than database pages | gauge | `mssql_instance` |
| `windows_mssql_memmgr_target_server_memory_bytes` | Indicates the ideal amount of memory the server can consume | gauge | `mssql_instance` |
| `windows_mssql_memmgr_total_server_memory_bytes` | Specifies the amount of memory the server has committed using the memory manager | gauge | `mssql_instance` |
| `windows_mssql_sqlstats_auto_parameterization_attempts` | Number of failed auto-parameterization attempts per second. This should be small. Note that auto-parameterizations are also known as simple parameterizations in later versions of SQL Server | counter | `mssql_instance` |
| `windows_mssql_sqlstats_batch_requests` | _Not yet documented_ | counter | `mssql_instance` |
| `windows_mssql_sqlstats_failed_auto_parameterization_attempts` | _Not yet documented_ | counter | `mssql_instance` |
| `windows_mssql_sqlstats_forced_parameterizations` | Number of successful forced parameterizations per second | counter | `mssql_instance` |
| `windows_mssql_sqlstats_guided_plan_executions` | Number of plan executions per second in which the query plan has been generated by using a plan guide | counter | `mssql_instance` |
| `windows_mssql_sqlstats_misguided_plan_executions` | Number of plan executions per second in which a plan guide could not be honored during plan generation | counter | `mssql_instance` |
| `windows_mssql_sqlstats_safe_auto_parameterization_attempts` | Number of safe auto-parameterization attempts per second | counter | `mssql_instance` |
| `windows_mssql_sqlstats_sql_attentions` | Number of attentions per second | counter | `mssql_instance` |
| `windows_mssql_sqlstats_sql_compilations` | Number of SQL compilations per second | counter | `mssql_instance` |
| `windows_mssql_sqlstats_sql_recompilations` | Number of statement recompiles per second | counter | `mssql_instance` |
| `windows_mssql_sqlstats_unsafe_auto_parameterization_attempts` | Number of unsafe auto-parameterization attempts per second. | counter | `mssql_instance` |
| `windows_mssql_sql_errors_total` | Information for all errors | counter | `mssql_instance`, `resource` |
| `windows_mssql_transactions_tempdb_free_space_bytes` | The amount of space (in kilobytes) available in tempdb | gauge | `mssql_instance` |
| `windows_mssql_transactions_longest_transaction_running_seconds` | The length of time (in seconds) since the start of the transaction that has been active longer than any other current transaction | gauge | `mssql_instance` |
| `windows_mssql_transactions_nonsnapshot_version_active_total` | The number of currently active transactions that are not using snapshot isolation level and have made data modifications that have generated row versions in the tempdb version store | counter | `mssql_instance` |
| `windows_mssql_transactions_snapshot_active_total` | The number of currently active transactions using the snapshot isolation level | counter | `mssql_instance` |
| `windows_mssql_transactions_active` | The number of currently active transactions of all types | gauge | `mssql_instance` |
| `windows_mssql_transactions_update_conflicts_total` | The percentage of those transactions using the snapshot isolation level that have encountered update conflicts within the last second | counter | `mssql_instance` |
| `windows_mssql_transactions_update_snapshot_active_total` | The number of currently active transactions using the snapshot isolation level and have modified data | counter | `mssql_instance` |
| `windows_mssql_transactions_version_cleanup_rate_bytes` | The rate (in kilobytes per second) at which row versions are removed from the snapshot isolation version store in tempdb | gauge | `mssql_instance` |
| `windows_mssql_transactions_version_generation_rate_bytes` | The rate (in kilobytes per second) at which new row versions are added to the snapshot isolation version store in tempdb | gauge | `mssql_instance` |
| `windows_mssql_transactions_version_store_size_bytes` | he amount of space (in kilobytes) in tempdb being used to store snapshot isolation level row versions | gauge | `mssql_instance` |
| `windows_mssql_transactions_version_store_units` | The number of active allocation units in the snapshot isolation version store in tempdb | counter | `mssql_instance` |
| `windows_mssql_transactions_version_store_creation_units` | The number of allocation units that have been created in the snapshot isolation store since the instance of the Database Engine was started | counter | `mssql_instance` |
| `windows_mssql_transactions_version_store_truncation_units` | The number of allocation units that have been removed from the snapshot isolation store since the instance of the Database Engine was started | counter | `mssql_instance` |
| `windows_mssql_waitstats_lock_waits` | Statistics for processes waiting on a lock | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_memory_grant_queue_waits` | Statistics for processes waiting for memory grant to become available | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_thread_safe_memory_objects_waits` | Statistics for processes waiting on thread-safe memory allocators | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_log_write_waits` | Statistics for processes waiting for log buffer to be written | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_log_buffer_waits` | Statistics for processes waiting for log buffer to be available | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_network_io_waits` | Statistics relevant to wait on network I/O | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_page_io_latch_waits` | Statistics relevant to page I/O latches | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_page_latch_waits` | Statistics relevant to page latches, not including I/O latches | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_nonpage_latch_waits` | Statistics relevant to non-page latches | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_wait_for_the_worker_waits` | Statistics relevant to processes waiting for worker to become available | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_workspace_synchronization_waits` | Statistics relevant to processes synchronizing access to workspace | gauge | `mssql_instance`, `item` |
| `windows_mssql_waitstats_transaction_ownership_waits` | Statistics relevant to processes synchronizing access to transaction | gauge | `mssql_instance`, `item` |
### Example metric
@@ -311,4 +312,4 @@ groups:
summary: "SQl EXpress Database size exceeded 10GB"
description: "The database size has grown larger than 10GB. Instance: {{ $labels.instance }}"
```
```

View File

@@ -14,13 +14,11 @@ None
## Metrics
| Name | Description | Type | Labels |
|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|------------------------------------------------------------------------|
| `windows_os_info` | Contains full product name & version in labels. Note that the `major_version` for Windows 11 is "10"; a build number greater than 22000 represents Windows 11. | gauge | `product`, `version`, `major_version`, `minor_version`, `build_number` |
| `windows_os_paging_limit_bytes` | Total number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files | gauge | None |
| `windows_os_paging_free_bytes` | Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out | gauge | None |
| Name | Description | Type | Labels |
|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|------------------------------------------------------------------------|
| `windows_os_hostname` | Labelled system hostname information as provided by ComputerSystem.DNSHostName and ComputerSystem.Domain | gauge | `domain`, `fqdn`, `hostname` |
| `windows_os_info` | Contains full product name & version in labels. Note that the `major_version` for Windows 11 is "10"; a build number greater than 22000 represents Windows 11. | gauge | `product`, `version`, `major_version`, `minor_version`, `build_number` |
### Example metric
```
@@ -36,4 +34,4 @@ windows_os_info{build_number="19045",major_version="10",minor_version="0",produc
_This collector does not yet have useful queries, we would appreciate your help adding them!_
## Alerting examples
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
_This collector does not yet have alerting examples, we would appreciate your help adding them!_

View File

@@ -0,0 +1,38 @@
# pagefile collector
The pagefile collector exposes metrics about the pagefile usage
|||
-|-
Metric name prefix | `pagefile`
Classes | [`Win32_OperatingSystem`](https://msdn.microsoft.com/en-us/library/aa394239)
Enabled by default? | Yes
## Flags
None
## Metrics
| Name | Description | Type | Labels |
|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------|-------|--------|
| `windows_pagefile_free_bytes` | Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out | gauge | `file` |
| `windows_pagefile_limit_bytes` | Number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files | gauge | `file` |
### Example metric
```
# HELP windows_pagefile_free_bytes OperatingSystem.FreeSpaceInPagingFiles
# TYPE windows_pagefile_free_bytes gauge
windows_pagefile_free_bytes{file="C:\\pagefile.sys"} 6.025797632e+09
# HELP windows_pagefile_limit_bytes OperatingSystem.SizeStoredInPagingFiles
# TYPE windows_pagefile_limit_bytes gauge
windows_pagefile_limit_bytes{file="C:\\pagefile.sys"} 6.442450944e+09
```
## Useful queries
_This collector does not yet have useful queries, we would appreciate your help adding them!_
## Alerting examples
_This collector does not yet have alerting examples, we would appreciate your help adding them!_

View File

@@ -1,114 +0,0 @@
# Perfdata collector
The perfdata collector exposes any configured metric.
| | |
|---------------------|-------------------------|
| Metric name prefix | `perfdata` |
| Data source | Performance Data Helper |
| Enabled by default? | No |
## Flags
### `--collector.perfdata.objects`
Objects is a list of objects to collect metrics from. The value takes the form of a JSON array of strings. YAML is also supported.
The collector supports only english named counter. Localized counter-names are not supported.
#### Schema
YAML:
```yaml
- object: "Processor Information"
instances: ["*"]
instance_label: "core"
counters:
"% Processor Time": {}
- object: "Memory"
counters:
"Cache Faults/sec":
type: "counter"
```
JSON:
```json
[
{"object":"Processor Information","instance_label": "core","instances":["*"],"counters": {"% Processor Time": {}}},
{"object":"Memory","counters": {"Cache Faults/sec": {"type": "counter"}}}
]
```
#### name
ObjectName is the Object to query for, like Processor, DirectoryServices, LogicalDisk or similar.
The collector supports only english named counter. Localized counter-names are not supported.
#### instances
The instances key (this is an array) declares the instances of a counter you would like returned, it can be one or more values.
Example: Instances = `["C:","D:","E:"]`
This will return only for the instances C:, D: and E: where relevant. To get all instances of a Counter, use `["*"]` only.
Some Objects like `Memory` do not have instances to select from at all. In this case, the `instances` key can be omitted.
#### counters
The Counters key (this is an object) declares the counters of the ObjectName you would like returned, it can also be one or more values.
Example: Counters = `{"% Idle Time": {}, "% Disk Read Time": {}, "% Disk Write Time": {}}`
This must be specified for every counter you want the results. Wildcards are not supported.
#### counters Sub-Schema
##### type
This key is optional. It indicates the type of the counter. The value can be `counter` or `gauge`.
If not specified, the windows_exporter will try to determine the type based on the counter type.
### Example
```
# HELP windows_perfdata_memory_cache_faults_sec
# TYPE windows_perfdata_memory_cache_faults_sec counter
windows_perfdata_memory_cache_faults_sec 2.369977e+07
# HELP windows_perfdata_processor_information__processor_time
# TYPE windows_perfdata_processor_information__processor_time gauge
windows_perfdata_processor_information__processor_time{instance="0,0"} 1.7259640625e+11
windows_perfdata_processor_information__processor_time{instance="0,1"} 1.7576796875e+11
windows_perfdata_processor_information__processor_time{instance="0,10"} 2.2704234375e+11
windows_perfdata_processor_information__processor_time{instance="0,11"} 2.3069296875e+11
windows_perfdata_processor_information__processor_time{instance="0,12"} 2.3302265625e+11
windows_perfdata_processor_information__processor_time{instance="0,13"} 2.32851875e+11
windows_perfdata_processor_information__processor_time{instance="0,14"} 2.3282421875e+11
windows_perfdata_processor_information__processor_time{instance="0,15"} 2.3271234375e+11
windows_perfdata_processor_information__processor_time{instance="0,16"} 2.329590625e+11
windows_perfdata_processor_information__processor_time{instance="0,17"} 2.32800625e+11
windows_perfdata_processor_information__processor_time{instance="0,18"} 2.3194359375e+11
windows_perfdata_processor_information__processor_time{instance="0,19"} 2.32380625e+11
windows_perfdata_processor_information__processor_time{instance="0,2"} 1.954765625e+11
windows_perfdata_processor_information__processor_time{instance="0,20"} 2.3259765625e+11
windows_perfdata_processor_information__processor_time{instance="0,21"} 2.3268515625e+11
windows_perfdata_processor_information__processor_time{instance="0,22"} 2.3301765625e+11
windows_perfdata_processor_information__processor_time{instance="0,23"} 2.3264328125e+11
windows_perfdata_processor_information__processor_time{instance="0,3"} 1.94745625e+11
windows_perfdata_processor_information__processor_time{instance="0,4"} 2.2011453125e+11
windows_perfdata_processor_information__processor_time{instance="0,5"} 2.27244375e+11
windows_perfdata_processor_information__processor_time{instance="0,6"} 2.25501875e+11
windows_perfdata_processor_information__processor_time{instance="0,7"} 2.2995265625e+11
windows_perfdata_processor_information__processor_time{instance="0,8"} 2.2929890625e+11
windows_perfdata_processor_information__processor_time{instance="0,9"} 2.313540625e+11
windows_perfdata_processor_information__processor_time{instance="0,_Total"} 2.23009459635e+11
```
## Metrics
The perfdata collector returns metrics based on the user configuration.
The metrics are named based on the object name and the counter name.
The instance name is added as a label to the metric.

View File

@@ -0,0 +1,262 @@
# performancecounter collector
The performancecounter collector exposes any configured metric.
| | |
|---------------------|-------------------------|
| Metric name prefix | `performancecounter` |
| Data source | Performance Data Helper |
| Enabled by default? | No |
## Flags
### `--collector.performancecounter.objects`
Objects is a list of objects to collect metrics from. The value takes the form of a JSON array of strings.
YAML is supported.
The collector supports only English-named counter. Localized counter-names arent supported.
> [!CAUTION]
> If you are using a configuration file, the value must be kept as a string.
>
> Use a `|-` to keep the value as a string.
#### Example
```yaml
collector:
performancecounter:
objects: |-
- name: memory
object: "Memory"
counters:
- name: "Cache Faults/sec"
type: "counter" # optional
```
#### Schema
YAML:
<details>
<summary>Click to expand YAML schema</summary>
```yaml
- name: cpu # free text name
object: "Processor Information" # Performance counter object name
instances: ["*"]
instance_label: "core"
counters:
- name: "% Processor Time"
metric: windows_performancecounter_processor_information_processor_time # optional
labels:
state: active
- name: "% Idle Time"
metric: windows_performancecounter_processor_information_processor_time # optional
labels:
state: idle
- name: memory
object: "Memory"
type: "formatted"
counters:
- name: "Cache Faults/sec"
type: "counter" # optional
```
</details>
<details>
<summary>Click to expand JSON schema</summary>
```json
[
{
"name": "cpu",
"object": "Processor Information",
"instances": [
"*"
],
"instance_label": "core",
"counters": [
{
"name": "% Processor Time",
"metric": "windows_performancecounter_processor_information_processor_time",
"labels": {
"state": "active"
}
},
{
"name": "% Idle Time",
"metric": "windows_performancecounter_processor_information_processor_time",
"labels": {
"state": "idle"
}
}
]
},
{
"name": "memory",
"object": "Memory",
"type": "formatted",
"counters": [
{
"name": "Cache Faults/sec",
"type": "counter"
}
]
}
]
```
</details>
#### name
The name is used to identify the object in the logs and metrics.
Must unique across all objects.
#### object
ObjectName is the Object to query for, like Processor, DirectoryServices, LogicalDisk or similar.
The collector supports only english named counter. Localized counter-names are not supported.
#### type
The counter-type. The value can be `raw` or `formatted`. Optional and defaults to `raw`.
- `raw` returns the raw value of the counter. This is the default.
- `formatted` returns the formatted value of the counter. This is useful for counters like `Processor Information` where the value is a percentage.
The difference between a raw Windows Performance Counter and a formatted Windows Performance Counter is about how the data is presented and processed:
1. Raw Windows Performance Counter:
This provides the counter's data in its basic, unprocessed form.
The values may represent cumulative counts, time intervals, or other uncalibrated metrics.
Interpreting these values often requires more calculations or context, such as calculating deltas or normalizing values over time.
2. Formatted Windows Performance Counter:
This presents data that has already been processed and interpreted according to the counter type (e.g., rates per second, averages, percentages).
Formatted counters are easier to understand directly since the necessary calculations have been applied.
These are often what monitoring tools display to users because they are meaningful at a glance.
For example:
* A raw counter for CPU time might give the total number of clock ticks used since the system started.
* A formatted counter would convert this into a percentage of CPU utilization over a specific time interval.
#### instances
The instances key (this is an array) declares the instances of a counter you would like returned, it can be one or more values.
Example: Instances = `["C:","D:","E:"]`
This will return only for the instances C:, D: and E: where relevant. To get all instances of a Counter, use `["*"]` only.
Some Objects like `Memory` do not have instances to select from at all. In this case, the `instances` key can be omitted.
#### counters
List of counters to collect from the object. See the counters sub-schema for more information.
#### counters Sub-Schema
##### name
The name of the counter to collect.
##### metric
It indicates the name of the metric to be exposed. If not specified, the metric name will be generated based on the object name and the counter name.
This key is optional.
##### type
It indicates the type of the counter. The value can be `counter` or `gauge`.
If not specified, the windows_exporter will try to determine the type based on the counter type.
This key is optional.
##### labels
Labels is a map of key-value pairs that will be added as labels to the metric.
### Example
```
# HELP windows_performancecounter_memory_cache_faults_sec
# TYPE windows_performancecounter_memory_cache_faults_sec counter
windows_performancecounter_memory_cache_faults_sec 7.028097e+06
# HELP windows_performancecounter_processor_information_processor_time
# TYPE windows_performancecounter_processor_information_processor_time counter
windows_performancecounter_processor_information_processor_time{core="0,0",state="active"} 8.3809375e+10
windows_performancecounter_processor_information_processor_time{core="0,0",state="idle"} 8380.9375
windows_performancecounter_processor_information_processor_time{core="0,1",state="active"} 8.2868125e+10
windows_performancecounter_processor_information_processor_time{core="0,1",state="idle"} 8286.8125
windows_performancecounter_processor_information_processor_time{core="0,10",state="active"} 9.720046875e+10
windows_performancecounter_processor_information_processor_time{core="0,10",state="idle"} 9720.046875
windows_performancecounter_processor_information_processor_time{core="0,11",state="active"} 9.994921875e+10
windows_performancecounter_processor_information_processor_time{core="0,11",state="idle"} 9994.921875
windows_performancecounter_processor_information_processor_time{core="0,12",state="active"} 1.014403125e+11
windows_performancecounter_processor_information_processor_time{core="0,12",state="idle"} 10144.03125
windows_performancecounter_processor_information_processor_time{core="0,13",state="active"} 1.0155453125e+11
windows_performancecounter_processor_information_processor_time{core="0,13",state="idle"} 10155.453125
windows_performancecounter_processor_information_processor_time{core="0,14",state="active"} 1.01290625e+11
windows_performancecounter_processor_information_processor_time{core="0,14",state="idle"} 10129.0625
windows_performancecounter_processor_information_processor_time{core="0,15",state="active"} 1.0134890625e+11
windows_performancecounter_processor_information_processor_time{core="0,15",state="idle"} 10134.890625
windows_performancecounter_processor_information_processor_time{core="0,16",state="active"} 1.01405625e+11
windows_performancecounter_processor_information_processor_time{core="0,16",state="idle"} 10140.5625
windows_performancecounter_processor_information_processor_time{core="0,17",state="active"} 1.0153421875e+11
windows_performancecounter_processor_information_processor_time{core="0,17",state="idle"} 10153.421875
windows_performancecounter_processor_information_processor_time{core="0,18",state="active"} 1.0086390625e+11
windows_performancecounter_processor_information_processor_time{core="0,18",state="idle"} 10086.390625
windows_performancecounter_processor_information_processor_time{core="0,19",state="active"} 1.0123453125e+11
windows_performancecounter_processor_information_processor_time{core="0,19",state="idle"} 10123.453125
windows_performancecounter_processor_information_processor_time{core="0,2",state="active"} 8.3548125e+10
windows_performancecounter_processor_information_processor_time{core="0,2",state="idle"} 8354.8125
windows_performancecounter_processor_information_processor_time{core="0,20",state="active"} 1.011703125e+11
windows_performancecounter_processor_information_processor_time{core="0,20",state="idle"} 10117.03125
windows_performancecounter_processor_information_processor_time{core="0,21",state="active"} 1.0140984375e+11
windows_performancecounter_processor_information_processor_time{core="0,21",state="idle"} 10140.984375
windows_performancecounter_processor_information_processor_time{core="0,22",state="active"} 1.014615625e+11
windows_performancecounter_processor_information_processor_time{core="0,22",state="idle"} 10146.15625
windows_performancecounter_processor_information_processor_time{core="0,23",state="active"} 1.0145125e+11
windows_performancecounter_processor_information_processor_time{core="0,23",state="idle"} 10145.125
windows_performancecounter_processor_information_processor_time{core="0,3",state="active"} 8.488953125e+10
windows_performancecounter_processor_information_processor_time{core="0,3",state="idle"} 8488.953125
windows_performancecounter_processor_information_processor_time{core="0,4",state="active"} 9.338234375e+10
windows_performancecounter_processor_information_processor_time{core="0,4",state="idle"} 9338.234375
windows_performancecounter_processor_information_processor_time{core="0,5",state="active"} 9.776453125e+10
windows_performancecounter_processor_information_processor_time{core="0,5",state="idle"} 9776.453125
windows_performancecounter_processor_information_processor_time{core="0,6",state="active"} 9.736265625e+10
windows_performancecounter_processor_information_processor_time{core="0,6",state="idle"} 9736.265625
windows_performancecounter_processor_information_processor_time{core="0,7",state="active"} 9.959375e+10
windows_performancecounter_processor_information_processor_time{core="0,7",state="idle"} 9959.375
windows_performancecounter_processor_information_processor_time{core="0,8",state="active"} 9.939421875e+10
windows_performancecounter_processor_information_processor_time{core="0,8",state="idle"} 9939.421875
windows_performancecounter_processor_information_processor_time{core="0,9",state="active"} 1.0059484375e+11
windows_performancecounter_processor_information_processor_time{core="0,9",state="idle"} 10059.484375
```
> [!NOTE]
> If you are using a configuration file, the value must be keep as string.
Example:
```yaml
collector:
performancecounter:
objects: |
```
## Metrics
The perfdata collector returns metrics based on the user configuration.
The metrics are named based on the object name and the counter name.
The instance name is added as a label to the metric.

View File

@@ -35,7 +35,7 @@ metrics.
Enables IIS process name queries. IIS process names are combined with their app pool name to form the `process` label.
Disabled by default, and can be enabled with `--collector.process.iis=true`.
Disabled by default, and can be enabled with `--collector.process.iis`. NOTE: Just plain parameter without `true`.
### Example
@@ -44,7 +44,7 @@ Note that multiple processes with the same name will be disambiguated by
Windows by adding a number suffix, such as `firefox#2`. Your [regexp](https://en.wikipedia.org/wiki/Regular_expression) must take
these suffixes into consideration.
:warning: The regexp is case-sensitive, so `--collector.process.include="FIREFOX.*"` will **NOT** match a process named `firefox` .
:warning: The regexp is case-sensitive, so `--collector.process.include="FIREFOX.*"` will **NOT** match a process named `firefox` .
To specify multiple names, use the pipe `|` character:
```

View File

@@ -14,16 +14,16 @@ None
## Metrics
| Name | Description | Type | Labels |
|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
| `windows_system_context_switches_total` | Total number of [context switches](https://en.wikipedia.org/wiki/Context_switch) | counter | None |
| `windows_system_exception_dispatches_total` | Total exceptions dispatched by the system | counter | None |
| `windows_system_processes` | Number of process contexts currently loaded or running on the operating system | gauge | None |
| `windows_system_process_limit` | The size of the user-mode portion of the virtual address space of the calling process, in bytes. This value depends on the type of process, the type of processor, and the configuration of the operating system. | gauge | None |
| `windows_system_processor_queue_length` | Number of threads in the processor queue. There is a single queue for processor time even on computers with multiple processors. | gauge | None |
| `windows_system_system_calls_total` | Total combined calls to Windows NT system service routines by all processes running on the computer | counter | None |
| `windows_system_system_up_time` | Time of last boot of system | gauge | None |
| `windows_system_threads` | Number of Windows system [threads](https://en.wikipedia.org/wiki/Thread_(computing)) | gauge | None |
| Name | Description | Type | Labels |
|----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
| `windows_system_boot_time_timestamp_seconds` | Unix timestamp of last system boot | gauge | None |
| `windows_system_context_switches_total` | Total number of [context switches](https://en.wikipedia.org/wiki/Context_switch) | counter | None |
| `windows_system_exception_dispatches_total` | Total exceptions dispatched by the system | counter | None |
| `windows_system_processes` | Number of process contexts currently loaded or running on the operating system | gauge | None |
| `windows_system_process_limit` | The size of the user-mode portion of the virtual address space of the calling process, in bytes. This value depends on the type of process, the type of processor, and the configuration of the operating system. | gauge | None |
| `windows_system_processor_queue_length` | Number of threads in the processor queue. There is a single queue for processor time even on computers with multiple processors. | gauge | None |
| `windows_system_system_calls_total` | Total combined calls to Windows NT system service routines by all processes running on the computer | counter | None |
| `windows_system_threads` | Number of Windows system [threads](https://en.wikipedia.org/wiki/Thread_(computing)) | gauge | None |
@@ -41,7 +41,7 @@ windows_system_processes{instance="localhost"}
## Useful queries
Find hosts that have rebooted in the last 24 hours
```
time() - windows_system_system_up_time < 86400
time() - windows_system_boot_time_timestamp_seconds < 86400
```
## Alerting examples

View File

@@ -1,12 +1,11 @@
# tcp collector
The tcp collector exposes metrics about the TCP/IPv4 network stack.
The tcp collector exposes metrics about the TCP network stack.
|||
-|-
Metric name prefix | `tcp`
Data source | Perflib
Classes | [`Win32_PerfRawData_Tcpip_TCPv4`](https://msdn.microsoft.com/en-us/library/aa394341(v=vs.85).aspx), Win32_PerfRawData_Tcpip_TCPv6
Enabled by default? | No
## Flags
@@ -15,17 +14,18 @@ None
## Metrics
Name | Description | Type | Labels
-----|-------------|------|-------
`windows_tcp_connection_failures_total` | Number of times TCP connections have made a direct transition to the CLOSED state from the SYN-SENT state or the SYN-RCVD state, plus the number of times TCP connections have made a direct transition from the SYN-RCVD state to the LISTEN state | counter | af
`windows_tcp_connections_active_total` | Number of times TCP connections have made a direct transition from the CLOSED state to the SYN-SENT state.| counter | af
`windows_tcp_connections_established` | Number of TCP connections for which the current state is either ESTABLISHED or CLOSE-WAIT. | gauge | af
`windows_tcp_connections_passive_total` | Number of times TCP connections have made a direct transition from the LISTEN state to the SYN-RCVD state. | counter | af
`windows_tcp_connections_reset_total` | Connections Reset is the number of times TCP connections have made a direct transition to the CLOSED state from either the ESTABLISHED state or the CLOSE-WAIT state. | counter | af
`windows_tcp_segments_total` | Total segments sent or received using the TCP protocol | counter | af
`windows_tcp_segments_received_total` | Total segments received, including those received in error. This count includes segments received on currently established connections | counter | af
`windows_tcp_segments_retransmitted_total` | Total segments retransmitted. That is, segments transmitted that contain one or more previously transmitted bytes | counter | af
`windows_tcp_segments_sent_total` | Total segments sent, including those on current connections, but excluding those containing *only* retransmitted bytes | counter | af
| Name | Description | Type | Labels |
|--------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
| `windows_tcp_connection_failures_total` | Number of times TCP connections have made a direct transition to the CLOSED state from the SYN-SENT state or the SYN-RCVD state, plus the number of times TCP connections have made a direct transition from the SYN-RCVD state to the LISTEN state | counter | af |
| `windows_tcp_connections_active_total` | Number of times TCP connections have made a direct transition from the CLOSED state to the SYN-SENT state. | counter | af |
| `windows_tcp_connections_established` | Number of TCP connections for which the current state is either ESTABLISHED or CLOSE-WAIT. | gauge | af |
| `windows_tcp_connections_passive_total` | Number of times TCP connections have made a direct transition from the LISTEN state to the SYN-RCVD state. | counter | af |
| `windows_tcp_connections_reset_total` | Connections Reset is the number of times TCP connections have made a direct transition to the CLOSED state from either the ESTABLISHED state or the CLOSE-WAIT state. | counter | af |
| `windows_tcp_segments_total` | Total segments sent or received using the TCP protocol | counter | af |
| `windows_tcp_segments_received_total` | Total segments received, including those received in error. This count includes segments received on currently established connections | counter | af |
| `windows_tcp_segments_retransmitted_total` | Total segments retransmitted. That is, segments transmitted that contain one or more previously transmitted bytes | counter | af |
| `windows_tcp_segments_sent_total` | Total segments sent, including those on current connections, but excluding those containing *only* retransmitted bytes | counter | af |
| `windows_tcp_connections_state_count` | Number of TCP connections by state among: CLOSED, LISTENING, SYN_SENT, SYN_RECEIVED, ESTABLISHED, FIN_WAIT1, FIN_WAIT2, CLOSE_WAIT, CLOSING, LAST_ACK, TIME_WAIT, DELETE_TCB | gauge | af |
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_

View File

@@ -1,64 +0,0 @@
# teradici_pcoip collector
The teradici_pcoip collector exposes metrics relating to Teradici PCoIP sessions
|||
-|-
Metric name prefix | `teradici_pcoip`
Classes | `Win32_PerfRawData_TeradiciPerf_PCoIPSessionAudioStatistics`, `Win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics`,`Win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics`,`Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics`,`Win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics`
Enabled by default? | No
## Flags
None
## Metrics
Name | Description | Type | Labels
-----|-------------|------|-------
`windows_teradici_pcoip_audio_bytes_received_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_audio_bytes_sent_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_audio_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_audio_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_audio_tx_bw_limit_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_bytes_received_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_bytes_sent_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_packets_received_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_packets_sent_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_rx_packets_lost_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_session_duration_seconds_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_tx_packets_lost_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_imaging_active_min_quality` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_imaging_apex2800_offload` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_imaging_bytes_received_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_imaging_bytes_sent_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_imaging_decoder_capability_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_imaging_encoded_frames_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_imaging_megapixel_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_imaging_negative_acks_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_imaging_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_imaging_svga_devtap_frames_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_imaging_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_round_trip_latency_ms` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_rx_bw_peak_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_rx_packet_loss_percent` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_rx_packet_loss_percent_base` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_tx_bw_active_limit_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_tx_bw_limit_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_tx_packet_loss_percent` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_tx_packet_loss_percent_base` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_usb_bytes_received_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_usb_bytes_sent_total` | _Not yet documented_ | counter | None
`windows_teradici_pcoip_usb_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
`windows_teradici_pcoip_usb_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_
## Useful queries
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
## Alerting examples
_This collector does not yet have alerting examples, we would appreciate your help adding them!_

View File

@@ -6,7 +6,7 @@ The textfile collector exposes metrics from files written by other processes.
-|-
Metric name prefix | `textfile`
Classes | None
Enabled by default? | Yes
Enabled by default? | No
## Flags

View File

@@ -5,15 +5,19 @@ If the Windows Time Service is stopped after collection has started, collector m
Please note the Time Service perflib counters are only available on [Windows Server 2016 or newer](https://docs.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-server-2016-improvements).
| | |
|---------------------|---------|
| Metric name prefix | `time` |
| Data source | Perflib |
| Enabled by default? | No |
| | |
|---------------------|--------|
| Metric name prefix | `time` |
| Data source | PDH |
| Enabled by default? | No |
## Flags
None
### `--collectors.time.enabled`
Comma-separated list of collectors to use, for example: `--collectors.time.enabled=ntp,system_time`.
Matching is case-sensitive.
## Metrics

31
docs/collector.udp.md Normal file
View File

@@ -0,0 +1,31 @@
# udp collector
The udp collector exposes metrics about the UDP network stack.
|||
-|-
Metric name prefix | `udp`
Data source | Perflib
Enabled by default? | No
## Flags
None
## Metrics
| Name | Description | Type | Labels |
|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
| `windows_udp_datagram_datagram_no_port_total` | Number of received UDP datagrams for which there was no application at the destination port | counter | af |
| `windows_udp_datagram_received_errors_total` | Number of received UDP datagrams that could not be delivered for reasons other than the lack of an application at the destination port | counter | af |
| `windows_udp_datagram_received_total` | Number of UDP datagrams segments received | counter | af |
| `windows_udp_datagram_sent_total` | Number of UDP datagrams segments sent | counter | af |
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_
## Useful queries
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
## Alerting examples
_This collector does not yet have alerting examples, we would appreciate your help adding them!_

48
docs/collector.update.md Normal file
View File

@@ -0,0 +1,48 @@
# update collector
The update collector exposes the Windows Update service metrics. Note that the Windows Update service (`wuauserv`) must be running, else metric collection will fail.
The Windows Update service is responsible for managing the installation of updates for the operating system and other Microsoft software. The service can be configured to automatically download and install updates, or to notify the user when updates are available.
| | |
|---------------------|------------------------|
| Metric name prefix | `update` |
| Data source | Windows Update service |
| Enabled by default? | No |
## Flags
### `--collector.updates.online`
Whether to search for updates online. If set to `false`, the collector will only list updates that are already found by the Windows Update service.
Set to `true` to search for updates online, which will take longer to complete.
### `--collector.updates.scrape-interval`
Define the interval of scraping Windows Update information
## Metrics
| Name | Description | Type | Labels |
|--------------------------------|-----------------------------------------------|-------|-------------------------------|
| `windows_updates_pending_info` | Expose information single pending update item | gauge | `category`,`severity`,`title` |
| `windows_updates_scrape_query_duration_seconds` | Duration of the last scrape query to the Windows Update API | gauge | |
| `windows_updates_scrape_timestamp_seconds` | Timestamp of the last scrape | gauge | |
### Example metrics
```
# HELP windows_updates_pending Pending Windows Updates
# TYPE windows_updates_pending gauge
windows_updates_pending{category="Drivers",severity="",title="Intel Corporation - Bluetooth - 23.60.5.10"} 1
# HELP windows_updates_scrape_query_duration_seconds Duration of the last scrape query to the Windows Update API
# TYPE windows_updates_scrape_query_duration_seconds gauge
windows_updates_scrape_query_duration_seconds 2.8161838
# HELP windows_updates_scrape_timestamp_seconds Timestamp of the last scrape
# TYPE windows_updates_scrape_timestamp_seconds gauge
windows_updates_scrape_timestamp_seconds 1.727539734e+09
```
## Useful queries
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
## Alerting examples
_This collector does not yet have alerting examples, we would appreciate your help adding them!_

View File

@@ -2,11 +2,11 @@
The vmware collector exposes metrics about a VMware guest VM
|||
-|-
Metric name prefix | `vmware`
Classes | `Win32_PerfRawData_vmGuestLib_VMem`, `Win32_PerfRawData_vmGuestLib_VCPU`
Enabled by default? | No
| | |
|---------------------|----------------------|
| Metric name prefix | `vmware` |
| Source | Performance counters |
| Enabled by default? | No |
## Flags
@@ -14,27 +14,27 @@ None
## Metrics
Name | Description | Type | Labels
-----|-------------|------|-------
`windows_vmware_mem_active_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_ballooned_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_limit_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_mapped_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_overhead_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_reservation_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_shared_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_shared_saved_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_shares` | _Not yet documented_ | gauge | None
`windows_vmware_mem_swapped_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_target_size_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_mem_used_bytes` | _Not yet documented_ | gauge | None
`windows_vmware_cpu_limit_mhz` | _Not yet documented_ | gauge | None
`windows_vmware_cpu_reservation_mhz` | _Not yet documented_ | gauge | None
`windows_vmware_cpu_shares` | _Not yet documented_ | gauge | None
`windows_vmware_cpu_stolen_seconds_total` | _Not yet documented_ | counter | None
`windows_vmware_cpu_time_seconds_total` | _Not yet documented_ | counter | None
`windows_vmware_effective_vm_speed_mhz` | _Not yet documented_ | gauge | None
`windows_vmware_host_processor_speed_mhz` | _Not yet documented_ | gauge | None
| Name | Description | Type | Labels |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
| `windows_vmware_mem_active_bytes` | The estimated amount of memory the virtual machine is actively using. | gauge | None |
| `windows_vmware_mem_ballooned_bytes` | The amount of memory that has been reclaimed from this virtual machine via the VMware Memory Balloon mechanism. | gauge | None |
| `windows_vmware_mem_limit_bytes` | The maximum amount of memory that is allowed to the virtual machine. Assigning a Memory Limit ensures that this virtual machine never consumes more than a certain amount of the allowed memory. By limiting the amount of memory consumed, a portion of this shared resource is allowed to other virtual machines. | gauge | None |
| `windows_vmware_mem_mapped_bytes` | The mapped memory size of this virtual machine. This is the current total amount of guest memory that is backed by physical memory. Note that this number may include pages of memory shared between multiple virtual machines and thus may be an overestimate of the amount of physical host memory consumed by this virtual machine. | gauge | None |
| `windows_vmware_mem_overhead_bytes` | The amount of overhead memory associated with this virtual machine consumed on the host system. | gauge | None |
| `windows_vmware_mem_reservation_bytes` | The minimum amount of memory that is guaranteed to the virtual machine. Assigning a Memory Reservation ensures that even as other virtual machines on the same host consume memory, there is still a certain minimum amount for this virtual machine. | gauge | None |
| `windows_vmware_mem_shared_bytes` | The amount of physical memory associated with this virtual machine that is copy-on-write (COW) shared on the host. | gauge | None |
| `windows_vmware_mem_shared_saved_bytes` | The estimated amount of physical memory on the host saved from copy-on-write (COW) shared guest physical memory. | gauge | None |
| `windows_vmware_mem_shares` | The number of memory shares allocated to the virtual machine. | gauge | None |
| `windows_vmware_mem_swapped_bytes` | The amount of memory associated with this virtual machine that has been swapped by ESX. | gauge | None |
| `windows_vmware_mem_target_size_bytes` | Memory Target Size | gauge | None |
| `windows_vmware_mem_used_bytes` | The estimated amount of physical host memory currently consumed for this virtual machines physical memory. | gauge | None |
| `windows_vmware_cpu_limit_mhz` | The maximum processing power in MHz allowed to the virtual machine. Assigning a CPU Limit ensures that this virtual machine never consumes more than a certain amount of the available processor power. By limiting the amount of processing power consumed, a portion of the processing power becomes available to other virtual machines. | gauge | None |
| `windows_vmware_cpu_reservation_mhz` | The minimum processing power in MHz available to the virtual machine. Assigning a CPU Reservation ensures that even as other virtual machines on the same host consume shared processing power, there is still a certain minimum amount for this virtual machine. | gauge | None |
| `windows_vmware_cpu_shares` | The number of CPU shares allocated to the virtual machine. | gauge | None |
| `windows_vmware_cpu_stolen_seconds_total` | The time that the VM was runnable but not scheduled to run | counter | None |
| `windows_vmware_cpu_time_seconds_total` | Current load of the VMs virtual processor | counter | None |
| `windows_vmware_cpu_effective_vm_speed_mhz` | The effective speed of the VMs virtual CPU | gauge | None |
| `windows_vmware_host_processor_speed_mhz` | Host Processor speed | gauge | None |
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_

View File

@@ -1,98 +0,0 @@
# vmware_blast collector
The vmware_blast collector exposes metrics relating to VMware Blast sessions
|||
-|-
Metric name prefix | `vmware_blast`
Classes | `Win32_PerfRawData_Counters_VMwareBlastAudioCounters`,`Win32_PerfRawData_Counters_VMwareBlastCDRCounters`,`Win32_PerfRawData_Counters_VMwareBlastClipboardCounters`,`Win32_PerfRawData_Counters_VMwareBlastHTML5MMRCounters`,`Win32_PerfRawData_Counters_VMwareBlastImagingCounters`,`Win32_PerfRawData_Counters_VMwareBlastRTAVCounters`,`Win32_PerfRawData_Counters_VMwareBlastSerialPortandScannerCounters`,`Win32_PerfRawData_Counters_VMwareBlastSessionCounters`,`Win32_PerfRawData_Counters_VMwareBlastSkypeforBusinessControlCounters`,`Win32_PerfRawData_Counters_VMwareBlastThinPrintCounters`,`Win32_PerfRawData_Counters_VMwareBlastUSBCounters`,`Win32_PerfRawData_Counters_VMwareBlastWindowsMediaMMRCounters`
Enabled by default? | No
## Flags
None
## Metrics
Some of these metrics may not be collected, depending on the installation options chosen when installing the Horizon agent
Name | Description | Type | Labels
-----|-------------|------|-------
`windows_vmware_blast_audio_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_audio_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_audio_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_audio_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_cdr_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_cdr_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_cdr_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_cdr_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_clipboard_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_clipboard_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_clipboard_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_clipboard_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_html5_mmr_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_html5_mmr_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_html5_mmr_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_html5_mmr_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_imaging_dirty_frames_per_second` | _Not yet documented_ | gauge | None
`windows_vmware_blast_imaging_fbc_rate` | _Not yet documented_ | gauge | None
`windows_vmware_blast_imaging_frames_per_second` | _Not yet documented_ | gauge | None
`windows_vmware_blast_imaging_poll_rate` | _Not yet documented_ | gauge | None
`windows_vmware_blast_imaging_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_imaging_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_imaging_dirty_frames_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_imaging_fbc_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_imaging_frames_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_imaging_poll_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_imaging_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_imaging_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_rtav_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_rtav_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_rtav_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_rtav_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_serial_port_and_scanner_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_serial_port_and_scanner_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_serial_port_and_scanner_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_serial_port_and_scanner_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_automatic_reconnect_count_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_cumlative_received_bytes_over_tcp_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_cumlative_received_bytes_over_udp_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_cumlative_transmitted_bytes_over_tcp_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_cumlative_transmitted_bytes_over_udp_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_estimated_bandwidth_uplink` | _Not yet documented_ | gauge | None
`windows_vmware_blast_session_instantaneous_received_bytes_over_tcp_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_instantaneous_received_bytes_over_udp_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_instantaneous_transmitted_bytes_over_tcp_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_instantaneous_transmitted_bytes_over_udp_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_jitter_uplink` | _Not yet documented_ | gauge | None
`windows_vmware_blast_session_packet_loss_uplink` | _Not yet documented_ | gauge | None
`windows_vmware_blast_session_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_rtt` | _Not yet documented_ | gauge | None
`windows_vmware_blast_session_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_session_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_skype_for_business_control_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_skype_for_business_control_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_skype_for_business_control_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_skype_for_business_control_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_thinprint_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_thinprint_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_thinprint_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_thinprint_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_usb_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_usb_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_usb_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_usb_transmitted_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_windows_media_mmr_received_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_windows_media_mmr_received_packets_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_windows_media_mmr_transmitted_bytes_total` | _Not yet documented_ | counter | None
`windows_vmware_blast_windows_media_mmr_transmitted_packets_total` | _Not yet documented_ | counter | None
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_
## Useful queries
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
## Alerting examples
_This collector does not yet have alerting examples, we would appreciate your help adding them!_

44
go.mod
View File

@@ -3,34 +3,36 @@ module github.com/prometheus-community/windows_exporter
go 1.23
require (
github.com/Microsoft/hcsshim v0.12.7
github.com/Microsoft/hcsshim v0.12.9
github.com/alecthomas/kingpin/v2 v2.4.0
github.com/bmatcuk/doublestar/v4 v4.6.1
github.com/bmatcuk/doublestar/v4 v4.7.1
github.com/dimchansky/utfbom v1.1.1
github.com/go-ole/go-ole v1.3.0
github.com/google/uuid v1.6.0
github.com/prometheus/client_golang v1.20.4
github.com/prometheus/client_golang v1.20.5
github.com/prometheus/client_model v0.6.1
github.com/prometheus/common v0.59.2-0.20240918152650-14bac55a992f
github.com/prometheus/exporter-toolkit v0.13.0
github.com/stretchr/testify v1.9.0
github.com/yusufpapurcu/wmi v1.2.4
golang.org/x/sys v0.25.0
github.com/prometheus/common v0.61.0
github.com/prometheus/exporter-toolkit v0.13.2
github.com/stretchr/testify v1.10.0
golang.org/x/sys v0.29.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/containerd/cgroups/v3 v3.0.3 // indirect
github.com/containerd/errdefs v0.1.0 // indirect
github.com/containerd/cgroups/v3 v3.0.4 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/klauspost/compress v1.17.10 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/mdlayher/socket v0.5.1 // indirect
github.com/mdlayher/vsock v1.2.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
@@ -41,13 +43,13 @@ require (
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/text v0.18.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect
google.golang.org/grpc v1.67.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/net v0.32.0 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect
google.golang.org/grpc v1.68.0 // indirect
google.golang.org/protobuf v1.35.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

109
go.sum
View File

@@ -2,25 +2,29 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Microsoft/hcsshim v0.12.7 h1:MP6R1spmjxTE4EU4J3YsrTxn8CjvN9qwjTKJXldFaRg=
github.com/Microsoft/hcsshim v0.12.7/go.mod h1:HPbAuJ9BvQYYZbB4yEQcyGIsTP5L4yHKeO9XO149AEM=
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg=
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0=
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
github.com/containerd/cgroups/v3 v3.0.4 h1:2fs7l3P0Qxb1nKWuJNFiwhp2CqiKzho71DQkDrHJIo4=
github.com/containerd/cgroups/v3 v3.0.4/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -32,14 +36,15 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -50,6 +55,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -63,8 +70,10 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0=
github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -83,15 +92,15 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.59.2-0.20240918152650-14bac55a992f h1:3okwxT2ame6iNnOMGt2bH7JISqpwGn2KoMZ2bVFBQ6I=
github.com/prometheus/common v0.59.2-0.20240918152650-14bac55a992f/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0=
github.com/prometheus/exporter-toolkit v0.13.0 h1:lmA0Q+8IaXgmFRKw09RldZmZdnvu9wwcDLIXGmTPw1c=
github.com/prometheus/exporter-toolkit v0.13.0/go.mod h1:2uop99EZl80KdXhv/MxVI2181fMcwlsumFOqBecGkG0=
github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ=
github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
github.com/prometheus/exporter-toolkit v0.13.2 h1:Z02fYtbqTMy2i/f+xZ+UK5jy/bl1Ex3ndzh06T/Q9DQ=
github.com/prometheus/exporter-toolkit v0.13.2/go.mod h1:tCqnfx21q6qN1KA4U3Bfb8uWzXfijIrJz3/kTIqMV7g=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
@@ -107,71 +116,85 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -181,8 +204,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

View File

@@ -1,5 +1,20 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:netfx="http://wixtoolset.org/schemas/v4/wxs/netfx"
xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
<!--
~ Copyright 2024 The Prometheus Authors
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<Wix xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"
xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment>
<DirectoryRef Id="APPLICATIONFOLDER">
<Component Transitive="yes">
@@ -13,7 +28,7 @@
Start="auto"
Type="ownProcess"
Vital="yes"
Arguments="--log.file eventlog [ConfigFileFlag] [CollectorsFlag] [ListenFlag] [MetricsPathFlag] [TextfileDirsFlag] [ExtraFlags]">
Arguments="[ConfigFileFlag] [CollectorsFlag] [ListenFlag] [MetricsPathFlag] [TextfileDirsFlag] [ExtraFlags]">
<util:ServiceConfig
ResetPeriodInDays="1"
FirstFailureActionType="restart"

View File

@@ -9,9 +9,24 @@
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?endif?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall"
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
<!--
~ Copyright 2024 The Prometheus Authors
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<Wix xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall"
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui"
xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Package UpgradeCode="66a6eb5b-1fc2-4b14-a362-5ceec6413308" Name="$(var.ProductName)" Version="$(var.Version)"
Manufacturer="prometheus-community" Language="1033" Scope="perMachine">
<SummaryInformation Manufacturer="prometheus-community" Description="$(var.ProductName) $(var.Version) installer" />

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package ad_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/ad"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, ad.Name, ad.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, ad.New, nil)
}

View File

@@ -0,0 +1,223 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package ad
type perfDataCounterValues struct {
AbANRPerSec float64 `perfdata:"AB ANR/sec"`
AbBrowsesPerSec float64 `perfdata:"AB Browses/sec"`
AbClientSessions float64 `perfdata:"AB Client Sessions"`
AbMatchesPerSec float64 `perfdata:"AB Matches/sec"`
AbPropertyReadsPerSec float64 `perfdata:"AB Property Reads/sec"`
AbProxyLookupsPerSec float64 `perfdata:"AB Proxy Lookups/sec"`
AbSearchesPerSec float64 `perfdata:"AB Searches/sec"`
ApproximateHighestDNT float64 `perfdata:"Approximate highest DNT"`
AtqEstimatedQueueDelay float64 `perfdata:"ATQ Estimated Queue Delay"`
AtqOutstandingQueuedRequests float64 `perfdata:"ATQ Outstanding Queued Requests"`
_ float64 `perfdata:"ATQ Queue Latency"`
AtqRequestLatency float64 `perfdata:"ATQ Request Latency"`
AtqThreadsLDAP float64 `perfdata:"ATQ Threads LDAP"`
AtqThreadsOther float64 `perfdata:"ATQ Threads Other"`
AtqThreadsTotal float64 `perfdata:"ATQ Threads Total"`
BaseSearchesPerSec float64 `perfdata:"Base searches/sec"`
DatabaseAddsPerSec float64 `perfdata:"Database adds/sec"`
DatabaseDeletesPerSec float64 `perfdata:"Database deletes/sec"`
DatabaseModifiesPerSec float64 `perfdata:"Database modifys/sec"`
DatabaseRecyclesPerSec float64 `perfdata:"Database recycles/sec"`
DigestBindsPerSec float64 `perfdata:"Digest Binds/sec"`
_ float64 `perfdata:"DirSync session throttling rate"`
_ float64 `perfdata:"DirSync sessions in progress"`
DRAHighestUSNCommittedHighPart float64 `perfdata:"DRA Highest USN Committed (High part)"`
DRAHighestUSNCommittedLowPart float64 `perfdata:"DRA Highest USN Committed (Low part)"`
DRAHighestUSNIssuedHighPart float64 `perfdata:"DRA Highest USN Issued (High part)"`
DRAHighestUSNIssuedLowPart float64 `perfdata:"DRA Highest USN Issued (Low part)"`
DRAInboundBytesCompressedBetweenSitesAfterCompressionSinceBoot float64 `perfdata:"DRA Inbound Bytes Compressed (Between Sites, After Compression) Since Boot"`
DRAInboundBytesCompressedBetweenSitesAfterCompressionPerSec float64 `perfdata:"DRA Inbound Bytes Compressed (Between Sites, After Compression)/sec"`
DRAInboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot float64 `perfdata:"DRA Inbound Bytes Compressed (Between Sites, Before Compression) Since Boot"`
DRAInboundBytesCompressedBetweenSitesBeforeCompressionPerSec float64 `perfdata:"DRA Inbound Bytes Compressed (Between Sites, Before Compression)/sec"`
DRAInboundBytesNotCompressedWithinSiteSinceBoot float64 `perfdata:"DRA Inbound Bytes Not Compressed (Within Site) Since Boot"`
DRAInboundBytesNotCompressedWithinSitePerSec float64 `perfdata:"DRA Inbound Bytes Not Compressed (Within Site)/sec"`
DRAInboundBytesTotalSinceBoot float64 `perfdata:"DRA Inbound Bytes Total Since Boot"`
DRAInboundBytesTotalPerSec float64 `perfdata:"DRA Inbound Bytes Total/sec"`
DRAInboundFullSyncObjectsRemaining float64 `perfdata:"DRA Inbound Full Sync Objects Remaining"`
DRAInboundLinkValueUpdatesRemainingInPacket float64 `perfdata:"DRA Inbound Link Value Updates Remaining in Packet"`
_ float64 `perfdata:"DRA Inbound Link Values/sec"`
DRAInboundObjectUpdatesRemainingInPacket float64 `perfdata:"DRA Inbound Object Updates Remaining in Packet"`
DRAInboundObjectsAppliedPerSec float64 `perfdata:"DRA Inbound Objects Applied/sec"`
DRAInboundObjectsFilteredPerSec float64 `perfdata:"DRA Inbound Objects Filtered/sec"`
DRAInboundObjectsPerSec float64 `perfdata:"DRA Inbound Objects/sec"`
DRAInboundPropertiesAppliedPerSec float64 `perfdata:"DRA Inbound Properties Applied/sec"`
DRAInboundPropertiesFilteredPerSec float64 `perfdata:"DRA Inbound Properties Filtered/sec"`
DRAInboundPropertiesTotalPerSec float64 `perfdata:"DRA Inbound Properties Total/sec"`
_ float64 `perfdata:"DRA Inbound Sync Link Deletion/sec"`
DRAInboundTotalUpdatesRemainingInPacket float64 `perfdata:"DRA Inbound Total Updates Remaining in Packet"`
DRAInboundValuesDNsOnlyPerSec float64 `perfdata:"DRA Inbound Values (DNs only)/sec"`
DRAInboundValuesTotalPerSec float64 `perfdata:"DRA Inbound Values Total/sec"`
_ float64 `perfdata:"DRA number of NC replication calls since boot"`
_ float64 `perfdata:"DRA number of successful NC replication calls since boot"`
DRAOutboundBytesCompressedBetweenSitesAfterCompressionSinceBoot float64 `perfdata:"DRA Outbound Bytes Compressed (Between Sites, After Compression) Since Boot"`
DRAOutboundBytesCompressedBetweenSitesAfterCompressionPerSec float64 `perfdata:"DRA Outbound Bytes Compressed (Between Sites, After Compression)/sec"`
DRAOutboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot float64 `perfdata:"DRA Outbound Bytes Compressed (Between Sites, Before Compression) Since Boot"`
DRAOutboundBytesCompressedBetweenSitesBeforeCompressionPerSec float64 `perfdata:"DRA Outbound Bytes Compressed (Between Sites, Before Compression)/sec"`
DRAOutboundBytesNotCompressedWithinSiteSinceBoot float64 `perfdata:"DRA Outbound Bytes Not Compressed (Within Site) Since Boot"`
DRAOutboundBytesNotCompressedWithinSitePerSec float64 `perfdata:"DRA Outbound Bytes Not Compressed (Within Site)/sec"`
DRAOutboundBytesTotalSinceBoot float64 `perfdata:"DRA Outbound Bytes Total Since Boot"`
DRAOutboundBytesTotalPerSec float64 `perfdata:"DRA Outbound Bytes Total/sec"`
DRAOutboundObjectsFilteredPerSec float64 `perfdata:"DRA Outbound Objects Filtered/sec"`
DRAOutboundObjectsPerSec float64 `perfdata:"DRA Outbound Objects/sec"`
DRAOutboundPropertiesPerSec float64 `perfdata:"DRA Outbound Properties/sec"`
DRAOutboundValuesDNsOnlyPerSec float64 `perfdata:"DRA Outbound Values (DNs only)/sec"`
DRAOutboundValuesTotalPerSec float64 `perfdata:"DRA Outbound Values Total/sec"`
DRAPendingReplicationOperations float64 `perfdata:"DRA Pending Replication Operations"`
DRAPendingReplicationSynchronizations float64 `perfdata:"DRA Pending Replication Synchronizations"`
DRASyncFailuresOnSchemaMismatch float64 `perfdata:"DRA Sync Failures on Schema Mismatch"`
DRASyncRequestsMade float64 `perfdata:"DRA Sync Requests Made"`
DRASyncRequestsSuccessful float64 `perfdata:"DRA Sync Requests Successful"`
DRAThreadsGettingNCChanges float64 `perfdata:"DRA Threads Getting NC Changes"`
DRAThreadsGettingNCChangesHoldingSemaphore float64 `perfdata:"DRA Threads Getting NC Changes Holding Semaphore"`
_ float64 `perfdata:"DRA total number of Busy failures since boot"`
_ float64 `perfdata:"DRA total number of MissingParent failures since boot"`
_ float64 `perfdata:"DRA total number of NotEnoughAttrs/MissingObject failures since boot"`
_ float64 `perfdata:"DRA total number of Preempted failures since boot"`
_ float64 `perfdata:"DRA total time of applying replication package since boot"`
_ float64 `perfdata:"DRA total time of NC replication calls since boot"`
_ float64 `perfdata:"DRA total time of successful NC replication calls since boot"`
_ float64 `perfdata:"DRA total time of successfully applying replication package since boot"`
_ float64 `perfdata:"DRA total time on waiting async replication packages since boot"`
_ float64 `perfdata:"DRA total time on waiting sync replication packages since boot"`
DsPercentReadsFromDRA float64 `perfdata:"DS % Reads from DRA"`
DsPercentReadsFromKCC float64 `perfdata:"DS % Reads from KCC"`
DsPercentReadsFromLSA float64 `perfdata:"DS % Reads from LSA"`
DsPercentReadsFromNSPI float64 `perfdata:"DS % Reads from NSPI"`
DsPercentReadsFromNTDSAPI float64 `perfdata:"DS % Reads from NTDSAPI"`
DsPercentReadsFromSAM float64 `perfdata:"DS % Reads from SAM"`
DsPercentReadsOther float64 `perfdata:"DS % Reads Other"`
DsPercentSearchesFromDRA float64 `perfdata:"DS % Searches from DRA"`
DsPercentSearchesFromKCC float64 `perfdata:"DS % Searches from KCC"`
DsPercentSearchesFromLDAP float64 `perfdata:"DS % Searches from LDAP"`
DsPercentSearchesFromLSA float64 `perfdata:"DS % Searches from LSA"`
DsPercentSearchesFromNSPI float64 `perfdata:"DS % Searches from NSPI"`
DsPercentSearchesFromNTDSAPI float64 `perfdata:"DS % Searches from NTDSAPI"`
DsPercentSearchesFromSAM float64 `perfdata:"DS % Searches from SAM"`
DsPercentSearchesOther float64 `perfdata:"DS % Searches Other"`
DsPercentWritesFromDRA float64 `perfdata:"DS % Writes from DRA"`
DsPercentWritesFromKCC float64 `perfdata:"DS % Writes from KCC"`
DsPercentWritesFromLDAP float64 `perfdata:"DS % Writes from LDAP"`
DsPercentWritesFromLSA float64 `perfdata:"DS % Writes from LSA"`
DsPercentWritesFromNSPI float64 `perfdata:"DS % Writes from NSPI"`
DsPercentWritesFromNTDSAPI float64 `perfdata:"DS % Writes from NTDSAPI"`
DsPercentWritesFromSAM float64 `perfdata:"DS % Writes from SAM"`
DsPercentWritesOther float64 `perfdata:"DS % Writes Other"`
DsClientBindsPerSec float64 `perfdata:"DS Client Binds/sec"`
DsClientNameTranslationsPerSec float64 `perfdata:"DS Client Name Translations/sec"`
DsDirectoryReadsPerSec float64 `perfdata:"DS Directory Reads/sec"`
DsDirectorySearchesPerSec float64 `perfdata:"DS Directory Searches/sec"`
DsDirectoryWritesPerSec float64 `perfdata:"DS Directory Writes/sec"`
DsMonitorListSize float64 `perfdata:"DS Monitor List Size"`
DsNameCacheHitRate float64 `perfdata:"DS Name Cache hit rate"`
DsNameCacheHitRateSecondValue float64 `perfdata:"DS Name Cache hit rate,secondvalue"`
DsNotifyQueueSize float64 `perfdata:"DS Notify Queue Size"`
DsSearchSubOperationsPerSec float64 `perfdata:"DS Search sub-operations/sec"`
DsSecurityDescriptorPropagationsEvents float64 `perfdata:"DS Security Descriptor Propagations Events"`
DsSecurityDescriptorPropagatorAverageExclusionTime float64 `perfdata:"DS Security Descriptor Propagator Average Exclusion Time"`
DsSecurityDescriptorPropagatorRuntimeQueue float64 `perfdata:"DS Security Descriptor Propagator Runtime Queue"`
DsSecurityDescriptorSubOperationsPerSec float64 `perfdata:"DS Security Descriptor sub-operations/sec"`
DsServerBindsPerSec float64 `perfdata:"DS Server Binds/sec"`
DsServerNameTranslationsPerSec float64 `perfdata:"DS Server Name Translations/sec"`
DsThreadsInUse float64 `perfdata:"DS Threads in Use"`
_ float64 `perfdata:"Error eventlogs since boot"`
_ float64 `perfdata:"Error events since boot"`
ExternalBindsPerSec float64 `perfdata:"External Binds/sec"`
FastBindsPerSec float64 `perfdata:"Fast Binds/sec"`
_ float64 `perfdata:"Fatal events since boot"`
_ float64 `perfdata:"Info eventlogs since boot"`
LdapActiveThreads float64 `perfdata:"LDAP Active Threads"`
_ float64 `perfdata:"LDAP Add Operations"`
_ float64 `perfdata:"LDAP Add Operations/sec"`
_ float64 `perfdata:"LDAP batch slots available"`
LdapBindTime float64 `perfdata:"LDAP Bind Time"`
_ float64 `perfdata:"LDAP busy retries"`
_ float64 `perfdata:"LDAP busy retries/sec"`
LdapClientSessions float64 `perfdata:"LDAP Client Sessions"`
LdapClosedConnectionsPerSec float64 `perfdata:"LDAP Closed Connections/sec"`
_ float64 `perfdata:"LDAP Delete Operations"`
_ float64 `perfdata:"LDAP Delete Operations/sec"`
_ float64 `perfdata:"LDAP Modify DN Operations"`
_ float64 `perfdata:"LDAP Modify DN Operations/sec"`
_ float64 `perfdata:"LDAP Modify Operations"`
_ float64 `perfdata:"LDAP Modify Operations/sec"`
LdapNewConnectionsPerSec float64 `perfdata:"LDAP New Connections/sec"`
LdapNewSSLConnectionsPerSec float64 `perfdata:"LDAP New SSL Connections/sec"`
_ float64 `perfdata:"LDAP Outbound Bytes"`
_ float64 `perfdata:"LDAP Outbound Bytes/sec"`
_ float64 `perfdata:"LDAP Page Search Cache entries count"`
_ float64 `perfdata:"LDAP Page Search Cache size"`
LdapSearchesPerSec float64 `perfdata:"LDAP Searches/sec"`
LdapSuccessfulBindsPerSec float64 `perfdata:"LDAP Successful Binds/sec"`
_ float64 `perfdata:"LDAP Threads Sleeping on BUSY"`
LdapUDPOperationsPerSec float64 `perfdata:"LDAP UDP operations/sec"`
LdapWritesPerSec float64 `perfdata:"LDAP Writes/sec"`
LinkValuesCleanedPerSec float64 `perfdata:"Link Values Cleaned/sec"`
_ float64 `perfdata:"Links added"`
_ float64 `perfdata:"Links added/sec"`
_ float64 `perfdata:"Links visited"`
_ float64 `perfdata:"Links visited/sec"`
_ float64 `perfdata:"Logical link deletes"`
_ float64 `perfdata:"Logical link deletes/sec"`
NegotiatedBindsPerSec float64 `perfdata:"Negotiated Binds/sec"`
NTLMBindsPerSec float64 `perfdata:"NTLM Binds/sec"`
_ float64 `perfdata:"Objects returned"`
_ float64 `perfdata:"Objects returned/sec"`
_ float64 `perfdata:"Objects visited"`
_ float64 `perfdata:"Objects visited/sec"`
OneLevelSearchesPerSec float64 `perfdata:"Onelevel searches/sec"`
_ float64 `perfdata:"PDC failed password update notifications"`
_ float64 `perfdata:"PDC password update notifications/sec"`
_ float64 `perfdata:"PDC successful password update notifications"`
PhantomsCleanedPerSec float64 `perfdata:"Phantoms Cleaned/sec"`
PhantomsVisitedPerSec float64 `perfdata:"Phantoms Visited/sec"`
_ float64 `perfdata:"Physical link deletes"`
_ float64 `perfdata:"Physical link deletes/sec"`
_ float64 `perfdata:"Replicate Single Object operations"`
_ float64 `perfdata:"Replicate Single Object operations/sec"`
_ float64 `perfdata:"RID Pool invalidations since boot"`
_ float64 `perfdata:"RID Pool request failures since boot"`
_ float64 `perfdata:"RID Pool request successes since boot"`
SamAccountGroupEvaluationLatency float64 `perfdata:"SAM Account Group Evaluation Latency"`
SamDisplayInformationQueriesPerSec float64 `perfdata:"SAM Display Information Queries/sec"`
SamDomainLocalGroupMembershipEvaluationsPerSec float64 `perfdata:"SAM Domain Local Group Membership Evaluations/sec"`
SamEnumerationsPerSec float64 `perfdata:"SAM Enumerations/sec"`
SamGCEvaluationsPerSec float64 `perfdata:"SAM GC Evaluations/sec"`
SamGlobalGroupMembershipEvaluationsPerSec float64 `perfdata:"SAM Global Group Membership Evaluations/sec"`
SamMachineCreationAttemptsPerSec float64 `perfdata:"SAM Machine Creation Attempts/sec"`
SamMembershipChangesPerSec float64 `perfdata:"SAM Membership Changes/sec"`
SamNonTransitiveMembershipEvaluationsPerSec float64 `perfdata:"SAM Non-Transitive Membership Evaluations/sec"`
SamPasswordChangesPerSec float64 `perfdata:"SAM Password Changes/sec"`
SamResourceGroupEvaluationLatency float64 `perfdata:"SAM Resource Group Evaluation Latency"`
SamSuccessfulComputerCreationsPerSecIncludesAllRequests float64 `perfdata:"SAM Successful Computer Creations/sec: Includes all requests"`
SamSuccessfulUserCreationsPerSec float64 `perfdata:"SAM Successful User Creations/sec"`
SamTransitiveMembershipEvaluationsPerSec float64 `perfdata:"SAM Transitive Membership Evaluations/sec"`
SamUniversalGroupMembershipEvaluationsPerSec float64 `perfdata:"SAM Universal Group Membership Evaluations/sec"`
SamUserCreationAttemptsPerSec float64 `perfdata:"SAM User Creation Attempts/sec"`
SimpleBindsPerSec float64 `perfdata:"Simple Binds/sec"`
SubtreeSearchesPerSec float64 `perfdata:"Subtree searches/sec"`
TombstonesGarbageCollectedPerSec float64 `perfdata:"Tombstones Garbage Collected/sec"`
TombstonesVisitedPerSec float64 `perfdata:"Tombstones Visited/sec"`
TransitiveOperationsMillisecondsRun float64 `perfdata:"Transitive operations milliseconds run"`
TransitiveOperationsPerSec float64 `perfdata:"Transitive operations/sec"`
TransitiveSubOperationsPerSec float64 `perfdata:"Transitive suboperations/sec"`
_ float64 `perfdata:"Warning eventlogs since boot"`
_ float64 `perfdata:"Warning events since boot"`
}

View File

@@ -1,29 +1,45 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package adcs
import (
"errors"
"fmt"
"log/slog"
"strings"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/perflib"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/pkg/utils"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "adcs"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
type Collector struct {
config Config
perfDataCollector *pdh.Collector
perfDataObject []perfDataCounterValues
challengeResponseProcessingTime *prometheus.Desc
challengeResponsesPerSecond *prometheus.Desc
failedRequestsPerSecond *prometheus.Desc
@@ -59,15 +75,20 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{"Certification Authority"}, nil
}
func (c *Collector) Close() error {
c.perfDataCollector.Close()
func (c *Collector) Close(_ *slog.Logger) error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
var err error
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Certification Authority", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Certification Authority collector: %w", err)
}
c.requestsPerSecond = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "requests_total"),
"Total certificate requests processed",
@@ -150,134 +171,90 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
return nil
}
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
if err := c.collectADCSCounters(ctx, logger, ch); err != nil {
logger.Error("failed collecting ADCS metrics",
slog.Any("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 *Collector) collectADCSCounters(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
dst := make([]perflibADCS, 0)
if _, ok := ctx.PerfObjects["Certification Authority"]; !ok {
return errors.New("perflib did not contain an entry for Certification Authority")
}
err := perflib.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, logger)
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
err := c.perfDataCollector.Collect(&c.perfDataObject)
if err != nil {
return err
return fmt.Errorf("failed to collect Certification Authority (ADCS) metrics: %w", err)
}
if len(dst) == 0 {
return errors.New("perflib query for Certification Authority (ADCS) returned empty result set")
}
for _, d := range dst {
n := strings.ToLower(d.Name)
if n == "" {
continue
}
for _, data := range c.perfDataObject {
ch <- prometheus.MustNewConstMetric(
c.requestsPerSecond,
prometheus.CounterValue,
d.RequestsPerSecond,
d.Name,
data.RequestsPerSecond,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.requestProcessingTime,
prometheus.GaugeValue,
utils.MilliSecToSec(d.RequestProcessingTime),
d.Name,
utils.MilliSecToSec(data.RequestProcessingTime),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.retrievalsPerSecond,
prometheus.CounterValue,
d.RetrievalsPerSecond,
d.Name,
data.RetrievalsPerSecond,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.retrievalProcessingTime,
prometheus.GaugeValue,
utils.MilliSecToSec(d.RetrievalProcessingTime),
d.Name,
utils.MilliSecToSec(data.RetrievalProcessingTime),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.failedRequestsPerSecond,
prometheus.CounterValue,
d.FailedRequestsPerSecond,
d.Name,
data.FailedRequestsPerSecond,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.issuedRequestsPerSecond,
prometheus.CounterValue,
d.IssuedRequestsPerSecond,
d.Name,
data.IssuedRequestsPerSecond,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.pendingRequestsPerSecond,
prometheus.CounterValue,
d.PendingRequestsPerSecond,
d.Name,
data.PendingRequestsPerSecond,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.requestCryptographicSigningTime,
prometheus.GaugeValue,
utils.MilliSecToSec(d.RequestCryptographicSigningTime),
d.Name,
utils.MilliSecToSec(data.RequestCryptographicSigningTime),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.requestPolicyModuleProcessingTime,
prometheus.GaugeValue,
utils.MilliSecToSec(d.RequestPolicyModuleProcessingTime),
d.Name,
utils.MilliSecToSec(data.RequestPolicyModuleProcessingTime),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.challengeResponsesPerSecond,
prometheus.CounterValue,
d.ChallengeResponsesPerSecond,
d.Name,
data.ChallengeResponsesPerSecond,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.challengeResponseProcessingTime,
prometheus.GaugeValue,
utils.MilliSecToSec(d.ChallengeResponseProcessingTime),
d.Name,
utils.MilliSecToSec(data.ChallengeResponseProcessingTime),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.signedCertificateTimestampListsPerSecond,
prometheus.CounterValue,
d.SignedCertificateTimestampListsPerSecond,
d.Name,
data.SignedCertificateTimestampListsPerSecond,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.signedCertificateTimestampListProcessingTime,
prometheus.GaugeValue,
utils.MilliSecToSec(d.SignedCertificateTimestampListProcessingTime),
d.Name,
utils.MilliSecToSec(data.SignedCertificateTimestampListProcessingTime),
data.Name,
)
}

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package adcs_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/adcs"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, adcs.Name, adcs.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, adcs.New, nil)
}

View File

@@ -0,0 +1,34 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package adcs
type perfDataCounterValues struct {
Name string
ChallengeResponseProcessingTime float64 `perfdata:"Challenge Response processing time (ms)"`
ChallengeResponsesPerSecond float64 `perfdata:"Challenge Responses/sec"`
FailedRequestsPerSecond float64 `perfdata:"Failed Requests/sec"`
IssuedRequestsPerSecond float64 `perfdata:"Issued Requests/sec"`
PendingRequestsPerSecond float64 `perfdata:"Pending Requests/sec"`
RequestCryptographicSigningTime float64 `perfdata:"Request cryptographic signing time (ms)"`
RequestPolicyModuleProcessingTime float64 `perfdata:"Request policy module processing time (ms)"`
RequestProcessingTime float64 `perfdata:"Request processing time (ms)"`
RequestsPerSecond float64 `perfdata:"Requests/sec"`
RetrievalProcessingTime float64 `perfdata:"Retrieval processing time (ms)"`
RetrievalsPerSecond float64 `perfdata:"Retrievals/sec"`
SignedCertificateTimestampListProcessingTime float64 `perfdata:"Signed Certificate Timestamp List processing time (ms)"`
SignedCertificateTimestampListsPerSecond float64 `perfdata:"Signed Certificate Timestamp Lists/sec"`
}

View File

@@ -1,27 +1,45 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package adfs
import (
"fmt"
"log/slog"
"math"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/perflib"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "adfs"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
type Collector struct {
config Config
perfDataCollector *pdh.Collector
perfDataObject []perfDataCounterValues
adLoginConnectionFailures *prometheus.Desc
artifactDBFailures *prometheus.Desc
avgArtifactDBQueryTime *prometheus.Desc
@@ -63,8 +81,8 @@ type Collector struct {
upAuthenticationFailures *prometheus.Desc
upAuthentications *prometheus.Desc
windowsIntegratedAuthentications *prometheus.Desc
wsfedTokenRequests *prometheus.Desc
wstrustTokenRequests *prometheus.Desc
wsFedTokenRequests *prometheus.Desc
wsTrustTokenRequests *prometheus.Desc
}
func New(config *Config) *Collector {
@@ -87,15 +105,20 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{"AD FS"}, nil
}
func (c *Collector) Close() error {
c.perfDataCollector.Close()
func (c *Collector) Close(_ *slog.Logger) error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
var err error
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "AD FS", nil)
if err != nil {
return fmt.Errorf("failed to create AD FS collector: %w", err)
}
c.adLoginConnectionFailures = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ad_login_connection_failures_total"),
"Total number of connection failures to an Active Directory domain controller",
@@ -288,13 +311,13 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
nil,
nil,
)
c.wsfedTokenRequests = prometheus.NewDesc(
c.wsFedTokenRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "wsfed_token_requests_success_total"),
"Total number of successful RP tokens issued over WS-Fed protocol",
nil,
nil,
)
c.wstrustTokenRequests = prometheus.NewDesc(
c.wsTrustTokenRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "wstrust_token_requests_success_total"),
"Total number of successful RP tokens issued over WS-Trust protocol",
nil,
@@ -358,318 +381,268 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
return 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"`
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 *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
var adfsData []perflibADFS
err := perflib.UnmarshalObject(ctx.PerfObjects["AD FS"], &adfsData, logger)
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
err := c.perfDataCollector.Collect(&c.perfDataObject)
if err != nil {
return err
return fmt.Errorf("failed to collect ADFS metrics: %w", err)
}
ch <- prometheus.MustNewConstMetric(
c.adLoginConnectionFailures,
prometheus.CounterValue,
adfsData[0].AdLoginConnectionFailures,
c.perfDataObject[0].AdLoginConnectionFailures,
)
ch <- prometheus.MustNewConstMetric(
c.certificateAuthentications,
prometheus.CounterValue,
adfsData[0].CertificateAuthentications,
c.perfDataObject[0].CertificateAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.deviceAuthentications,
prometheus.CounterValue,
adfsData[0].DeviceAuthentications,
c.perfDataObject[0].DeviceAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.extranetAccountLockouts,
prometheus.CounterValue,
adfsData[0].ExtranetAccountLockouts,
c.perfDataObject[0].ExtranetAccountLockouts,
)
ch <- prometheus.MustNewConstMetric(
c.federatedAuthentications,
prometheus.CounterValue,
adfsData[0].FederatedAuthentications,
c.perfDataObject[0].FederatedAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.passportAuthentications,
prometheus.CounterValue,
adfsData[0].PassportAuthentications,
c.perfDataObject[0].PassportAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.passiveRequests,
prometheus.CounterValue,
adfsData[0].PassiveRequests,
c.perfDataObject[0].PassiveRequests,
)
ch <- prometheus.MustNewConstMetric(
c.passwordChangeFailed,
prometheus.CounterValue,
adfsData[0].PasswordChangeFailed,
c.perfDataObject[0].PasswordChangeFailed,
)
ch <- prometheus.MustNewConstMetric(
c.passwordChangeSucceeded,
prometheus.CounterValue,
adfsData[0].PasswordChangeSucceeded,
c.perfDataObject[0].PasswordChangeSucceeded,
)
ch <- prometheus.MustNewConstMetric(
c.tokenRequests,
prometheus.CounterValue,
adfsData[0].TokenRequests,
c.perfDataObject[0].TokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.windowsIntegratedAuthentications,
prometheus.CounterValue,
adfsData[0].WindowsIntegratedAuthentications,
c.perfDataObject[0].WindowsIntegratedAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthAuthZRequests,
prometheus.CounterValue,
adfsData[0].OAuthAuthZRequests,
c.perfDataObject[0].OAuthAuthZRequests,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientAuthentications,
c.perfDataObject[0].OAuthClientAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientAuthenticationsFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientAuthenticationFailures,
c.perfDataObject[0].OAuthClientAuthenticationFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientCredentialsRequestFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientCredentialRequestFailures,
c.perfDataObject[0].OAuthClientCredentialRequestFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientCredentialsRequests,
prometheus.CounterValue,
adfsData[0].OAuthClientCredentialRequests,
c.perfDataObject[0].OAuthClientCredentialRequests,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientPrivateKeyJwtAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientPrivKeyJWTAuthnFailures,
c.perfDataObject[0].OAuthClientPrivateKeyJWTAuthenticationFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientPrivateKeyJwtAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientPrivKeyJWTAuthentications,
c.perfDataObject[0].OAuthClientPrivateKeyJWTAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientSecretBasicAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientBasicAuthnFailures,
c.perfDataObject[0].OAuthClientBasicAuthenticationFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientSecretBasicAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientBasicAuthentications,
c.perfDataObject[0].OAuthClientBasicAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientSecretPostAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientSecretPostAuthnFailures,
c.perfDataObject[0].OAuthClientSecretPostAuthenticationFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientSecretPostAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientSecretPostAuthentications,
c.perfDataObject[0].OAuthClientSecretPostAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientWindowsIntegratedAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].OAuthClientWindowsAuthnFailures,
c.perfDataObject[0].OAuthClientWindowsAuthenticationFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthClientWindowsIntegratedAuthentications,
prometheus.CounterValue,
adfsData[0].OAuthClientWindowsAuthentications,
c.perfDataObject[0].OAuthClientWindowsAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthLogonCertificateRequestFailures,
prometheus.CounterValue,
adfsData[0].OAuthLogonCertRequestFailures,
c.perfDataObject[0].OAuthLogonCertRequestFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthLogonCertificateTokenRequests,
prometheus.CounterValue,
adfsData[0].OAuthLogonCertTokenRequests,
c.perfDataObject[0].OAuthLogonCertTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthPasswordGrantRequestFailures,
prometheus.CounterValue,
adfsData[0].OAuthPasswordGrantRequestFailures,
c.perfDataObject[0].OAuthPasswordGrantRequestFailures,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthPasswordGrantRequests,
prometheus.CounterValue,
adfsData[0].OAuthPasswordGrantRequests,
c.perfDataObject[0].OAuthPasswordGrantRequests,
)
ch <- prometheus.MustNewConstMetric(
c.oAuthTokenRequests,
prometheus.CounterValue,
adfsData[0].OAuthTokenRequests,
c.perfDataObject[0].OAuthTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.samlPTokenRequests,
prometheus.CounterValue,
adfsData[0].SAMLPTokenRequests,
c.perfDataObject[0].SamlPTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.ssoAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].SSOAuthenticationFailures,
c.perfDataObject[0].SsoAuthenticationFailures,
)
ch <- prometheus.MustNewConstMetric(
c.ssoAuthentications,
prometheus.CounterValue,
adfsData[0].SSOAuthentications,
c.perfDataObject[0].SsoAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.wsfedTokenRequests,
c.wsFedTokenRequests,
prometheus.CounterValue,
adfsData[0].WSFedTokenRequests,
c.perfDataObject[0].WsFedTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.wstrustTokenRequests,
c.wsTrustTokenRequests,
prometheus.CounterValue,
adfsData[0].WSTrustTokenRequests,
c.perfDataObject[0].WsTrustTokenRequests,
)
ch <- prometheus.MustNewConstMetric(
c.upAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].UsernamePasswordAuthnFailures,
c.perfDataObject[0].UsernamePasswordAuthenticationFailures,
)
ch <- prometheus.MustNewConstMetric(
c.upAuthentications,
prometheus.CounterValue,
adfsData[0].UsernamePasswordAuthentications,
c.perfDataObject[0].UsernamePasswordAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.externalAuthenticationFailures,
prometheus.CounterValue,
adfsData[0].ExternalAuthNFailures,
c.perfDataObject[0].ExternalAuthNFailures,
)
ch <- prometheus.MustNewConstMetric(
c.externalAuthentications,
prometheus.CounterValue,
adfsData[0].ExternalAuthentications,
c.perfDataObject[0].ExternalAuthentications,
)
ch <- prometheus.MustNewConstMetric(
c.artifactDBFailures,
prometheus.CounterValue,
adfsData[0].ArtifactDBFailures,
c.perfDataObject[0].ArtifactDBFailures,
)
ch <- prometheus.MustNewConstMetric(
c.avgArtifactDBQueryTime,
prometheus.CounterValue,
adfsData[0].AvgArtifactDBQueryTime*math.Pow(10, -8),
c.perfDataObject[0].AvgArtifactDBQueryTime*math.Pow(10, -8),
)
ch <- prometheus.MustNewConstMetric(
c.configDBFailures,
prometheus.CounterValue,
adfsData[0].ConfigDBFailures,
c.perfDataObject[0].ConfigDBFailures,
)
ch <- prometheus.MustNewConstMetric(
c.avgConfigDBQueryTime,
prometheus.CounterValue,
adfsData[0].AvgConfigDBQueryTime*math.Pow(10, -8),
c.perfDataObject[0].AvgConfigDBQueryTime*math.Pow(10, -8),
)
ch <- prometheus.MustNewConstMetric(
c.federationMetadataRequests,
prometheus.CounterValue,
adfsData[0].FederationMetadataRequests,
c.perfDataObject[0].FederationMetadataRequests,
)
return nil

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package adfs_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/adfs"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, adfs.Name, adfs.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, adfs.New, nil)
}

View File

@@ -0,0 +1,62 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package adfs
type perfDataCounterValues struct {
AdLoginConnectionFailures float64 `perfdata:"AD Login Connection Failures"`
ArtifactDBFailures float64 `perfdata:"Artifact Database Connection Failures"`
AvgArtifactDBQueryTime float64 `perfdata:"Average Artifact Database Query Time"`
AvgConfigDBQueryTime float64 `perfdata:"Average Config Database Query Time"`
CertificateAuthentications float64 `perfdata:"Certificate Authentications"`
ConfigDBFailures float64 `perfdata:"Configuration Database Connection Failures"`
DeviceAuthentications float64 `perfdata:"Device Authentications"`
ExternalAuthentications float64 `perfdata:"External Authentications"`
ExternalAuthNFailures float64 `perfdata:"External Authentication Failures"`
ExtranetAccountLockouts float64 `perfdata:"Extranet Account Lockouts"`
FederatedAuthentications float64 `perfdata:"Federated Authentications"`
FederationMetadataRequests float64 `perfdata:"Federation Metadata Requests"`
OAuthAuthZRequests float64 `perfdata:"OAuth AuthZ Requests"`
OAuthClientAuthenticationFailures float64 `perfdata:"OAuth Client Authentications Failures"`
OAuthClientAuthentications float64 `perfdata:"OAuth Client Authentications"`
OAuthClientBasicAuthenticationFailures float64 `perfdata:"OAuth Client Secret Basic Authentication Failures"`
OAuthClientBasicAuthentications float64 `perfdata:"OAuth Client Secret Basic Authentications"`
OAuthClientCredentialRequestFailures float64 `perfdata:"OAuth Client Credentials Request Failures"`
OAuthClientCredentialRequests float64 `perfdata:"OAuth Client Credentials Requests"`
OAuthClientPrivateKeyJWTAuthenticationFailures float64 `perfdata:"OAuth Client Private Key Jwt Authentication Failures"`
OAuthClientPrivateKeyJWTAuthentications float64 `perfdata:"OAuth Client Private Key Jwt Authentications"`
OAuthClientSecretPostAuthenticationFailures float64 `perfdata:"OAuth Client Secret Post Authentication Failures"`
OAuthClientSecretPostAuthentications float64 `perfdata:"OAuth Client Secret Post Authentications"`
OAuthClientWindowsAuthenticationFailures float64 `perfdata:"OAuth Client Windows Integrated Authentication Failures"`
OAuthClientWindowsAuthentications float64 `perfdata:"OAuth Client Windows Integrated Authentications"`
OAuthLogonCertRequestFailures float64 `perfdata:"OAuth Logon Certificate Request Failures"`
OAuthLogonCertTokenRequests float64 `perfdata:"OAuth Logon Certificate Token Requests"`
OAuthPasswordGrantRequestFailures float64 `perfdata:"OAuth Password Grant Request Failures"`
OAuthPasswordGrantRequests float64 `perfdata:"OAuth Password Grant Requests"`
OAuthTokenRequests float64 `perfdata:"OAuth Token Requests"`
PassiveRequests float64 `perfdata:"Passive Requests"`
PassportAuthentications float64 `perfdata:"Microsoft Passport Authentications"`
PasswordChangeFailed float64 `perfdata:"Password Change Failed Requests"`
PasswordChangeSucceeded float64 `perfdata:"Password Change Successful Requests"`
SamlPTokenRequests float64 `perfdata:"SAML-P Token Requests"`
SsoAuthenticationFailures float64 `perfdata:"SSO Authentication Failures"`
SsoAuthentications float64 `perfdata:"SSO Authentications"`
TokenRequests float64 `perfdata:"Token Requests"`
UsernamePasswordAuthenticationFailures float64 `perfdata:"U/P Authentication Failures"`
UsernamePasswordAuthentications float64 `perfdata:"U/P Authentications"`
WindowsIntegratedAuthentications float64 `perfdata:"Windows Integrated Authentications"`
WsFedTokenRequests float64 `perfdata:"WS-Fed Token Requests"`
WsTrustTokenRequests float64 `perfdata:"WS-Trust Token Requests"`
}

View File

@@ -1,28 +1,45 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cache
import (
"errors"
"fmt"
"log/slog"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/perflib"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "cache"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for Perflib Cache metrics.
type Collector struct {
config Config
perfDataCollector *pdh.Collector
perfDataObject []perfDataCounterValues
asyncCopyReadsTotal *prometheus.Desc
asyncDataMapsTotal *prometheus.Desc
asyncFastReadsTotal *prometheus.Desc
@@ -74,15 +91,20 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{"Cache"}, nil
}
func (c *Collector) Close() error {
c.perfDataCollector.Close()
func (c *Collector) Close(_ *slog.Logger) error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
var err error
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Cache", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Cache collector: %w", err)
}
c.asyncCopyReadsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "async_copy_reads_total"),
"(AsyncCopyReadsTotal)",
@@ -262,238 +284,184 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
}
// Collect implements the Collector interface.
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
if err := c.collect(ctx, logger, ch); err != nil {
logger.Error("failed collecting cache metrics",
slog.Any("err", err),
)
return err
}
return nil
}
// Perflib "Cache":
// - https://docs.microsoft.com/en-us/previous-versions/aa394267(v=vs.85)
type perflibCache struct {
AsyncCopyReadsTotal float64 `perflib:"Async Copy Reads/sec"`
AsyncDataMapsTotal float64 `perflib:"Async Data Maps/sec"`
AsyncFastReadsTotal float64 `perflib:"Async Fast Reads/sec"`
AsyncMDLReadsTotal float64 `perflib:"Async MDL Reads/sec"`
AsyncPinReadsTotal float64 `perflib:"Async Pin Reads/sec"`
CopyReadHitsTotal float64 `perflib:"Copy Read Hits %"`
CopyReadsTotal float64 `perflib:"Copy Reads/sec"`
DataFlushesTotal float64 `perflib:"Data Flushes/sec"`
DataFlushPagesTotal float64 `perflib:"Data Flush Pages/sec"`
DataMapHitsPercent float64 `perflib:"Data Map Hits %"`
DataMapPinsTotal float64 `perflib:"Data Map Pins/sec"`
DataMapsTotal float64 `perflib:"Data Maps/sec"`
DirtyPages float64 `perflib:"Dirty Pages"`
DirtyPageThreshold float64 `perflib:"Dirty Page Threshold"`
FastReadNotPossiblesTotal float64 `perflib:"Fast Read Not Possibles/sec"`
FastReadResourceMissesTotal float64 `perflib:"Fast Read Resource Misses/sec"`
FastReadsTotal float64 `perflib:"Fast Reads/sec"`
LazyWriteFlushesTotal float64 `perflib:"Lazy Write Flushes/sec"`
LazyWritePagesTotal float64 `perflib:"Lazy Write Pages/sec"`
MDLReadHitsTotal float64 `perflib:"MDL Read Hits %"`
MDLReadsTotal float64 `perflib:"MDL Reads/sec"`
PinReadHitsTotal float64 `perflib:"Pin Read Hits %"`
PinReadsTotal float64 `perflib:"Pin Reads/sec"`
ReadAheadsTotal float64 `perflib:"Read Aheads/sec"`
SyncCopyReadsTotal float64 `perflib:"Sync Copy Reads/sec"`
SyncDataMapsTotal float64 `perflib:"Sync Data Maps/sec"`
SyncFastReadsTotal float64 `perflib:"Sync Fast Reads/sec"`
SyncMDLReadsTotal float64 `perflib:"Sync MDL Reads/sec"`
SyncPinReadsTotal float64 `perflib:"Sync Pin Reads/sec"`
}
func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
var dst []perflibCache // Single-instance class, array is required but will have single entry.
if err := perflib.UnmarshalObject(ctx.PerfObjects["Cache"], &dst, logger); err != nil {
return err
}
if len(dst) != 1 {
return errors.New("expected single instance of Cache")
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
err := c.perfDataCollector.Collect(&c.perfDataObject)
if err != nil {
return fmt.Errorf("failed to collect Cache metrics: %w", err)
}
ch <- prometheus.MustNewConstMetric(
c.asyncCopyReadsTotal,
prometheus.CounterValue,
dst[0].AsyncCopyReadsTotal,
c.perfDataObject[0].AsyncCopyReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.asyncDataMapsTotal,
prometheus.CounterValue,
dst[0].AsyncDataMapsTotal,
c.perfDataObject[0].AsyncDataMapsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.asyncFastReadsTotal,
prometheus.CounterValue,
dst[0].AsyncFastReadsTotal,
c.perfDataObject[0].AsyncFastReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.asyncMDLReadsTotal,
prometheus.CounterValue,
dst[0].AsyncMDLReadsTotal,
c.perfDataObject[0].AsyncMDLReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.asyncPinReadsTotal,
prometheus.CounterValue,
dst[0].AsyncPinReadsTotal,
c.perfDataObject[0].AsyncPinReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.copyReadHitsTotal,
prometheus.GaugeValue,
dst[0].CopyReadHitsTotal,
c.perfDataObject[0].CopyReadHitsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.copyReadsTotal,
prometheus.CounterValue,
dst[0].CopyReadsTotal,
c.perfDataObject[0].CopyReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.dataFlushesTotal,
prometheus.CounterValue,
dst[0].DataFlushesTotal,
c.perfDataObject[0].DataFlushesTotal,
)
ch <- prometheus.MustNewConstMetric(
c.dataFlushPagesTotal,
prometheus.CounterValue,
dst[0].DataFlushPagesTotal,
c.perfDataObject[0].DataFlushPagesTotal,
)
ch <- prometheus.MustNewConstMetric(
c.dataMapHitsPercent,
prometheus.GaugeValue,
dst[0].DataMapHitsPercent,
c.perfDataObject[0].DataMapHitsPercent,
)
ch <- prometheus.MustNewConstMetric(
c.dataMapPinsTotal,
prometheus.CounterValue,
dst[0].DataMapPinsTotal,
c.perfDataObject[0].DataMapPinsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.dataMapsTotal,
prometheus.CounterValue,
dst[0].DataMapsTotal,
c.perfDataObject[0].DataMapsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.dirtyPages,
prometheus.GaugeValue,
dst[0].DirtyPages,
c.perfDataObject[0].DirtyPages,
)
ch <- prometheus.MustNewConstMetric(
c.dirtyPageThreshold,
prometheus.GaugeValue,
dst[0].DirtyPageThreshold,
c.perfDataObject[0].DirtyPageThreshold,
)
ch <- prometheus.MustNewConstMetric(
c.fastReadNotPossiblesTotal,
prometheus.CounterValue,
dst[0].FastReadNotPossiblesTotal,
c.perfDataObject[0].FastReadNotPossiblesTotal,
)
ch <- prometheus.MustNewConstMetric(
c.fastReadResourceMissesTotal,
prometheus.CounterValue,
dst[0].FastReadResourceMissesTotal,
c.perfDataObject[0].FastReadResourceMissesTotal,
)
ch <- prometheus.MustNewConstMetric(
c.fastReadsTotal,
prometheus.CounterValue,
dst[0].FastReadsTotal,
c.perfDataObject[0].FastReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.lazyWriteFlushesTotal,
prometheus.CounterValue,
dst[0].LazyWriteFlushesTotal,
c.perfDataObject[0].LazyWriteFlushesTotal,
)
ch <- prometheus.MustNewConstMetric(
c.lazyWritePagesTotal,
prometheus.CounterValue,
dst[0].LazyWritePagesTotal,
c.perfDataObject[0].LazyWritePagesTotal,
)
ch <- prometheus.MustNewConstMetric(
c.mdlReadHitsTotal,
prometheus.CounterValue,
dst[0].MDLReadHitsTotal,
c.perfDataObject[0].MdlReadHitsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.mdlReadsTotal,
prometheus.CounterValue,
dst[0].MDLReadsTotal,
c.perfDataObject[0].MdlReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.pinReadHitsTotal,
prometheus.CounterValue,
dst[0].PinReadHitsTotal,
c.perfDataObject[0].PinReadHitsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.pinReadsTotal,
prometheus.CounterValue,
dst[0].PinReadsTotal,
c.perfDataObject[0].PinReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.readAheadsTotal,
prometheus.CounterValue,
dst[0].ReadAheadsTotal,
c.perfDataObject[0].ReadAheadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.syncCopyReadsTotal,
prometheus.CounterValue,
dst[0].SyncCopyReadsTotal,
c.perfDataObject[0].SyncCopyReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.syncDataMapsTotal,
prometheus.CounterValue,
dst[0].SyncDataMapsTotal,
c.perfDataObject[0].SyncDataMapsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.syncFastReadsTotal,
prometheus.CounterValue,
dst[0].SyncFastReadsTotal,
c.perfDataObject[0].SyncFastReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.syncMDLReadsTotal,
prometheus.CounterValue,
dst[0].SyncMDLReadsTotal,
c.perfDataObject[0].SyncMDLReadsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.syncPinReadsTotal,
prometheus.CounterValue,
dst[0].SyncPinReadsTotal,
c.perfDataObject[0].SyncPinReadsTotal,
)
return nil

31
internal/collector/cache/cache_test.go vendored Normal file
View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cache_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/cache"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, cache.Name, cache.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, cache.New, nil)
}

50
internal/collector/cache/types.go vendored Normal file
View File

@@ -0,0 +1,50 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cache
// Perflib "Cache":
// - https://docs.microsoft.com/en-us/previous-versions/aa394267(v=vs.85)
type perfDataCounterValues struct {
AsyncCopyReadsTotal float64 `perfdata:"Async Copy Reads/sec"`
AsyncDataMapsTotal float64 `perfdata:"Async Data Maps/sec"`
AsyncFastReadsTotal float64 `perfdata:"Async Fast Reads/sec"`
AsyncMDLReadsTotal float64 `perfdata:"Async MDL Reads/sec"`
AsyncPinReadsTotal float64 `perfdata:"Async Pin Reads/sec"`
CopyReadHitsTotal float64 `perfdata:"Copy Read Hits %"`
CopyReadsTotal float64 `perfdata:"Copy Reads/sec"`
DataFlushesTotal float64 `perfdata:"Data Flushes/sec"`
DataFlushPagesTotal float64 `perfdata:"Data Flush Pages/sec"`
DataMapHitsPercent float64 `perfdata:"Data Map Hits %"`
DataMapPinsTotal float64 `perfdata:"Data Map Pins/sec"`
DataMapsTotal float64 `perfdata:"Data Maps/sec"`
DirtyPages float64 `perfdata:"Dirty Pages"`
DirtyPageThreshold float64 `perfdata:"Dirty Page Threshold"`
FastReadNotPossiblesTotal float64 `perfdata:"Fast Read Not Possibles/sec"`
FastReadResourceMissesTotal float64 `perfdata:"Fast Read Resource Misses/sec"`
FastReadsTotal float64 `perfdata:"Fast Reads/sec"`
LazyWriteFlushesTotal float64 `perfdata:"Lazy Write Flushes/sec"`
LazyWritePagesTotal float64 `perfdata:"Lazy Write Pages/sec"`
MdlReadHitsTotal float64 `perfdata:"MDL Read Hits %"`
MdlReadsTotal float64 `perfdata:"MDL Reads/sec"`
PinReadHitsTotal float64 `perfdata:"Pin Read Hits %"`
PinReadsTotal float64 `perfdata:"Pin Reads/sec"`
ReadAheadsTotal float64 `perfdata:"Read Aheads/sec"`
SyncCopyReadsTotal float64 `perfdata:"Sync Copy Reads/sec"`
SyncDataMapsTotal float64 `perfdata:"Sync Data Maps/sec"`
SyncFastReadsTotal float64 `perfdata:"Sync Fast Reads/sec"`
SyncMDLReadsTotal float64 `perfdata:"Sync MDL Reads/sec"`
SyncPinReadsTotal float64 `perfdata:"Sync Pin Reads/sec"`
}

View File

@@ -1,3 +1,16 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package container
@@ -10,22 +23,25 @@ import (
"github.com/Microsoft/hcsshim"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/perflib"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "container"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for containers metrics.
type Collector struct {
config Config
logger *slog.Logger
// Presence
containerAvailable *prometheus.Desc
@@ -78,15 +94,13 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{}, nil
}
func (c *Collector) Close(_ *slog.Logger) error {
func (c *Collector) Close() error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
c.logger = logger.With(slog.String("collector", Name))
c.containerAvailable = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "available"),
"Available",
@@ -201,28 +215,11 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
if err := c.collect(logger, ch); err != nil {
logger.Error("failed collecting collector metrics",
slog.Any("err", err),
)
return err
}
return nil
}
func (c *Collector) collect(logger *slog.Logger, ch chan<- prometheus.Metric) error {
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
// Types Container is passed to get the containers compute systems only
containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
if err != nil {
logger.Error("Err in Getting containers",
slog.Any("err", err),
)
return err
return fmt.Errorf("error in fetching containers: %w", err)
}
count := len(containers)
@@ -243,14 +240,14 @@ func (c *Collector) collect(logger *slog.Logger, ch chan<- prometheus.Metric) er
for _, containerDetails := range containers {
containerIdWithPrefix := getContainerIdWithPrefix(containerDetails)
if err = c.collectContainer(logger, ch, containerDetails, containerIdWithPrefix); err != nil {
if err = c.collectContainer(ch, containerDetails, containerIdWithPrefix); err != nil {
if hcsshim.IsNotExist(err) {
logger.Debug("err in fetching container statistics",
c.logger.Debug("err in fetching container statistics",
slog.String("container_id", containerDetails.ID),
slog.Any("err", err),
)
} else {
logger.Error("err in fetching container statistics",
c.logger.Error("err in fetching container statistics",
slog.String("container_id", containerDetails.ID),
slog.Any("err", err),
)
@@ -264,7 +261,7 @@ func (c *Collector) collect(logger *slog.Logger, ch chan<- prometheus.Metric) er
containerPrefixes[containerDetails.ID] = containerIdWithPrefix
}
if err = c.collectNetworkMetrics(logger, ch, containerPrefixes); err != nil {
if err = c.collectNetworkMetrics(ch, containerPrefixes); err != nil {
return fmt.Errorf("error in fetching container network statistics: %w", err)
}
@@ -275,7 +272,7 @@ func (c *Collector) collect(logger *slog.Logger, ch chan<- prometheus.Metric) er
return nil
}
func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.Metric, containerDetails hcsshim.ContainerProperties, containerIdWithPrefix string) error {
func (c *Collector) collectContainer(ch chan<- prometheus.Metric, containerDetails hcsshim.ContainerProperties, containerIdWithPrefix string) error {
container, err := hcsshim.OpenContainer(containerDetails.ID)
if err != nil {
return fmt.Errorf("error in opening container: %w", err)
@@ -287,7 +284,7 @@ func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.M
}
if err := container.Close(); err != nil {
logger.Error("error in closing container",
c.logger.Error("error in closing container",
slog.Any("err", err),
)
}
@@ -325,19 +322,19 @@ func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.M
ch <- prometheus.MustNewConstMetric(
c.runtimeTotal,
prometheus.CounterValue,
float64(containerStats.Processor.TotalRuntime100ns)*perflib.TicksToSecondScaleFactor,
float64(containerStats.Processor.TotalRuntime100ns)*pdh.TicksToSecondScaleFactor,
containerIdWithPrefix,
)
ch <- prometheus.MustNewConstMetric(
c.runtimeUser,
prometheus.CounterValue,
float64(containerStats.Processor.RuntimeUser100ns)*perflib.TicksToSecondScaleFactor,
float64(containerStats.Processor.RuntimeUser100ns)*pdh.TicksToSecondScaleFactor,
containerIdWithPrefix,
)
ch <- prometheus.MustNewConstMetric(
c.runtimeKernel,
prometheus.CounterValue,
float64(containerStats.Processor.RuntimeKernel100ns)*perflib.TicksToSecondScaleFactor,
float64(containerStats.Processor.RuntimeKernel100ns)*pdh.TicksToSecondScaleFactor,
containerIdWithPrefix,
)
ch <- prometheus.MustNewConstMetric(
@@ -372,24 +369,20 @@ func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.M
// With HNSv2, the network stats must be collected from hcsshim.HNSListEndpointRequest.
// Network statistics from the container.Statistics() are providing data only, if HNSv1 is used.
// Ref: https://github.com/prometheus-community/windows_exporter/pull/1218
func (c *Collector) collectNetworkMetrics(logger *slog.Logger, ch chan<- prometheus.Metric, containerPrefixes map[string]string) error {
func (c *Collector) collectNetworkMetrics(ch chan<- prometheus.Metric, containerPrefixes map[string]string) error {
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
if err != nil {
logger.Warn("Failed to collect network stats for containers")
return err
return fmt.Errorf("error in fetching HNS endpoints: %w", err)
}
if len(hnsEndpoints) == 0 {
logger.Info("No network stats for containers to collect")
return nil
return errors.New("no network stats for containers to collect")
}
for _, endpoint := range hnsEndpoints {
endpointStats, err := hcsshim.GetHNSEndpointStats(endpoint.Id)
if err != nil {
logger.Warn("Failed to collect network stats for interface "+endpoint.Id,
c.logger.Warn("Failed to collect network stats for interface "+endpoint.Id,
slog.Any("err", err),
)
@@ -400,7 +393,7 @@ func (c *Collector) collectNetworkMetrics(logger *slog.Logger, ch chan<- prometh
containerIdWithPrefix, ok := containerPrefixes[containerId]
if !ok {
logger.Debug("Failed to collect network stats for container " + containerId)
c.logger.Debug("Failed to collect network stats for container " + containerId)
continue
}

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package container_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/container"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, container.Name, container.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, container.New, nil)
}

View File

@@ -0,0 +1,356 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cpu
import (
"fmt"
"log/slog"
"sync"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
)
const Name = "cpu"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
type Collector struct {
config Config
perfDataCollector *pdh.Collector
perfDataObject []perfDataCounterValues
mu sync.Mutex
processorRTCValues map[string]utils.Counter
processorMPerfValues map[string]utils.Counter
logicalProcessors *prometheus.Desc
cStateSecondsTotal *prometheus.Desc
timeTotal *prometheus.Desc
interruptsTotal *prometheus.Desc
dpcsTotal *prometheus.Desc
clockInterruptsTotal *prometheus.Desc
idleBreakEventsTotal *prometheus.Desc
parkingStatus *prometheus.Desc
processorFrequencyMHz *prometheus.Desc
processorPerformance *prometheus.Desc
processorMPerf *prometheus.Desc
processorRTC *prometheus.Desc
processorUtility *prometheus.Desc
processorPrivilegedUtility *prometheus.Desc
}
func New(config *Config) *Collector {
if config == nil {
config = &ConfigDefaults
}
c := &Collector{
config: *config,
}
return c
}
func NewWithFlags(_ *kingpin.Application) *Collector {
return &Collector{}
}
func (c *Collector) GetName() string {
return Name
}
func (c *Collector) Close() error {
c.perfDataCollector.Close()
return nil
}
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
var err error
c.mu = sync.Mutex{}
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Processor Information", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Processor Information collector: %w", err)
}
c.logicalProcessors = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "logical_processor"),
"Total number of logical processors",
nil,
nil,
)
c.cStateSecondsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "cstate_seconds_total"),
"Time spent in low-power idle state",
[]string{"core", "state"},
nil,
)
c.timeTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "time_total"),
"Time that processor spent in different modes (dpc, idle, interrupt, privileged, user)",
[]string{"core", "mode"},
nil,
)
c.interruptsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "interrupts_total"),
"Total number of received and serviced hardware interrupts",
[]string{"core"},
nil,
)
c.dpcsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dpcs_total"),
"Total number of received and serviced deferred procedure calls (DPCs)",
[]string{"core"},
nil,
)
c.clockInterruptsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "clock_interrupts_total"),
"Total number of received and serviced clock tick interrupts",
[]string{"core"},
nil,
)
c.idleBreakEventsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "idle_break_events_total"),
"Total number of time processor was woken from idle",
[]string{"core"},
nil,
)
c.parkingStatus = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "parking_status"),
"Parking Status represents whether a processor is parked or not",
[]string{"core"},
nil,
)
c.processorFrequencyMHz = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "core_frequency_mhz"),
"Core frequency in megahertz",
[]string{"core"},
nil,
)
c.processorPerformance = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "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,
)
c.processorMPerf = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "processor_mperf_total"),
"Processor MPerf is the number of TSC ticks incremented while executing instructions",
[]string{"core"},
nil,
)
c.processorRTC = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "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,
)
c.processorUtility = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "processor_utility_total"),
"Processor Utility represents is the amount of time the core spends executing instructions",
[]string{"core"},
nil,
)
c.processorPrivilegedUtility = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "processor_privileged_utility_total"),
"Processor Privileged Utility represents is the amount of time the core has spent executing instructions inside the kernel",
[]string{"core"},
nil,
)
c.processorRTCValues = map[string]utils.Counter{}
c.processorMPerfValues = map[string]utils.Counter{}
return nil
}
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
c.mu.Lock() // Lock is needed to prevent concurrent map access to c.processorRTCValues
defer c.mu.Unlock()
err := c.perfDataCollector.Collect(&c.perfDataObject)
if err != nil {
return fmt.Errorf("failed to collect Processor Information metrics: %w", err)
}
var coreCount float64
for _, coreData := range c.perfDataObject {
core := coreData.Name
coreCount++
var (
counterProcessorRTCValues utils.Counter
counterProcessorMPerfValues utils.Counter
ok bool
)
if counterProcessorRTCValues, ok = c.processorRTCValues[core]; ok {
counterProcessorRTCValues.AddValue(uint32(coreData.ProcessorUtilityRateSecondValue))
} else {
counterProcessorRTCValues = utils.NewCounter(uint32(coreData.ProcessorUtilityRateSecondValue))
}
c.processorRTCValues[core] = counterProcessorRTCValues
if counterProcessorMPerfValues, ok = c.processorMPerfValues[core]; ok {
counterProcessorMPerfValues.AddValue(uint32(coreData.ProcessorPerformanceSecondValue))
} else {
counterProcessorMPerfValues = utils.NewCounter(uint32(coreData.ProcessorPerformanceSecondValue))
}
c.processorMPerfValues[core] = counterProcessorMPerfValues
ch <- prometheus.MustNewConstMetric(
c.cStateSecondsTotal,
prometheus.CounterValue,
coreData.C1TimeSeconds,
core, "c1",
)
ch <- prometheus.MustNewConstMetric(
c.cStateSecondsTotal,
prometheus.CounterValue,
coreData.C2TimeSeconds,
core, "c2",
)
ch <- prometheus.MustNewConstMetric(
c.cStateSecondsTotal,
prometheus.CounterValue,
coreData.C3TimeSeconds,
core, "c3",
)
ch <- prometheus.MustNewConstMetric(
c.timeTotal,
prometheus.CounterValue,
coreData.IdleTimeSeconds,
core, "idle",
)
ch <- prometheus.MustNewConstMetric(
c.timeTotal,
prometheus.CounterValue,
coreData.InterruptTimeSeconds,
core, "interrupt",
)
ch <- prometheus.MustNewConstMetric(
c.timeTotal,
prometheus.CounterValue,
coreData.DpcTimeSeconds,
core, "dpc",
)
ch <- prometheus.MustNewConstMetric(
c.timeTotal,
prometheus.CounterValue,
coreData.PrivilegedTimeSeconds,
core, "privileged",
)
ch <- prometheus.MustNewConstMetric(
c.timeTotal,
prometheus.CounterValue,
coreData.UserTimeSeconds,
core, "user",
)
ch <- prometheus.MustNewConstMetric(
c.interruptsTotal,
prometheus.CounterValue,
coreData.InterruptsTotal,
core,
)
ch <- prometheus.MustNewConstMetric(
c.dpcsTotal,
prometheus.CounterValue,
coreData.DpcQueuedPerSecond,
core,
)
ch <- prometheus.MustNewConstMetric(
c.clockInterruptsTotal,
prometheus.CounterValue,
coreData.ClockInterruptsTotal,
core,
)
ch <- prometheus.MustNewConstMetric(
c.idleBreakEventsTotal,
prometheus.CounterValue,
coreData.IdleBreakEventsTotal,
core,
)
ch <- prometheus.MustNewConstMetric(
c.parkingStatus,
prometheus.GaugeValue,
coreData.ParkingStatus,
core,
)
ch <- prometheus.MustNewConstMetric(
c.processorFrequencyMHz,
prometheus.GaugeValue,
coreData.ProcessorFrequencyMHz,
core,
)
ch <- prometheus.MustNewConstMetric(
c.processorPerformance,
prometheus.CounterValue,
coreData.ProcessorPerformance,
core,
)
ch <- prometheus.MustNewConstMetric(
c.processorMPerf,
prometheus.CounterValue,
counterProcessorMPerfValues.Value(),
core,
)
ch <- prometheus.MustNewConstMetric(
c.processorRTC,
prometheus.CounterValue,
counterProcessorRTCValues.Value(),
core,
)
ch <- prometheus.MustNewConstMetric(
c.processorUtility,
prometheus.CounterValue,
coreData.ProcessorUtilityRate,
core,
)
ch <- prometheus.MustNewConstMetric(
c.processorPrivilegedUtility,
prometheus.CounterValue,
coreData.PrivilegedUtilitySeconds,
core,
)
}
ch <- prometheus.MustNewConstMetric(
c.logicalProcessors,
prometheus.GaugeValue,
coreCount,
)
return nil
}

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cpu_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/cpu"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, cpu.Name, cpu.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, cpu.New, nil)
}

View File

@@ -0,0 +1,47 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cpu
// Processor performance counters.
type perfDataCounterValues struct {
Name string
C1TimeSeconds float64 `perfdata:"% C1 Time"`
C2TimeSeconds float64 `perfdata:"% C2 Time"`
C3TimeSeconds float64 `perfdata:"% C3 Time"`
C1TransitionsTotal float64 `perfdata:"C1 Transitions/sec"`
C2TransitionsTotal float64 `perfdata:"C2 Transitions/sec"`
C3TransitionsTotal float64 `perfdata:"C3 Transitions/sec"`
ClockInterruptsTotal float64 `perfdata:"Clock Interrupts/sec"`
DpcQueuedPerSecond float64 `perfdata:"DPCs Queued/sec"`
DpcTimeSeconds float64 `perfdata:"% DPC Time"`
IdleBreakEventsTotal float64 `perfdata:"Idle Break Events/sec"`
IdleTimeSeconds float64 `perfdata:"% Idle Time"`
InterruptsTotal float64 `perfdata:"Interrupts/sec"`
InterruptTimeSeconds float64 `perfdata:"% Interrupt Time"`
ParkingStatus float64 `perfdata:"Parking Status"`
PerformanceLimitPercent float64 `perfdata:"% Performance Limit"`
PriorityTimeSeconds float64 `perfdata:"% Priority Time"`
PrivilegedTimeSeconds float64 `perfdata:"% Privileged Time"`
PrivilegedUtilitySeconds float64 `perfdata:"% Privileged Utility"`
ProcessorFrequencyMHz float64 `perfdata:"Processor Frequency"`
ProcessorPerformance float64 `perfdata:"% Processor Performance"`
ProcessorPerformanceSecondValue float64 `perfdata:"% Processor Performance,secondvalue"`
ProcessorTimeSeconds float64 `perfdata:"% Processor Time"`
ProcessorUtilityRate float64 `perfdata:"% Processor Utility"`
ProcessorUtilityRateSecondValue float64 `perfdata:"% Processor Utility,secondvalue"`
UserTimeSeconds float64 `perfdata:"% User Time"`
}

View File

@@ -1,32 +1,45 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cpu_info
import (
"errors"
"fmt"
"log/slog"
"strconv"
"strings"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const (
Name = "cpu_info"
)
const Name = "cpu_info"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_Processor.
type Collector struct {
config Config
wmiClient *wmi.Client
config Config
miSession *mi.Session
miQuery mi.Query
cpuInfo *prometheus.Desc
cpuCoreCount *prometheus.Desc
@@ -57,20 +70,23 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{}, nil
}
func (c *Collector) Close(_ *slog.Logger) error {
func (c *Collector) Close() error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
if wmiClient == nil || wmiClient.SWbemServicesClient == nil {
return errors.New("wmiClient or SWbemServicesClient is nil")
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
if miSession == nil {
return errors.New("miSession is nil")
}
c.wmiClient = wmiClient
miQuery, err := mi.NewQuery("SELECT Architecture, DeviceId, Description, Family, L2CacheSize, L3CacheSize, Name, ThreadCount, NumberOfCores, NumberOfEnabledCore, NumberOfLogicalProcessors FROM Win32_Processor")
if err != nil {
return fmt.Errorf("failed to create WMI query: %w", err)
}
c.miQuery = miQuery
c.miSession = miSession
c.cpuInfo = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, "", Name),
"Labelled CPU information as provided by Win32_Processor",
@@ -132,49 +148,36 @@ func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
nil,
)
var dst []miProcessor
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, c.miQuery); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
return nil
}
type win32Processor struct {
Architecture uint32
DeviceID string
Description string
Family uint16
L2CacheSize uint32
L3CacheSize uint32
Name string
ThreadCount uint32
NumberOfCores uint32
NumberOfEnabledCore uint32
NumberOfLogicalProcessors uint32
type miProcessor struct {
Architecture uint32 `mi:"Architecture"`
DeviceID string `mi:"DeviceID"`
Description string `mi:"Description"`
Family uint16 `mi:"Family"`
L2CacheSize uint32 `mi:"L2CacheSize"`
L3CacheSize uint32 `mi:"L3CacheSize"`
Name string `mi:"Name"`
ThreadCount uint32 `mi:"ThreadCount"`
NumberOfCores uint32 `mi:"NumberOfCores"`
NumberOfEnabledCore uint32 `mi:"NumberOfEnabledCore"`
NumberOfLogicalProcessors uint32 `mi:"NumberOfLogicalProcessors"`
Total int
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
if err := c.collect(ch); err != nil {
logger.Error("failed collecting cpu_info metrics",
slog.Any("err", err),
)
return err
}
return nil
}
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
var dst []win32Processor
// We use a static query here because the provided methods in wmi.go all issue a SELECT *;
// This results in the time-consuming LoadPercentage field being read which seems to measure each CPU
// serially over a 1 second interval, so the scrape time is at least 1s * num_sockets
if err := c.wmiClient.Query("SELECT Architecture, DeviceId, Description, Family, L2CacheSize, L3CacheSize, Name, ThreadCount, NumberOfCores, NumberOfEnabledCore, NumberOfLogicalProcessors FROM Win32_Processor", &dst); err != nil {
return err
}
if len(dst) == 0 {
return errors.New("WMI query returned empty result set")
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
var dst []miProcessor
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, c.miQuery); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
// Some CPUs end up exposing trailing spaces for certain strings, so clean them up

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cpu_info_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/cpu_info"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, cpu_info.Name, cpu_info.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, cpu_info.New, nil)
}

View File

@@ -1,3 +1,16 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cs
@@ -6,16 +19,17 @@ import (
"log/slog"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/headers/sysinfoapi"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/headers/sysinfoapi"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "cs"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI metrics.
@@ -23,10 +37,10 @@ type Collector struct {
config Config
// physicalMemoryBytes
// Deprecated: Use windows_cpu_logical_processor instead
// Deprecated: Use windows_physical_memory_total_bytes instead
physicalMemoryBytes *prometheus.Desc
// logicalProcessors
// Deprecated: Use windows_physical_memory_total_bytes instead
// Deprecated: Use windows_cpu_logical_processor instead
logicalProcessors *prometheus.Desc
// hostname
// Deprecated: Use windows_os_hostname instead
@@ -53,15 +67,11 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{}, nil
}
func (c *Collector) Close(_ *slog.Logger) error {
func (c *Collector) Close() error {
return nil
}
func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
logger.Warn("The cs collector is deprecated and will be removed in a future release. " +
"Logical processors has been moved to cpu_info collector. " +
"Physical memory has been moved to memory collector. " +
@@ -95,21 +105,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
if err := c.collect(ch); err != nil {
logger.Error("failed collecting cs metrics",
slog.Any("err", err),
)
return err
}
return nil
}
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
// Get systeminfo for number of processors
systemInfo := sysinfoapi.GetSystemInfo()

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package cs_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/cs"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, cs.Name, cs.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, cs.New, nil)
}

View File

@@ -1,17 +1,32 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package dfsr
import (
"errors"
"fmt"
"log/slog"
"slices"
"strings"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/perflib"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "dfsr"
@@ -20,6 +35,7 @@ type Config struct {
CollectorsEnabled []string `yaml:"collectors_enabled"`
}
//nolint:gochecknoglobals
var ConfigDefaults = Config{
CollectorsEnabled: []string{"connection", "folder", "volume"},
}
@@ -28,6 +44,13 @@ var ConfigDefaults = Config{
type Collector struct {
config Config
perfDataCollectorConnection *pdh.Collector
perfDataCollectorFolder *pdh.Collector
perfDataCollectorVolume *pdh.Collector
perfDataObjectConnection []perfDataCounterValuesConnection
perfDataObjectFolder []perfDataCounterValuesFolder
perfDataObjectVolume []perfDataCounterValuesVolume
// connection source
connectionBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc
connectionBytesReceivedTotal *prometheus.Desc
@@ -36,17 +59,17 @@ type Collector struct {
connectionRDCBytesReceivedTotal *prometheus.Desc
connectionRDCCompressedSizeOfFilesReceivedTotal *prometheus.Desc
connectionRDCSizeOfFilesReceivedTotal *prometheus.Desc
connectionRDCNumberofFilesReceivedTotal *prometheus.Desc
connectionRDCNumberOfFilesReceivedTotal *prometheus.Desc
connectionSizeOfFilesReceivedTotal *prometheus.Desc
// folder source
folderBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc
folderCompressedSizeOfFilesReceivedTotal *prometheus.Desc
folderConflictBytesCleanedupTotal *prometheus.Desc
folderConflictBytesCleanedUpTotal *prometheus.Desc
folderConflictBytesGeneratedTotal *prometheus.Desc
folderConflictFilesCleanedUpTotal *prometheus.Desc
folderConflictFilesGeneratedTotal *prometheus.Desc
folderConflictfolderCleanupsCompletedTotal *prometheus.Desc
folderConflictFolderCleanupsCompletedTotal *prometheus.Desc
folderConflictSpaceInUse *prometheus.Desc
folderDeletedSpaceInUse *prometheus.Desc
folderDeletedBytesCleanedUpTotal *prometheus.Desc
@@ -58,7 +81,7 @@ type Collector struct {
folderFilesReceivedTotal *prometheus.Desc
folderRDCBytesReceivedTotal *prometheus.Desc
folderRDCCompressedSizeOfFilesReceivedTotal *prometheus.Desc
folderRDCNumberofFilesReceivedTotal *prometheus.Desc
folderRDCNumberOfFilesReceivedTotal *prometheus.Desc
folderRDCSizeOfFilesReceivedTotal *prometheus.Desc
folderSizeOfFilesReceivedTotal *prometheus.Desc
folderStagingSpaceInUse *prometheus.Desc
@@ -74,29 +97,6 @@ type Collector struct {
volumeUSNJournalUnreadPercentage *prometheus.Desc
volumeUSNJournalRecordsAcceptedTotal *prometheus.Desc
volumeUSNJournalRecordsReadTotal *prometheus.Desc
// Map of child Collector functions used during collection
dfsrChildCollectors []dfsrCollectorFunc
}
type dfsrCollectorFunc func(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error
// Map Perflib sources to DFSR Collector names
// e.g, volume -> DFS Replication Service Volumes.
func dfsrGetPerfObjectName(collector string) string {
prefix := "DFS "
suffix := ""
switch collector {
case "connection":
suffix = "Replication Connections"
case "folder":
suffix = "Replicated Folders"
case "volume":
suffix = "Replication Service Volumes"
}
return prefix + suffix
}
func New(config *Config) *Collector {
@@ -119,10 +119,11 @@ func NewWithFlags(app *kingpin.Application) *Collector {
c := &Collector{
config: ConfigDefaults,
}
c.config.CollectorsEnabled = make([]string, 0)
var collectorsEnabled string
app.Flag("collectors.dfsr.sources-enabled", "Comma-separated list of DFSR Perflib sources to use.").
app.Flag("collector.dfsr.sources-enabled", "Comma-separated list of DFSR Perflib sources to use.").
Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
app.Action(func(*kingpin.ParseContext) error {
@@ -138,27 +139,50 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
// Perflib sources are dynamic, depending on the enabled child collectors
expandedChildCollectors := slices.Compact(c.config.CollectorsEnabled)
perflibDependencies := make([]string, 0, len(expandedChildCollectors))
for _, source := range expandedChildCollectors {
perflibDependencies = append(perflibDependencies, dfsrGetPerfObjectName(source))
func (c *Collector) Close() error {
if slices.Contains(c.config.CollectorsEnabled, "connection") {
c.perfDataCollectorConnection.Close()
}
return perflibDependencies, nil
}
if slices.Contains(c.config.CollectorsEnabled, "folder") {
c.perfDataCollectorFolder.Close()
}
if slices.Contains(c.config.CollectorsEnabled, "volume") {
c.perfDataCollectorVolume.Close()
}
func (c *Collector) Close(_ *slog.Logger) error {
return nil
}
func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
logger = logger.With(slog.String("collector", Name))
logger.Info("dfsr collector is in an experimental state! Metrics for this collector have not been tested.")
var err error
if slices.Contains(c.config.CollectorsEnabled, "connection") {
c.perfDataCollectorConnection, err = pdh.NewCollector[perfDataCounterValuesConnection](pdh.CounterTypeRaw, "DFS Replication Connections", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create DFS Replication Connections collector: %w", err)
}
}
if slices.Contains(c.config.CollectorsEnabled, "folder") {
c.perfDataCollectorFolder, err = pdh.NewCollector[perfDataCounterValuesFolder](pdh.CounterTypeRaw, "DFS Replicated Folders", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create DFS Replicated Folders collector: %w", err)
}
}
if slices.Contains(c.config.CollectorsEnabled, "volume") {
c.perfDataCollectorVolume, err = pdh.NewCollector[perfDataCounterValuesVolume](pdh.CounterTypeRaw, "DFS Replication Service Volumes", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create DFS Replication Service Volumes collector: %w", err)
}
}
// connection
c.connectionBandwidthSavingsUsingDFSReplicationTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_bandwidth_savings_using_dfs_replication_bytes_total"),
@@ -202,7 +226,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
nil,
)
c.connectionRDCNumberofFilesReceivedTotal = prometheus.NewDesc(
c.connectionRDCNumberOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_received_files_total"),
"Total number of files received using remote differential compression",
[]string{"name"},
@@ -238,7 +262,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
nil,
)
c.folderConflictBytesCleanedupTotal = prometheus.NewDesc(
c.folderConflictBytesCleanedUpTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_cleaned_up_bytes_total"),
"Total size of conflict loser files and folders deleted from the Conflict and Deleted folder, in bytes",
[]string{"name"},
@@ -266,7 +290,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
nil,
)
c.folderConflictfolderCleanupsCompletedTotal = prometheus.NewDesc(
c.folderConflictFolderCleanupsCompletedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_folder_cleanups_total"),
"Number of deletions of conflict loser files and folders in the Conflict and Deleted",
[]string{"name"},
@@ -350,7 +374,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
nil,
)
c.folderRDCNumberofFilesReceivedTotal = prometheus.NewDesc(
c.folderRDCNumberOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_received_files_total"),
"Total number of files received with Remote Differential Compression",
[]string{"name"},
@@ -449,428 +473,348 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
nil,
)
// Perflib sources are dynamic, depending on the enabled child collectors
expandedChildCollectors := slices.Compact(c.config.CollectorsEnabled)
c.dfsrChildCollectors = c.getDFSRChildCollectors(expandedChildCollectors)
return nil
}
// Maps enabled child collectors names to their relevant collection function,
// for use in Collector.Collect().
func (c *Collector) getDFSRChildCollectors(enabledCollectors []string) []dfsrCollectorFunc {
var dfsrCollectors []dfsrCollectorFunc
for _, collector := range enabledCollectors {
switch collector {
case "connection":
dfsrCollectors = append(dfsrCollectors, c.collectConnection)
case "folder":
dfsrCollectors = append(dfsrCollectors, c.collectFolder)
case "volume":
dfsrCollectors = append(dfsrCollectors, c.collectVolume)
}
}
return dfsrCollectors
}
// Collect implements the Collector interface.
// Sends metric values for each metric to the provided prometheus Metric channel.
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
for _, fn := range c.dfsrChildCollectors {
err := fn(ctx, logger, ch)
if err != nil {
return err
}
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
errs := make([]error, 0, 3)
if slices.Contains(c.config.CollectorsEnabled, "connection") {
errs = append(errs, c.collectPDHConnection(ch))
}
return nil
}
// PerflibDFSRConnection Perflib: "DFS Replication Service Connections".
type PerflibDFSRConnection struct {
Name string
BandwidthSavingsUsingDFSReplicationTotal float64 `perflib:"Bandwidth Savings Using DFS Replication"`
BytesReceivedTotal float64 `perflib:"Total Bytes Received"`
CompressedSizeOfFilesReceivedTotal float64 `perflib:"Compressed Size of Files Received"`
FilesReceivedTotal float64 `perflib:"Total Files Received"`
RDCBytesReceivedTotal float64 `perflib:"RDC Bytes Received"`
RDCCompressedSizeOfFilesReceivedTotal float64 `perflib:"RDC Compressed Size of Files Received"`
RDCNumberofFilesReceivedTotal float64 `perflib:"RDC Number of Files Received"`
RDCSizeOfFilesReceivedTotal float64 `perflib:"RDC Size of Files Received"`
SizeOfFilesReceivedTotal float64 `perflib:"Size of Files Received"`
}
func (c *Collector) collectConnection(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
var dst []PerflibDFSRConnection
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Connections"], &dst, logger); err != nil {
return err
if slices.Contains(c.config.CollectorsEnabled, "folder") {
errs = append(errs, c.collectPDHFolder(ch))
}
for _, connection := range dst {
if slices.Contains(c.config.CollectorsEnabled, "volume") {
errs = append(errs, c.collectPDHVolume(ch))
}
return errors.Join(errs...)
}
func (c *Collector) collectPDHConnection(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorConnection.Collect(&c.perfDataObjectConnection)
if err != nil {
return fmt.Errorf("failed to collect DFS Replication Connections metrics: %w", err)
}
for _, connection := range c.perfDataObjectConnection {
name := connection.Name
ch <- prometheus.MustNewConstMetric(
c.connectionBandwidthSavingsUsingDFSReplicationTotal,
prometheus.CounterValue,
connection.BandwidthSavingsUsingDFSReplicationTotal,
connection.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.connectionBytesReceivedTotal,
prometheus.CounterValue,
connection.BytesReceivedTotal,
connection.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.connectionCompressedSizeOfFilesReceivedTotal,
prometheus.CounterValue,
connection.CompressedSizeOfFilesReceivedTotal,
connection.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.connectionFilesReceivedTotal,
prometheus.CounterValue,
connection.FilesReceivedTotal,
connection.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.connectionRDCBytesReceivedTotal,
prometheus.CounterValue,
connection.RDCBytesReceivedTotal,
connection.Name,
connection.RdcBytesReceivedTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.connectionRDCCompressedSizeOfFilesReceivedTotal,
prometheus.CounterValue,
connection.RDCCompressedSizeOfFilesReceivedTotal,
connection.Name,
connection.RdcCompressedSizeOfFilesReceivedTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.connectionRDCSizeOfFilesReceivedTotal,
prometheus.CounterValue,
connection.RDCSizeOfFilesReceivedTotal,
connection.Name,
connection.RdcSizeOfFilesReceivedTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.connectionRDCNumberofFilesReceivedTotal,
c.connectionRDCNumberOfFilesReceivedTotal,
prometheus.CounterValue,
connection.RDCNumberofFilesReceivedTotal,
connection.Name,
connection.RdcNumberOfFilesReceivedTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.connectionSizeOfFilesReceivedTotal,
prometheus.CounterValue,
connection.SizeOfFilesReceivedTotal,
connection.Name,
name,
)
}
return nil
}
// perflibDFSRFolder Perflib: "DFS Replicated Folder".
type perflibDFSRFolder struct {
Name string
BandwidthSavingsUsingDFSReplicationTotal float64 `perflib:"Bandwidth Savings Using DFS Replication"`
CompressedSizeOfFilesReceivedTotal float64 `perflib:"Compressed Size of Files Received"`
ConflictBytesCleanedupTotal float64 `perflib:"Conflict Bytes Cleaned Up"`
ConflictBytesGeneratedTotal float64 `perflib:"Conflict Bytes Generated"`
ConflictFilesCleanedUpTotal float64 `perflib:"Conflict Files Cleaned Up"`
ConflictFilesGeneratedTotal float64 `perflib:"Conflict Files Generated"`
ConflictFolderCleanupsCompletedTotal float64 `perflib:"Conflict folder Cleanups Completed"`
ConflictSpaceInUse float64 `perflib:"Conflict Space In Use"`
DeletedSpaceInUse float64 `perflib:"Deleted Space In Use"`
DeletedBytesCleanedUpTotal float64 `perflib:"Deleted Bytes Cleaned Up"`
DeletedBytesGeneratedTotal float64 `perflib:"Deleted Bytes Generated"`
DeletedFilesCleanedUpTotal float64 `perflib:"Deleted Files Cleaned Up"`
DeletedFilesGeneratedTotal float64 `perflib:"Deleted Files Generated"`
FileInstallsRetriedTotal float64 `perflib:"File Installs Retried"`
FileInstallsSucceededTotal float64 `perflib:"File Installs Succeeded"`
FilesReceivedTotal float64 `perflib:"Total Files Received"`
RDCBytesReceivedTotal float64 `perflib:"RDC Bytes Received"`
RDCCompressedSizeOfFilesReceivedTotal float64 `perflib:"RDC Compressed Size of Files Received"`
RDCNumberofFilesReceivedTotal float64 `perflib:"RDC Number of Files Received"`
RDCSizeOfFilesReceivedTotal float64 `perflib:"RDC Size of Files Received"`
SizeOfFilesReceivedTotal float64 `perflib:"Size of Files Received"`
StagingSpaceInUse float64 `perflib:"Staging Space In Use"`
StagingBytesCleanedUpTotal float64 `perflib:"Staging Bytes Cleaned Up"`
StagingBytesGeneratedTotal float64 `perflib:"Staging Bytes Generated"`
StagingFilesCleanedUpTotal float64 `perflib:"Staging Files Cleaned Up"`
StagingFilesGeneratedTotal float64 `perflib:"Staging Files Generated"`
UpdatesDroppedTotal float64 `perflib:"Updates Dropped"`
}
func (c *Collector) collectFolder(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
var dst []perflibDFSRFolder
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replicated Folders"], &dst, logger); err != nil {
return err
func (c *Collector) collectPDHFolder(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorFolder.Collect(&c.perfDataObjectFolder)
if err != nil {
return fmt.Errorf("failed to collect DFS Replicated Folders metrics: %w", err)
}
for _, folder := range dst {
for _, folder := range c.perfDataObjectFolder {
name := folder.Name
ch <- prometheus.MustNewConstMetric(
c.folderBandwidthSavingsUsingDFSReplicationTotal,
prometheus.CounterValue,
folder.BandwidthSavingsUsingDFSReplicationTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderCompressedSizeOfFilesReceivedTotal,
prometheus.CounterValue,
folder.CompressedSizeOfFilesReceivedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderConflictBytesCleanedupTotal,
c.folderConflictBytesCleanedUpTotal,
prometheus.CounterValue,
folder.ConflictBytesCleanedupTotal,
folder.Name,
folder.ConflictBytesCleanedUpTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderConflictBytesGeneratedTotal,
prometheus.CounterValue,
folder.ConflictBytesGeneratedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderConflictFilesCleanedUpTotal,
prometheus.CounterValue,
folder.ConflictFilesCleanedUpTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderConflictFilesGeneratedTotal,
prometheus.CounterValue,
folder.ConflictFilesGeneratedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderConflictfolderCleanupsCompletedTotal,
c.folderConflictFolderCleanupsCompletedTotal,
prometheus.CounterValue,
folder.ConflictFolderCleanupsCompletedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderConflictSpaceInUse,
prometheus.GaugeValue,
folder.ConflictSpaceInUse,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderDeletedSpaceInUse,
prometheus.GaugeValue,
folder.DeletedSpaceInUse,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderDeletedBytesCleanedUpTotal,
prometheus.CounterValue,
folder.DeletedBytesCleanedUpTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderDeletedBytesGeneratedTotal,
prometheus.CounterValue,
folder.DeletedBytesGeneratedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderDeletedFilesCleanedUpTotal,
prometheus.CounterValue,
folder.DeletedFilesCleanedUpTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderDeletedFilesGeneratedTotal,
prometheus.CounterValue,
folder.DeletedFilesGeneratedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderFileInstallsRetriedTotal,
prometheus.CounterValue,
folder.FileInstallsRetriedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderFileInstallsSucceededTotal,
prometheus.CounterValue,
folder.FileInstallsSucceededTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderFilesReceivedTotal,
prometheus.CounterValue,
folder.FilesReceivedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderRDCBytesReceivedTotal,
prometheus.CounterValue,
folder.RDCBytesReceivedTotal,
folder.Name,
folder.RdcBytesReceivedTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderRDCCompressedSizeOfFilesReceivedTotal,
prometheus.CounterValue,
folder.RDCCompressedSizeOfFilesReceivedTotal,
folder.Name,
folder.RdcCompressedSizeOfFilesReceivedTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderRDCNumberofFilesReceivedTotal,
c.folderRDCNumberOfFilesReceivedTotal,
prometheus.CounterValue,
folder.RDCNumberofFilesReceivedTotal,
folder.Name,
folder.RdcNumberOfFilesReceivedTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderRDCSizeOfFilesReceivedTotal,
prometheus.CounterValue,
folder.RDCSizeOfFilesReceivedTotal,
folder.Name,
folder.RdcSizeOfFilesReceivedTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderSizeOfFilesReceivedTotal,
prometheus.CounterValue,
folder.SizeOfFilesReceivedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderStagingSpaceInUse,
prometheus.GaugeValue,
folder.StagingSpaceInUse,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderStagingBytesCleanedUpTotal,
prometheus.CounterValue,
folder.StagingBytesCleanedUpTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderStagingBytesGeneratedTotal,
prometheus.CounterValue,
folder.StagingBytesGeneratedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderStagingFilesCleanedUpTotal,
prometheus.CounterValue,
folder.StagingFilesCleanedUpTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderStagingFilesGeneratedTotal,
prometheus.CounterValue,
folder.StagingFilesGeneratedTotal,
folder.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.folderUpdatesDroppedTotal,
prometheus.CounterValue,
folder.UpdatesDroppedTotal,
folder.Name,
name,
)
}
return nil
}
// perflibDFSRVolume Perflib: "DFS Replication Service Volumes".
type perflibDFSRVolume struct {
Name string
DatabaseCommitsTotal float64 `perflib:"Database Commits"`
DatabaseLookupsTotal float64 `perflib:"Database Lookups"`
USNJournalRecordsReadTotal float64 `perflib:"USN Journal Records Read"`
USNJournalRecordsAcceptedTotal float64 `perflib:"USN Journal Records Accepted"`
USNJournalUnreadPercentage float64 `perflib:"USN Journal Records Unread Percentage"`
}
func (c *Collector) collectVolume(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
var dst []perflibDFSRVolume
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Service Volumes"], &dst, logger); err != nil {
return err
func (c *Collector) collectPDHVolume(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorVolume.Collect(&c.perfDataObjectVolume)
if err != nil {
return fmt.Errorf("failed to collect DFS Replication Volumes metrics: %w", err)
}
for _, volume := range dst {
for _, volume := range c.perfDataObjectVolume {
name := volume.Name
ch <- prometheus.MustNewConstMetric(
c.volumeDatabaseLookupsTotal,
prometheus.CounterValue,
volume.DatabaseLookupsTotal,
volume.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.volumeDatabaseCommitsTotal,
prometheus.CounterValue,
volume.DatabaseCommitsTotal,
volume.Name,
name,
)
ch <- prometheus.MustNewConstMetric(
c.volumeUSNJournalRecordsAcceptedTotal,
prometheus.CounterValue,
volume.USNJournalRecordsAcceptedTotal,
volume.Name,
volume.UsnJournalRecordsAcceptedTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.volumeUSNJournalRecordsReadTotal,
prometheus.CounterValue,
volume.USNJournalRecordsReadTotal,
volume.Name,
volume.UsnJournalRecordsReadTotal,
name,
)
ch <- prometheus.MustNewConstMetric(
c.volumeUSNJournalUnreadPercentage,
prometheus.GaugeValue,
volume.USNJournalUnreadPercentage,
volume.Name,
volume.UsnJournalUnreadPercentage,
name,
)
}

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package dfsr_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/dfsr"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, dfsr.Name, dfsr.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, dfsr.New, nil)
}

View File

@@ -0,0 +1,75 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package dfsr
// Connection Perflib: "DFS Replication Service Connections".
type perfDataCounterValuesConnection struct {
Name string
BandwidthSavingsUsingDFSReplicationTotal float64 `perfdata:"Bandwidth Savings Using DFS Replication"`
BytesReceivedTotal float64 `perfdata:"Total Bytes Received"`
CompressedSizeOfFilesReceivedTotal float64 `perfdata:"Compressed Size of Files Received"`
FilesReceivedTotal float64 `perfdata:"Total Files Received"`
RdcBytesReceivedTotal float64 `perfdata:"RDC Bytes Received"`
RdcCompressedSizeOfFilesReceivedTotal float64 `perfdata:"RDC Compressed Size of Files Received"`
RdcNumberOfFilesReceivedTotal float64 `perfdata:"RDC Number of Files Received"`
RdcSizeOfFilesReceivedTotal float64 `perfdata:"RDC Size of Files Received"`
SizeOfFilesReceivedTotal float64 `perfdata:"Size of Files Received"`
}
// Folder Perflib: "DFS Replicated Folder".
type perfDataCounterValuesFolder struct {
Name string
BandwidthSavingsUsingDFSReplicationTotal float64 `perfdata:"Bandwidth Savings Using DFS Replication"`
CompressedSizeOfFilesReceivedTotal float64 `perfdata:"Compressed Size of Files Received"`
ConflictBytesCleanedUpTotal float64 `perfdata:"Conflict Bytes Cleaned Up"`
ConflictBytesGeneratedTotal float64 `perfdata:"Conflict Bytes Generated"`
ConflictFilesCleanedUpTotal float64 `perfdata:"Conflict Files Cleaned Up"`
ConflictFilesGeneratedTotal float64 `perfdata:"Conflict Files Generated"`
ConflictFolderCleanupsCompletedTotal float64 `perfdata:"Conflict folder Cleanups Completed"`
ConflictSpaceInUse float64 `perfdata:"Conflict Space In Use"`
DeletedSpaceInUse float64 `perfdata:"Deleted Space In Use"`
DeletedBytesCleanedUpTotal float64 `perfdata:"Deleted Bytes Cleaned Up"`
DeletedBytesGeneratedTotal float64 `perfdata:"Deleted Bytes Generated"`
DeletedFilesCleanedUpTotal float64 `perfdata:"Deleted Files Cleaned Up"`
DeletedFilesGeneratedTotal float64 `perfdata:"Deleted Files Generated"`
FileInstallsRetriedTotal float64 `perfdata:"File Installs Retried"`
FileInstallsSucceededTotal float64 `perfdata:"File Installs Succeeded"`
FilesReceivedTotal float64 `perfdata:"Total Files Received"`
RdcBytesReceivedTotal float64 `perfdata:"RDC Bytes Received"`
RdcCompressedSizeOfFilesReceivedTotal float64 `perfdata:"RDC Compressed Size of Files Received"`
RdcNumberOfFilesReceivedTotal float64 `perfdata:"RDC Number of Files Received"`
RdcSizeOfFilesReceivedTotal float64 `perfdata:"RDC Size of Files Received"`
SizeOfFilesReceivedTotal float64 `perfdata:"Size of Files Received"`
StagingSpaceInUse float64 `perfdata:"Staging Space In Use"`
StagingBytesCleanedUpTotal float64 `perfdata:"Staging Bytes Cleaned Up"`
StagingBytesGeneratedTotal float64 `perfdata:"Staging Bytes Generated"`
StagingFilesCleanedUpTotal float64 `perfdata:"Staging Files Cleaned Up"`
StagingFilesGeneratedTotal float64 `perfdata:"Staging Files Generated"`
UpdatesDroppedTotal float64 `perfdata:"Updates Dropped"`
}
// Volume Perflib: "DFS Replication Service Volumes".
type perfDataCounterValuesVolume struct {
Name string
DatabaseCommitsTotal float64 `perfdata:"Database Commits"`
DatabaseLookupsTotal float64 `perfdata:"Database Lookups"`
UsnJournalRecordsReadTotal float64 `perfdata:"USN Journal Records Read"`
UsnJournalRecordsAcceptedTotal float64 `perfdata:"USN Journal Records Accepted"`
UsnJournalUnreadPercentage float64 `perfdata:"USN Journal Unread Percentage"`
}

View File

@@ -1,27 +1,45 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package dhcp
import (
"fmt"
"log/slog"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/perflib"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "dhcp"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector perflib DHCP metrics.
type Collector struct {
config Config
perfDataCollector *pdh.Collector
perfDataObject []perfDataCounterValues
acksTotal *prometheus.Desc
activeQueueLength *prometheus.Desc
conflictCheckQueueLength *prometheus.Desc
@@ -30,12 +48,12 @@ type Collector struct {
deniedDueToNonMatch *prometheus.Desc
discoversTotal *prometheus.Desc
duplicatesDroppedTotal *prometheus.Desc
failoverBndackReceivedTotal *prometheus.Desc
failoverBndackSentTotal *prometheus.Desc
failoverBndupdDropped *prometheus.Desc
failoverBndupdPendingOutboundQueue *prometheus.Desc
failoverBndupdReceivedTotal *prometheus.Desc
failoverBndupdSentTotal *prometheus.Desc
failoverBndAckReceivedTotal *prometheus.Desc
failoverBndAckSentTotal *prometheus.Desc
failoverBndUpdDropped *prometheus.Desc
failoverBndUpdPendingOutboundQueue *prometheus.Desc
failoverBndUpdReceivedTotal *prometheus.Desc
failoverBndUpdSentTotal *prometheus.Desc
failoverTransitionsCommunicationInterruptedState *prometheus.Desc
failoverTransitionsPartnerDownState *prometheus.Desc
failoverTransitionsRecoverState *prometheus.Desc
@@ -69,15 +87,20 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{"DHCP Server"}, nil
}
func (c *Collector) Close() error {
c.perfDataCollector.Close()
func (c *Collector) Close(_ *slog.Logger) error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
var err error
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "DHCP Server", nil)
if err != nil {
return fmt.Errorf("failed to create DHCP Server collector: %w", err)
}
c.packetsReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "packets_received_total"),
"Total number of packets received by the DHCP server (PacketsReceivedTotal)",
@@ -174,31 +197,31 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
nil,
nil,
)
c.failoverBndupdSentTotal = prometheus.NewDesc(
c.failoverBndUpdSentTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_sent_total"),
"Number of DHCP fail over Binding Update messages sent (FailoverBndupdSentTotal)",
nil,
nil,
)
c.failoverBndupdReceivedTotal = prometheus.NewDesc(
c.failoverBndUpdReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_received_total"),
"Number of DHCP fail over Binding Update messages received (FailoverBndupdReceivedTotal)",
nil,
nil,
)
c.failoverBndackSentTotal = prometheus.NewDesc(
c.failoverBndAckSentTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "failover_bndack_sent_total"),
"Number of DHCP fail over Binding Ack messages sent (FailoverBndackSentTotal)",
nil,
nil,
)
c.failoverBndackReceivedTotal = prometheus.NewDesc(
c.failoverBndAckReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "failover_bndack_received_total"),
"Number of DHCP fail over Binding Ack messages received (FailoverBndackReceivedTotal)",
nil,
nil,
)
c.failoverBndupdPendingOutboundQueue = prometheus.NewDesc(
c.failoverBndUpdPendingOutboundQueue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_pending_in_outbound_queue"),
"Number of pending outbound DHCP fail over Binding Update messages (FailoverBndupdPendingOutboundQueue)",
nil,
@@ -222,7 +245,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
nil,
nil,
)
c.failoverBndupdDropped = prometheus.NewDesc(
c.failoverBndUpdDropped = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_dropped_total"),
"Total number of DHCP fail over Binding Updates dropped (FailoverBndupdDropped)",
nil,
@@ -232,194 +255,160 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
return nil
}
// represents perflib metrics from the DHCP Server class.
// While the name of a number of perflib metrics would indicate a rate is being returned (E.G. Packets Received/sec),
// perflib instead returns a counter, hence the "Total" suffix in some of the variable names.
type dhcpPerf struct {
PacketsReceivedTotal float64 `perflib:"Packets Received/sec"`
DuplicatesDroppedTotal float64 `perflib:"Duplicates Dropped/sec"`
PacketsExpiredTotal float64 `perflib:"Packets Expired/sec"`
ActiveQueueLength float64 `perflib:"Active Queue Length"`
ConflictCheckQueueLength float64 `perflib:"Conflict Check Queue Length"`
DiscoversTotal float64 `perflib:"Discovers/sec"`
OffersTotal float64 `perflib:"Offers/sec"`
RequestsTotal float64 `perflib:"Requests/sec"`
InformsTotal float64 `perflib:"Informs/sec"`
AcksTotal float64 `perflib:"Acks/sec"`
NacksTotal float64 `perflib:"Nacks/sec"`
DeclinesTotal float64 `perflib:"Declines/sec"`
ReleasesTotal float64 `perflib:"Releases/sec"`
DeniedDueToMatch float64 `perflib:"Denied due to match."`
DeniedDueToNonMatch float64 `perflib:"Denied due to match."`
OfferQueueLength float64 `perflib:"Offer Queue Length"`
FailoverBndupdSentTotal float64 `perflib:"Failover: BndUpd sent/sec."`
FailoverBndupdReceivedTotal float64 `perflib:"Failover: BndUpd received/sec."`
FailoverBndackSentTotal float64 `perflib:"Failover: BndAck sent/sec."`
FailoverBndackReceivedTotal float64 `perflib:"Failover: BndAck received/sec."`
FailoverBndupdPendingOutboundQueue float64 `perflib:"Failover: BndUpd pending in outbound queue."`
FailoverTransitionsCommunicationinterruptedState float64 `perflib:"Failover: Transitions to COMMUNICATION-INTERRUPTED state."`
FailoverTransitionsPartnerdownState float64 `perflib:"Failover: Transitions to PARTNER-DOWN state."`
FailoverTransitionsRecoverState float64 `perflib:"Failover: Transitions to RECOVER state."`
FailoverBndupdDropped float64 `perflib:"Failover: BndUpd Dropped."`
}
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
var dhcpPerfs []dhcpPerf
if err := perflib.UnmarshalObject(ctx.PerfObjects["DHCP Server"], &dhcpPerfs, logger); err != nil {
return err
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
err := c.perfDataCollector.Collect(&c.perfDataObject)
if err != nil {
return fmt.Errorf("failed to collect DHCP Server metrics: %w", err)
}
ch <- prometheus.MustNewConstMetric(
c.packetsReceivedTotal,
prometheus.CounterValue,
dhcpPerfs[0].PacketsReceivedTotal,
c.perfDataObject[0].PacketsReceivedTotal,
)
ch <- prometheus.MustNewConstMetric(
c.duplicatesDroppedTotal,
prometheus.CounterValue,
dhcpPerfs[0].DuplicatesDroppedTotal,
c.perfDataObject[0].DuplicatesDroppedTotal,
)
ch <- prometheus.MustNewConstMetric(
c.packetsExpiredTotal,
prometheus.CounterValue,
dhcpPerfs[0].PacketsExpiredTotal,
c.perfDataObject[0].PacketsExpiredTotal,
)
ch <- prometheus.MustNewConstMetric(
c.activeQueueLength,
prometheus.GaugeValue,
dhcpPerfs[0].ActiveQueueLength,
c.perfDataObject[0].ActiveQueueLength,
)
ch <- prometheus.MustNewConstMetric(
c.conflictCheckQueueLength,
prometheus.GaugeValue,
dhcpPerfs[0].ConflictCheckQueueLength,
c.perfDataObject[0].ConflictCheckQueueLength,
)
ch <- prometheus.MustNewConstMetric(
c.discoversTotal,
prometheus.CounterValue,
dhcpPerfs[0].DiscoversTotal,
c.perfDataObject[0].DiscoversTotal,
)
ch <- prometheus.MustNewConstMetric(
c.offersTotal,
prometheus.CounterValue,
dhcpPerfs[0].OffersTotal,
c.perfDataObject[0].OffersTotal,
)
ch <- prometheus.MustNewConstMetric(
c.requestsTotal,
prometheus.CounterValue,
dhcpPerfs[0].RequestsTotal,
c.perfDataObject[0].RequestsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.informsTotal,
prometheus.CounterValue,
dhcpPerfs[0].InformsTotal,
c.perfDataObject[0].InformsTotal,
)
ch <- prometheus.MustNewConstMetric(
c.acksTotal,
prometheus.CounterValue,
dhcpPerfs[0].AcksTotal,
c.perfDataObject[0].AcksTotal,
)
ch <- prometheus.MustNewConstMetric(
c.nACKsTotal,
prometheus.CounterValue,
dhcpPerfs[0].NacksTotal,
c.perfDataObject[0].NacksTotal,
)
ch <- prometheus.MustNewConstMetric(
c.declinesTotal,
prometheus.CounterValue,
dhcpPerfs[0].DeclinesTotal,
c.perfDataObject[0].DeclinesTotal,
)
ch <- prometheus.MustNewConstMetric(
c.releasesTotal,
prometheus.CounterValue,
dhcpPerfs[0].ReleasesTotal,
c.perfDataObject[0].ReleasesTotal,
)
ch <- prometheus.MustNewConstMetric(
c.offerQueueLength,
prometheus.GaugeValue,
dhcpPerfs[0].OfferQueueLength,
c.perfDataObject[0].OfferQueueLength,
)
ch <- prometheus.MustNewConstMetric(
c.deniedDueToMatch,
prometheus.CounterValue,
dhcpPerfs[0].DeniedDueToMatch,
c.perfDataObject[0].DeniedDueToMatch,
)
ch <- prometheus.MustNewConstMetric(
c.deniedDueToNonMatch,
prometheus.CounterValue,
dhcpPerfs[0].DeniedDueToNonMatch,
c.perfDataObject[0].DeniedDueToNonMatch,
)
ch <- prometheus.MustNewConstMetric(
c.failoverBndupdSentTotal,
c.failoverBndUpdSentTotal,
prometheus.CounterValue,
dhcpPerfs[0].FailoverBndupdSentTotal,
c.perfDataObject[0].FailoverBndUpdSentTotal,
)
ch <- prometheus.MustNewConstMetric(
c.failoverBndupdReceivedTotal,
c.failoverBndUpdReceivedTotal,
prometheus.CounterValue,
dhcpPerfs[0].FailoverBndupdReceivedTotal,
c.perfDataObject[0].FailoverBndUpdReceivedTotal,
)
ch <- prometheus.MustNewConstMetric(
c.failoverBndackSentTotal,
c.failoverBndAckSentTotal,
prometheus.CounterValue,
dhcpPerfs[0].FailoverBndackSentTotal,
c.perfDataObject[0].FailoverBndAckSentTotal,
)
ch <- prometheus.MustNewConstMetric(
c.failoverBndackReceivedTotal,
c.failoverBndAckReceivedTotal,
prometheus.CounterValue,
dhcpPerfs[0].FailoverBndackReceivedTotal,
c.perfDataObject[0].FailoverBndAckReceivedTotal,
)
ch <- prometheus.MustNewConstMetric(
c.failoverBndupdPendingOutboundQueue,
c.failoverBndUpdPendingOutboundQueue,
prometheus.GaugeValue,
dhcpPerfs[0].FailoverBndupdPendingOutboundQueue,
c.perfDataObject[0].FailoverBndUpdPendingOutboundQueue,
)
ch <- prometheus.MustNewConstMetric(
c.failoverTransitionsCommunicationInterruptedState,
prometheus.CounterValue,
dhcpPerfs[0].FailoverTransitionsCommunicationinterruptedState,
c.perfDataObject[0].FailoverTransitionsCommunicationInterruptedState,
)
ch <- prometheus.MustNewConstMetric(
c.failoverTransitionsPartnerDownState,
prometheus.CounterValue,
dhcpPerfs[0].FailoverTransitionsPartnerdownState,
c.perfDataObject[0].FailoverTransitionsPartnerDownState,
)
ch <- prometheus.MustNewConstMetric(
c.failoverTransitionsRecoverState,
prometheus.CounterValue,
dhcpPerfs[0].FailoverTransitionsRecoverState,
c.perfDataObject[0].FailoverTransitionsRecoverState,
)
ch <- prometheus.MustNewConstMetric(
c.failoverBndupdDropped,
c.failoverBndUpdDropped,
prometheus.CounterValue,
dhcpPerfs[0].FailoverBndupdDropped,
c.perfDataObject[0].FailoverBndUpdDropped,
)
return nil

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package dhcp_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/dhcp"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, dhcp.Name, dhcp.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, dhcp.New, nil)
}

View File

@@ -0,0 +1,44 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package dhcp
type perfDataCounterValues struct {
AcksTotal float64 `perfdata:"Acks/sec"`
ActiveQueueLength float64 `perfdata:"Active Queue Length"`
ConflictCheckQueueLength float64 `perfdata:"Conflict Check Queue Length"`
DeclinesTotal float64 `perfdata:"Declines/sec"`
DeniedDueToMatch float64 `perfdata:"Denied due to match."`
DeniedDueToNonMatch float64 `perfdata:"Denied due to match."`
DiscoversTotal float64 `perfdata:"Discovers/sec"`
DuplicatesDroppedTotal float64 `perfdata:"Duplicates Dropped/sec"`
FailoverBndAckReceivedTotal float64 `perfdata:"Failover: BndAck received/sec."`
FailoverBndAckSentTotal float64 `perfdata:"Failover: BndAck sent/sec."`
FailoverBndUpdDropped float64 `perfdata:"Failover: BndUpd Dropped."`
FailoverBndUpdPendingOutboundQueue float64 `perfdata:"Failover: BndUpd pending in outbound queue."`
FailoverBndUpdReceivedTotal float64 `perfdata:"Failover: BndUpd received/sec."`
FailoverBndUpdSentTotal float64 `perfdata:"Failover: BndUpd sent/sec."`
FailoverTransitionsCommunicationInterruptedState float64 `perfdata:"Failover: Transitions to COMMUNICATION-INTERRUPTED state."`
FailoverTransitionsPartnerDownState float64 `perfdata:"Failover: Transitions to PARTNER-DOWN state."`
FailoverTransitionsRecoverState float64 `perfdata:"Failover: Transitions to RECOVER state."`
InformsTotal float64 `perfdata:"Informs/sec"`
NacksTotal float64 `perfdata:"Nacks/sec"`
OfferQueueLength float64 `perfdata:"Offer Queue Length"`
OffersTotal float64 `perfdata:"Offers/sec"`
PacketsExpiredTotal float64 `perfdata:"Packets Expired/sec"`
PacketsReceivedTotal float64 `perfdata:"Packets Received/sec"`
ReleasesTotal float64 `perfdata:"Releases/sec"`
RequestsTotal float64 `perfdata:"Requests/sec"`
}

View File

@@ -1,31 +1,44 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package diskdrive
import (
"errors"
"fmt"
"log/slog"
"strings"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const (
Name = "diskdrive"
win32DiskQuery = "SELECT DeviceID, Model, Caption, Name, Partitions, Size, Status, Availability FROM WIN32_DiskDrive"
)
const Name = "diskdrive"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_DiskDrive.
type Collector struct {
config Config
wmiClient *wmi.Client
miSession *mi.Session
miQuery mi.Query
availability *prometheus.Desc
diskInfo *prometheus.Desc
@@ -54,20 +67,23 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{}, nil
}
func (c *Collector) Close(_ *slog.Logger) error {
func (c *Collector) Close() error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
if wmiClient == nil || wmiClient.SWbemServicesClient == nil {
return errors.New("wmiClient or SWbemServicesClient is nil")
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
if miSession == nil {
return errors.New("miSession is nil")
}
c.wmiClient = wmiClient
miQuery, err := mi.NewQuery("SELECT DeviceID, Model, Caption, Name, Partitions, Size, Status, Availability FROM WIN32_DiskDrive")
if err != nil {
return fmt.Errorf("failed to create WMI query: %w", err)
}
c.miQuery = miQuery
c.miSession = miSession
c.diskInfo = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "info"),
"General drive information",
@@ -104,20 +120,26 @@ func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
nil,
)
var dst []diskDrive
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, c.miQuery); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
return nil
}
type win32_DiskDrive struct {
DeviceID string
Model string
Size uint64
Name string
Caption string
Partitions uint32
Status string
Availability uint16
type diskDrive struct {
DeviceID string `mi:"DeviceID"`
Model string `mi:"Model"`
Size uint64 `mi:"Size"`
Name string `mi:"Name"`
Caption string `mi:"Caption"`
Partitions uint32 `mi:"Partitions"`
Status string `mi:"Status"`
Availability uint16 `mi:"Availability"`
}
//nolint:gochecknoglobals
var (
allDiskStatus = []string{
"OK",
@@ -160,24 +182,10 @@ var (
)
// Collect sends the metric values for each metric to the provided prometheus Metric channel.
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
if err := c.collect(ch); err != nil {
logger.Error("failed collecting disk_drive_info metrics",
slog.Any("err", err),
)
return err
}
return nil
}
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
var dst []win32_DiskDrive
if err := c.wmiClient.Query(win32DiskQuery, &dst); err != nil {
return err
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
var dst []diskDrive
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, c.miQuery); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
if len(dst) == 0 {
@@ -185,14 +193,16 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
}
for _, disk := range dst {
distName := strings.Trim(disk.Name, `\.`)
ch <- prometheus.MustNewConstMetric(
c.diskInfo,
prometheus.GaugeValue,
1.0,
strings.Trim(disk.DeviceID, "\\.\\"), //nolint:staticcheck
strings.Trim(disk.DeviceID, `\.`),
strings.TrimRight(disk.Model, " "),
strings.TrimRight(disk.Caption, " "),
strings.TrimRight(disk.Name, "\\.\\"), //nolint:staticcheck
distName,
)
for _, status := range allDiskStatus {
@@ -205,7 +215,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
c.status,
prometheus.GaugeValue,
isCurrentState,
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
distName,
status,
)
}
@@ -214,14 +224,14 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
c.size,
prometheus.GaugeValue,
float64(disk.Size),
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
distName,
)
ch <- prometheus.MustNewConstMetric(
c.partitions,
prometheus.GaugeValue,
float64(disk.Partitions),
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
distName,
)
for availNum, val := range availMap {
@@ -233,7 +243,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
c.availability,
prometheus.GaugeValue,
isCurrentState,
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
distName,
val,
)
}

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package diskdrive_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/diskdrive"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, diskdrive.Name, diskdrive.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, diskdrive.New, nil)
}

View File

@@ -1,27 +1,44 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package dns
import (
"errors"
"fmt"
"log/slog"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "dns"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics.
type Collector struct {
config Config
wmiClient *wmi.Client
config Config
perfDataCollector *pdh.Collector
perfDataObject []perfDataCounterValues
dynamicUpdatesFailures *prometheus.Desc
dynamicUpdatesQueued *prometheus.Desc
@@ -67,20 +84,19 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{}, nil
}
func (c *Collector) Close() error {
c.perfDataCollector.Close()
func (c *Collector) Close(_ *slog.Logger) error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
if wmiClient == nil || wmiClient.SWbemServicesClient == nil {
return errors.New("wmiClient or SWbemServicesClient is nil")
}
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
var err error
c.wmiClient = wmiClient
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "DNS", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create DNS collector: %w", err)
}
c.zoneTransferRequestsReceived = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_received_total"),
@@ -220,138 +236,75 @@ func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
if err := c.collect(ch); err != nil {
logger.Error("failed collecting dns metrics",
slog.Any("err", err),
)
return err
}
return nil
}
// Win32_PerfRawData_DNS_DNS docs:
// - https://msdn.microsoft.com/en-us/library/ms803992.aspx?f=255&MSPPError=-2147217396
// - https://technet.microsoft.com/en-us/library/cc977686.aspx
type Win32_PerfRawData_DNS_DNS struct {
AXFRRequestReceived uint32
AXFRRequestSent uint32
AXFRResponseReceived uint32
AXFRSuccessReceived uint32
AXFRSuccessSent uint32
CachingMemory uint32
DatabaseNodeMemory uint32
DynamicUpdateNoOperation uint32
DynamicUpdateQueued uint32
DynamicUpdateRejected uint32
DynamicUpdateTimeOuts uint32
DynamicUpdateWrittentoDatabase uint32
IXFRRequestReceived uint32
IXFRRequestSent uint32
IXFRResponseReceived uint32
IXFRSuccessSent uint32
IXFRTCPSuccessReceived uint32
IXFRUDPSuccessReceived uint32
NbstatMemory uint32
NotifyReceived uint32
NotifySent uint32
RecordFlowMemory uint32
RecursiveQueries uint32
RecursiveQueryFailure uint32
RecursiveSendTimeOuts uint32
SecureUpdateFailure uint32
SecureUpdateReceived uint32
TCPMessageMemory uint32
TCPQueryReceived uint32
TCPResponseSent uint32
UDPMessageMemory uint32
UDPQueryReceived uint32
UDPResponseSent uint32
UnmatchedResponsesReceived uint32
WINSLookupReceived uint32
WINSResponseSent uint32
WINSReverseLookupReceived uint32
WINSReverseResponseSent uint32
ZoneTransferFailure uint32
ZoneTransferSOARequestSent uint32
}
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_DNS_DNS
if err := c.wmiClient.Query("SELECT * FROM Win32_PerfRawData_DNS_DNS", &dst); err != nil {
return err
}
if len(dst) == 0 {
return errors.New("WMI query returned empty result set")
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
err := c.perfDataCollector.Collect(&c.perfDataObject)
if err != nil {
return fmt.Errorf("failed to collect DNS metrics: %w", err)
}
ch <- prometheus.MustNewConstMetric(
c.zoneTransferRequestsReceived,
prometheus.CounterValue,
float64(dst[0].AXFRRequestReceived),
c.perfDataObject[0].AxfrRequestReceived,
"full",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferRequestsReceived,
prometheus.CounterValue,
float64(dst[0].IXFRRequestReceived),
c.perfDataObject[0].IxfrRequestReceived,
"incremental",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferRequestsSent,
prometheus.CounterValue,
float64(dst[0].AXFRRequestSent),
c.perfDataObject[0].AxfrRequestSent,
"full",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferRequestsSent,
prometheus.CounterValue,
float64(dst[0].IXFRRequestSent),
c.perfDataObject[0].IxfrRequestSent,
"incremental",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferRequestsSent,
prometheus.CounterValue,
float64(dst[0].ZoneTransferSOARequestSent),
c.perfDataObject[0].ZoneTransferSOARequestSent,
"soa",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferResponsesReceived,
prometheus.CounterValue,
float64(dst[0].AXFRResponseReceived),
c.perfDataObject[0].AxfrResponseReceived,
"full",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferResponsesReceived,
prometheus.CounterValue,
float64(dst[0].IXFRResponseReceived),
c.perfDataObject[0].IxfrResponseReceived,
"incremental",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferSuccessReceived,
prometheus.CounterValue,
float64(dst[0].AXFRSuccessReceived),
c.perfDataObject[0].AxfrSuccessReceived,
"full",
"tcp",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferSuccessReceived,
prometheus.CounterValue,
float64(dst[0].IXFRTCPSuccessReceived),
c.perfDataObject[0].IxfrTCPSuccessReceived,
"incremental",
"tcp",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferSuccessReceived,
prometheus.CounterValue,
float64(dst[0].IXFRTCPSuccessReceived),
c.perfDataObject[0].IxfrTCPSuccessReceived,
"incremental",
"udp",
)
@@ -359,183 +312,183 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
ch <- prometheus.MustNewConstMetric(
c.zoneTransferSuccessSent,
prometheus.CounterValue,
float64(dst[0].AXFRSuccessSent),
c.perfDataObject[0].AxfrSuccessSent,
"full",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferSuccessSent,
prometheus.CounterValue,
float64(dst[0].IXFRSuccessSent),
c.perfDataObject[0].IxfrSuccessSent,
"incremental",
)
ch <- prometheus.MustNewConstMetric(
c.zoneTransferFailures,
prometheus.CounterValue,
float64(dst[0].ZoneTransferFailure),
c.perfDataObject[0].ZoneTransferFailure,
)
ch <- prometheus.MustNewConstMetric(
c.memoryUsedBytes,
prometheus.GaugeValue,
float64(dst[0].CachingMemory),
c.perfDataObject[0].CachingMemory,
"caching",
)
ch <- prometheus.MustNewConstMetric(
c.memoryUsedBytes,
prometheus.GaugeValue,
float64(dst[0].DatabaseNodeMemory),
c.perfDataObject[0].DatabaseNodeMemory,
"database_node",
)
ch <- prometheus.MustNewConstMetric(
c.memoryUsedBytes,
prometheus.GaugeValue,
float64(dst[0].NbstatMemory),
c.perfDataObject[0].NbStatMemory,
"nbstat",
)
ch <- prometheus.MustNewConstMetric(
c.memoryUsedBytes,
prometheus.GaugeValue,
float64(dst[0].RecordFlowMemory),
c.perfDataObject[0].RecordFlowMemory,
"record_flow",
)
ch <- prometheus.MustNewConstMetric(
c.memoryUsedBytes,
prometheus.GaugeValue,
float64(dst[0].TCPMessageMemory),
c.perfDataObject[0].TcpMessageMemory,
"tcp_message",
)
ch <- prometheus.MustNewConstMetric(
c.memoryUsedBytes,
prometheus.GaugeValue,
float64(dst[0].UDPMessageMemory),
c.perfDataObject[0].UdpMessageMemory,
"udp_message",
)
ch <- prometheus.MustNewConstMetric(
c.dynamicUpdatesReceived,
prometheus.CounterValue,
float64(dst[0].DynamicUpdateNoOperation),
c.perfDataObject[0].DynamicUpdateNoOperation,
"noop",
)
ch <- prometheus.MustNewConstMetric(
c.dynamicUpdatesReceived,
prometheus.CounterValue,
float64(dst[0].DynamicUpdateWrittentoDatabase),
c.perfDataObject[0].DynamicUpdateWrittenToDatabase,
"written",
)
ch <- prometheus.MustNewConstMetric(
c.dynamicUpdatesQueued,
prometheus.GaugeValue,
float64(dst[0].DynamicUpdateQueued),
c.perfDataObject[0].DynamicUpdateQueued,
)
ch <- prometheus.MustNewConstMetric(
c.dynamicUpdatesFailures,
prometheus.CounterValue,
float64(dst[0].DynamicUpdateRejected),
c.perfDataObject[0].DynamicUpdateRejected,
"rejected",
)
ch <- prometheus.MustNewConstMetric(
c.dynamicUpdatesFailures,
prometheus.CounterValue,
float64(dst[0].DynamicUpdateTimeOuts),
c.perfDataObject[0].DynamicUpdateTimeOuts,
"timeout",
)
ch <- prometheus.MustNewConstMetric(
c.notifyReceived,
prometheus.CounterValue,
float64(dst[0].NotifyReceived),
c.perfDataObject[0].NotifyReceived,
)
ch <- prometheus.MustNewConstMetric(
c.notifySent,
prometheus.CounterValue,
float64(dst[0].NotifySent),
c.perfDataObject[0].NotifySent,
)
ch <- prometheus.MustNewConstMetric(
c.recursiveQueries,
prometheus.CounterValue,
float64(dst[0].RecursiveQueries),
c.perfDataObject[0].RecursiveQueries,
)
ch <- prometheus.MustNewConstMetric(
c.recursiveQueryFailures,
prometheus.CounterValue,
float64(dst[0].RecursiveQueryFailure),
c.perfDataObject[0].RecursiveQueryFailure,
)
ch <- prometheus.MustNewConstMetric(
c.recursiveQuerySendTimeouts,
prometheus.CounterValue,
float64(dst[0].RecursiveSendTimeOuts),
c.perfDataObject[0].RecursiveSendTimeOuts,
)
ch <- prometheus.MustNewConstMetric(
c.queries,
prometheus.CounterValue,
float64(dst[0].TCPQueryReceived),
c.perfDataObject[0].TcpQueryReceived,
"tcp",
)
ch <- prometheus.MustNewConstMetric(
c.queries,
prometheus.CounterValue,
float64(dst[0].UDPQueryReceived),
c.perfDataObject[0].UdpQueryReceived,
"udp",
)
ch <- prometheus.MustNewConstMetric(
c.responses,
prometheus.CounterValue,
float64(dst[0].TCPResponseSent),
c.perfDataObject[0].TcpResponseSent,
"tcp",
)
ch <- prometheus.MustNewConstMetric(
c.responses,
prometheus.CounterValue,
float64(dst[0].UDPResponseSent),
c.perfDataObject[0].UdpResponseSent,
"udp",
)
ch <- prometheus.MustNewConstMetric(
c.unmatchedResponsesReceived,
prometheus.CounterValue,
float64(dst[0].UnmatchedResponsesReceived),
c.perfDataObject[0].UnmatchedResponsesReceived,
)
ch <- prometheus.MustNewConstMetric(
c.winsQueries,
prometheus.CounterValue,
float64(dst[0].WINSLookupReceived),
c.perfDataObject[0].WinsLookupReceived,
"forward",
)
ch <- prometheus.MustNewConstMetric(
c.winsQueries,
prometheus.CounterValue,
float64(dst[0].WINSReverseLookupReceived),
c.perfDataObject[0].WinsReverseLookupReceived,
"reverse",
)
ch <- prometheus.MustNewConstMetric(
c.winsResponses,
prometheus.CounterValue,
float64(dst[0].WINSResponseSent),
c.perfDataObject[0].WinsResponseSent,
"forward",
)
ch <- prometheus.MustNewConstMetric(
c.winsResponses,
prometheus.CounterValue,
float64(dst[0].WINSReverseResponseSent),
c.perfDataObject[0].WinsReverseResponseSent,
"reverse",
)
ch <- prometheus.MustNewConstMetric(
c.secureUpdateFailures,
prometheus.CounterValue,
float64(dst[0].SecureUpdateFailure),
c.perfDataObject[0].SecureUpdateFailure,
)
ch <- prometheus.MustNewConstMetric(
c.secureUpdateReceived,
prometheus.CounterValue,
float64(dst[0].SecureUpdateReceived),
c.perfDataObject[0].SecureUpdateReceived,
)
return nil

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package dns_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/dns"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, dns.Name, dns.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, dns.New, nil)
}

View File

@@ -0,0 +1,107 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package dns
type perfDataCounterValues struct {
_ float64 `perfdata:"% User Time"`
_ float64 `perfdata:"176"`
_ float64 `perfdata:"Async Fast Reads/sec"`
AxfrRequestReceived float64 `perfdata:"AXFR Request Received"`
AxfrRequestSent float64 `perfdata:"AXFR Request Sent"`
AxfrResponseReceived float64 `perfdata:"AXFR Response Received"`
AxfrSuccessReceived float64 `perfdata:"AXFR Success Received"`
AxfrSuccessSent float64 `perfdata:"AXFR Success Sent"`
CachingMemory float64 `perfdata:"Caching Memory"`
_ float64 `perfdata:"Data Flush Pages/sec"`
_ float64 `perfdata:"Data Flushes/sec"`
DatabaseNodeMemory float64 `perfdata:"Database Node Memory"`
DynamicUpdateNoOperation float64 `perfdata:"Dynamic Update NoOperation"`
_ float64 `perfdata:"Dynamic Update NoOperation/sec"`
DynamicUpdateQueued float64 `perfdata:"Dynamic Update Queued"`
_ float64 `perfdata:"Dynamic Update Received"`
_ float64 `perfdata:"Dynamic Update Received/sec"`
DynamicUpdateRejected float64 `perfdata:"Dynamic Update Rejected"`
DynamicUpdateTimeOuts float64 `perfdata:"Dynamic Update TimeOuts"`
DynamicUpdateWrittenToDatabase float64 `perfdata:"Dynamic Update Written to Database"`
_ float64 `perfdata:"Dynamic Update Written to Database/sec"`
_ float64 `perfdata:"Enumerations Server/sec"`
_ float64 `perfdata:"Fast Read Not Possibles/sec"`
_ float64 `perfdata:"Fast Read Resource Misses/sec"`
IxfrRequestReceived float64 `perfdata:"IXFR Request Received"`
IxfrRequestSent float64 `perfdata:"IXFR Request Sent"`
IxfrResponseReceived float64 `perfdata:"IXFR Response Received"`
_ float64 `perfdata:"IXFR Success Received"`
IxfrSuccessSent float64 `perfdata:"IXFR Success Sent"`
IxfrTCPSuccessReceived float64 `perfdata:"IXFR TCP Success Received"`
IxfrUDPSuccessReceived float64 `perfdata:"IXFR UDP Success Received"`
_ float64 `perfdata:"Lazy Write Flushes/sec"`
_ float64 `perfdata:"Lazy Write Pages/sec"`
_ float64 `perfdata:"Level 2 TLB Fills/sec"`
NbStatMemory float64 `perfdata:"Nbstat Memory"`
NotifyReceived float64 `perfdata:"Notify Received"`
NotifySent float64 `perfdata:"Notify Sent"`
_ float64 `perfdata:"Query Dropped Bad Socket"`
_ float64 `perfdata:"Query Dropped Bad Socket/sec"`
_ float64 `perfdata:"Query Dropped By Policy"`
_ float64 `perfdata:"Query Dropped By Policy/sec"`
_ float64 `perfdata:"Query Dropped By Response Rate Limiting"`
_ float64 `perfdata:"Query Dropped By Response Rate Limiting/sec"`
_ float64 `perfdata:"Query Dropped Send"`
_ float64 `perfdata:"Query Dropped Send/sec"`
_ float64 `perfdata:"Query Dropped Total"`
_ float64 `perfdata:"Query Dropped Total/sec"`
RecordFlowMemory float64 `perfdata:"Record Flow Memory"`
RecursiveQueries float64 `perfdata:"Recursive Queries"`
_ float64 `perfdata:"Recursive Queries/sec"`
RecursiveQueryFailure float64 `perfdata:"Recursive Query Failure"`
_ float64 `perfdata:"Recursive Query Failure/sec"`
_ float64 `perfdata:"Recursive Send TimeOuts"`
RecursiveSendTimeOuts float64 `perfdata:"Recursive TimeOut/sec"`
_ float64 `perfdata:"Responses Suppressed"`
_ float64 `perfdata:"Responses Suppressed/sec"`
SecureUpdateFailure float64 `perfdata:"Secure Update Failure"`
SecureUpdateReceived float64 `perfdata:"Secure Update Received"`
_ float64 `perfdata:"Secure Update Received/sec"`
TcpMessageMemory float64 `perfdata:"TCP Message Memory"`
TcpQueryReceived float64 `perfdata:"TCP Query Received"`
_ float64 `perfdata:"TCP Query Received/sec"`
TcpResponseSent float64 `perfdata:"TCP Response Sent"`
_ float64 `perfdata:"TCP Response Sent/sec"`
_ float64 `perfdata:"Total Query Received"`
_ float64 `perfdata:"Total Query Received/sec"`
_ float64 `perfdata:"Total Remote Inflight Queries"`
_ float64 `perfdata:"Total Response Sent"`
_ float64 `perfdata:"Total Response Sent/sec"`
UdpMessageMemory float64 `perfdata:"UDP Message Memory"`
UdpQueryReceived float64 `perfdata:"UDP Query Received"`
_ float64 `perfdata:"UDP Query Received/sec"`
UdpResponseSent float64 `perfdata:"UDP Response Sent"`
_ float64 `perfdata:"UDP Response Sent/sec"`
UnmatchedResponsesReceived float64 `perfdata:"Unmatched Responses Received"`
_ float64 `perfdata:"Virtual Bytes"`
WinsLookupReceived float64 `perfdata:"WINS Lookup Received"`
_ float64 `perfdata:"WINS Lookup Received/sec"`
WinsResponseSent float64 `perfdata:"WINS Response Sent"`
_ float64 `perfdata:"WINS Response Sent/sec"`
WinsReverseLookupReceived float64 `perfdata:"WINS Reverse Lookup Received"`
_ float64 `perfdata:"WINS Reverse Lookup Received/sec"`
WinsReverseResponseSent float64 `perfdata:"WINS Reverse Response Sent"`
_ float64 `perfdata:"WINS Reverse Response Sent/sec"`
ZoneTransferFailure float64 `perfdata:"Zone Transfer Failure"`
ZoneTransferSOARequestSent float64 `perfdata:"Zone Transfer Request Received"`
_ float64 `perfdata:"Zone Transfer SOA Request Sent"`
_ float64 `perfdata:"Zone Transfer Success"`
}

View File

@@ -0,0 +1,285 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"errors"
"fmt"
"log/slog"
"os"
"strings"
"sync"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus/client_golang/prometheus"
)
const Name = "exchange"
const (
subCollectorADAccessProcesses = "ADAccessProcesses"
subCollectorTransportQueues = "TransportQueues"
subCollectorHttpProxy = "HttpProxy"
subCollectorActiveSync = "ActiveSync"
subCollectorAvailabilityService = "AvailabilityService"
subCollectorOutlookWebAccess = "OutlookWebAccess"
subCollectorAutoDiscover = "Autodiscover"
subCollectorWorkloadManagement = "WorkloadManagement"
subCollectorRpcClientAccess = "RpcClientAccess"
subCollectorMapiHttpEmsmdb = "MapiHttpEmsmdb"
)
type Config struct {
CollectorsEnabled []string `yaml:"collectors_enabled"`
}
//nolint:gochecknoglobals
var ConfigDefaults = Config{
CollectorsEnabled: []string{
subCollectorADAccessProcesses,
subCollectorTransportQueues,
subCollectorHttpProxy,
subCollectorActiveSync,
subCollectorAvailabilityService,
subCollectorOutlookWebAccess,
subCollectorAutoDiscover,
subCollectorWorkloadManagement,
subCollectorRpcClientAccess,
subCollectorMapiHttpEmsmdb,
},
}
type Collector struct {
config Config
collectorFns []func(ch chan<- prometheus.Metric) error
closeFns []func()
collectorADAccessProcesses
collectorActiveSync
collectorAutoDiscover
collectorAvailabilityService
collectorHTTPProxy
collectorMapiHttpEmsmdb
collectorOWA
collectorRpcClientAccess
collectorTransportQueues
collectorWorkloadManagementWorkloads
}
func New(config *Config) *Collector {
if config == nil {
config = &ConfigDefaults
}
if config.CollectorsEnabled == nil {
config.CollectorsEnabled = ConfigDefaults.CollectorsEnabled
}
c := &Collector{
config: *config,
}
return c
}
func NewWithFlags(app *kingpin.Application) *Collector {
c := &Collector{
config: ConfigDefaults,
}
c.config.CollectorsEnabled = make([]string, 0)
var listAllCollectors bool
var collectorsEnabled string
app.Flag(
"collector.exchange.list",
"List the collectors along with their perflib object name/ids",
).BoolVar(&listAllCollectors)
app.Flag(
"collector.exchange.enabled",
"Comma-separated list of collectors to use. Defaults to all, if not specified.",
).Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
app.PreAction(func(*kingpin.ParseContext) error {
if listAllCollectors {
collectorDesc := map[string]string{
subCollectorADAccessProcesses: "[19108] MSExchange ADAccess Processes",
subCollectorTransportQueues: "[20524] MSExchangeTransport Queues",
subCollectorHttpProxy: "[36934] MSExchange HttpProxy",
subCollectorActiveSync: "[25138] MSExchange ActiveSync",
subCollectorAvailabilityService: "[24914] MSExchange Availability Service",
subCollectorOutlookWebAccess: "[24618] MSExchange OWA",
subCollectorAutoDiscover: "[29240] MSExchange Autodiscover",
subCollectorWorkloadManagement: "[19430] MSExchange WorkloadManagement Workloads",
subCollectorRpcClientAccess: "[29336] MSExchange RpcClientAccess",
subCollectorMapiHttpEmsmdb: "[26463] MSExchange MapiHttp Emsmdb",
}
sb := strings.Builder{}
sb.WriteString(fmt.Sprintf("%-32s %-32s\n", "Collector Name", "[PerfID] Perflib Object"))
for _, cname := range ConfigDefaults.CollectorsEnabled {
sb.WriteString(fmt.Sprintf("%-32s %-32s\n", cname, collectorDesc[cname]))
}
app.UsageTemplate(sb.String()).Usage(nil)
os.Exit(0)
}
return nil
})
app.Action(func(*kingpin.ParseContext) error {
c.config.CollectorsEnabled = strings.Split(collectorsEnabled, ",")
return nil
})
return c
}
func (c *Collector) GetName() string {
return Name
}
func (c *Collector) Close() error {
for _, fn := range c.closeFns {
fn()
}
return nil
}
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
subCollectors := map[string]struct {
build func() error
collect func(ch chan<- prometheus.Metric) error
close func()
}{
subCollectorADAccessProcesses: {
build: c.buildADAccessProcesses,
collect: c.collectADAccessProcesses,
close: c.perfDataCollectorADAccessProcesses.Close,
},
subCollectorTransportQueues: {
build: c.buildTransportQueues,
collect: c.collectTransportQueues,
close: c.perfDataCollectorTransportQueues.Close,
},
subCollectorHttpProxy: {
build: c.buildHTTPProxy,
collect: c.collectHTTPProxy,
close: c.perfDataCollectorHTTPProxy.Close,
},
subCollectorActiveSync: {
build: c.buildActiveSync,
collect: c.collectActiveSync,
close: c.perfDataCollectorActiveSync.Close,
},
subCollectorAvailabilityService: {
build: c.buildAvailabilityService,
collect: c.collectAvailabilityService,
close: c.perfDataCollectorAvailabilityService.Close,
},
subCollectorOutlookWebAccess: {
build: c.buildOWA,
collect: c.collectOWA,
close: c.perfDataCollectorOWA.Close,
},
subCollectorAutoDiscover: {
build: c.buildAutoDiscover,
collect: c.collectAutoDiscover,
close: c.perfDataCollectorAutoDiscover.Close,
},
subCollectorWorkloadManagement: {
build: c.buildWorkloadManagementWorkloads,
collect: c.collectWorkloadManagementWorkloads,
close: c.perfDataCollectorWorkloadManagementWorkloads.Close,
},
subCollectorRpcClientAccess: {
build: c.buildRpcClientAccess,
collect: c.collectRpcClientAccess,
close: c.perfDataCollectorRpcClientAccess.Close,
},
subCollectorMapiHttpEmsmdb: {
build: c.buildMapiHttpEmsmdb,
collect: c.collectMapiHttpEmsmdb,
close: c.perfDataCollectorMapiHttpEmsmdb.Close,
},
}
errs := make([]error, 0, len(c.config.CollectorsEnabled))
for _, name := range c.config.CollectorsEnabled {
if _, ok := subCollectors[name]; !ok {
return fmt.Errorf("unknown collector: %s", name)
}
if err := subCollectors[name].build(); err != nil {
errs = append(errs, fmt.Errorf("failed to build %s collector: %w", name, err))
continue
}
c.collectorFns = append(c.collectorFns, subCollectors[name].collect)
c.closeFns = append(c.closeFns, subCollectors[name].close)
}
return errors.Join(errs...)
}
// Collect collects exchange metrics and sends them to prometheus.
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
errCh := make(chan error, len(c.collectorFns))
errs := make([]error, 0, len(c.collectorFns))
wg := sync.WaitGroup{}
for _, fn := range c.collectorFns {
wg.Add(1)
go func(fn func(ch chan<- prometheus.Metric) error) {
defer wg.Done()
if err := fn(ch); err != nil {
errCh <- err
}
}(fn)
}
wg.Wait()
close(errCh)
for err := range errCh {
errs = append(errs, err)
}
return errors.Join(errs...)
}
// toLabelName converts strings to lowercase and replaces all whitespaces and dots with underscores.
func (c *Collector) toLabelName(name string) string {
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
s = strings.ReplaceAll(s, "__", "_")
return s
}

View File

@@ -0,0 +1,96 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
type collectorActiveSync struct {
perfDataCollectorActiveSync *pdh.Collector
perfDataObjectActiveSync []perfDataCounterValuesActiveSync
activeSyncRequestsPerSec *prometheus.Desc
pingCommandsPending *prometheus.Desc
syncCommandsPerSec *prometheus.Desc
}
type perfDataCounterValuesActiveSync struct {
RequestsPerSec float64 `perfdata:"Requests/sec"`
PingCommandsPending float64 `perfdata:"Ping Commands Pending"`
SyncCommandsPerSec float64 `perfdata:"Sync Commands/sec"`
}
func (c *Collector) buildActiveSync() error {
var err error
c.perfDataCollectorActiveSync, err = pdh.NewCollector[perfDataCounterValuesActiveSync](pdh.CounterTypeRaw, "MSExchange ActiveSync", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchange ActiveSync collector: %w", err)
}
c.pingCommandsPending = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "activesync_ping_cmds_pending"),
"Number of ping commands currently pending in the queue",
nil,
nil,
)
c.syncCommandsPerSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "activesync_sync_cmds_total"),
"Number of sync commands processed per second. Clients use this command to synchronize items within a folder",
nil,
nil,
)
c.activeSyncRequestsPerSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "activesync_requests_total"),
"Num HTTP requests received from the client via ASP.NET per sec. Shows Current user load",
nil,
nil,
)
return nil
}
func (c *Collector) collectActiveSync(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorActiveSync.Collect(&c.perfDataObjectActiveSync)
if err != nil {
return fmt.Errorf("failed to collect MSExchange ActiveSync metrics: %w", err)
}
for _, data := range c.perfDataObjectActiveSync {
ch <- prometheus.MustNewConstMetric(
c.activeSyncRequestsPerSec,
prometheus.CounterValue,
data.RequestsPerSec,
)
ch <- prometheus.MustNewConstMetric(
c.pingCommandsPending,
prometheus.GaugeValue,
data.PingCommandsPending,
)
ch <- prometheus.MustNewConstMetric(
c.syncCommandsPerSec,
prometheus.CounterValue,
data.SyncCommandsPerSec,
)
}
return nil
}

View File

@@ -0,0 +1,141 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
)
type collectorADAccessProcesses struct {
perfDataCollectorADAccessProcesses *pdh.Collector
perfDataObjectADAccessProcesses []perfDataCounterValuesADAccessProcesses
ldapReadTime *prometheus.Desc
ldapSearchTime *prometheus.Desc
ldapTimeoutErrorsPerSec *prometheus.Desc
ldapWriteTime *prometheus.Desc
longRunningLDAPOperationsPerMin *prometheus.Desc
}
type perfDataCounterValuesADAccessProcesses struct {
Name string
LdapReadTime float64 `perfdata:"LDAP Read Time"`
LdapSearchTime float64 `perfdata:"LDAP Search Time"`
LdapWriteTime float64 `perfdata:"LDAP Write Time"`
LdapTimeoutErrorsPerSec float64 `perfdata:"LDAP Timeout Errors/sec"`
LongRunningLDAPOperationsPerMin float64 `perfdata:"Long Running LDAP Operations/min"`
}
func (c *Collector) buildADAccessProcesses() error {
var err error
c.perfDataCollectorADAccessProcesses, err = pdh.NewCollector[perfDataCounterValuesADAccessProcesses](pdh.CounterTypeRaw, "MSExchange ADAccess Processes", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchange ADAccess Processes collector: %w", err)
}
c.ldapReadTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_read_time_sec"),
"Time (sec) to send an LDAP read request and receive a response",
[]string{"name"},
nil,
)
c.ldapSearchTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_search_time_sec"),
"Time (sec) to send an LDAP search request and receive a response",
[]string{"name"},
nil,
)
c.ldapWriteTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_write_time_sec"),
"Time (sec) to send an LDAP Add/Modify/Delete request and receive a response",
[]string{"name"},
nil,
)
c.ldapTimeoutErrorsPerSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_timeout_errors_total"),
"Total number of LDAP timeout errors",
[]string{"name"},
nil,
)
c.longRunningLDAPOperationsPerMin = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_long_running_ops_per_sec"),
"Long Running LDAP operations per second",
[]string{"name"},
nil,
)
return nil
}
func (c *Collector) collectADAccessProcesses(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorADAccessProcesses.Collect(&c.perfDataObjectADAccessProcesses)
if err != nil {
return fmt.Errorf("failed to collect MSExchange ADAccess Processes metrics: %w", err)
}
labelUseCount := make(map[string]int)
for _, data := range c.perfDataObjectADAccessProcesses {
labelName := c.toLabelName(data.Name)
// Since we're not including the PID suffix from the instance names in the label names, we get an occasional duplicate.
// This seems to affect about 4 instances only of this object.
labelUseCount[labelName]++
if labelUseCount[labelName] > 1 {
labelName = fmt.Sprintf("%s_%d", labelName, labelUseCount[labelName])
}
ch <- prometheus.MustNewConstMetric(
c.ldapReadTime,
prometheus.CounterValue,
utils.MilliSecToSec(data.LdapReadTime),
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.ldapSearchTime,
prometheus.CounterValue,
utils.MilliSecToSec(data.LdapSearchTime),
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.ldapWriteTime,
prometheus.CounterValue,
utils.MilliSecToSec(data.LdapWriteTime),
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.ldapTimeoutErrorsPerSec,
prometheus.CounterValue,
data.LdapTimeoutErrorsPerSec,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.longRunningLDAPOperationsPerMin,
prometheus.CounterValue,
data.LongRunningLDAPOperationsPerMin*60,
labelName,
)
}
return nil
}

View File

@@ -0,0 +1,70 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
type collectorAutoDiscover struct {
perfDataCollectorAutoDiscover *pdh.Collector
perfDataObjectAutoDiscover []perfDataCounterValuesAutoDiscover
autoDiscoverRequestsPerSec *prometheus.Desc
}
type perfDataCounterValuesAutoDiscover struct {
RequestsPerSec float64 `perfdata:"Requests/sec"`
}
func (c *Collector) buildAutoDiscover() error {
var err error
c.perfDataCollectorAutoDiscover, err = pdh.NewCollector[perfDataCounterValuesAutoDiscover](pdh.CounterTypeRaw, "MSExchange Autodiscover", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchange Autodiscover collector: %w", err)
}
c.autoDiscoverRequestsPerSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "autodiscover_requests_total"),
"Number of autodiscover service requests processed each second",
nil,
nil,
)
return nil
}
func (c *Collector) collectAutoDiscover(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorAutoDiscover.Collect(&c.perfDataObjectAutoDiscover)
if err != nil {
return fmt.Errorf("failed to collect MSExchange Autodiscover metrics: %w", err)
}
for _, data := range c.perfDataObjectAutoDiscover {
ch <- prometheus.MustNewConstMetric(
c.autoDiscoverRequestsPerSec,
prometheus.CounterValue,
data.RequestsPerSec,
)
}
return nil
}

View File

@@ -0,0 +1,70 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
type collectorAvailabilityService struct {
perfDataCollectorAvailabilityService *pdh.Collector
perfDataObjectAvailabilityService []perfDataCounterValuesAvailabilityService
availabilityRequestsSec *prometheus.Desc
}
type perfDataCounterValuesAvailabilityService struct {
RequestsPerSec float64 `perfdata:"Requests/sec"`
}
func (c *Collector) buildAvailabilityService() error {
var err error
c.perfDataCollectorAvailabilityService, err = pdh.NewCollector[perfDataCounterValuesAvailabilityService](pdh.CounterTypeRaw, "MSExchange Availability Service", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchange Availability Service collector: %w", err)
}
c.availabilityRequestsSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "avail_service_requests_per_sec"),
"Number of requests serviced per second",
nil,
nil,
)
return nil
}
func (c *Collector) collectAvailabilityService(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorAvailabilityService.Collect(&c.perfDataObjectAvailabilityService)
if err != nil {
return fmt.Errorf("failed to collect MSExchange Availability Service metrics: %w", err)
}
for _, data := range c.perfDataObjectAvailabilityService {
ch <- prometheus.MustNewConstMetric(
c.availabilityRequestsSec,
prometheus.CounterValue,
data.RequestsPerSec,
)
}
return nil
}

View File

@@ -0,0 +1,145 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
)
type collectorHTTPProxy struct {
perfDataCollectorHTTPProxy *pdh.Collector
perfDataObjectHTTPProxy []perfDataCounterValuesHTTPProxy
mailboxServerLocatorAverageLatency *prometheus.Desc
averageAuthenticationLatency *prometheus.Desc
outstandingProxyRequests *prometheus.Desc
proxyRequestsPerSec *prometheus.Desc
averageCASProcessingLatency *prometheus.Desc
mailboxServerProxyFailureRate *prometheus.Desc
}
type perfDataCounterValuesHTTPProxy struct {
Name string
MailboxServerLocatorAverageLatency float64 `perfdata:"MailboxServerLocator Average Latency (Moving Average)"`
AverageAuthenticationLatency float64 `perfdata:"Average Authentication Latency"`
AverageCASProcessingLatency float64 `perfdata:"Average ClientAccess Server Processing Latency"`
MailboxServerProxyFailureRate float64 `perfdata:"Mailbox Server Proxy Failure Rate"`
OutstandingProxyRequests float64 `perfdata:"Outstanding Proxy Requests"`
ProxyRequestsPerSec float64 `perfdata:"Proxy Requests/Sec"`
}
func (c *Collector) buildHTTPProxy() error {
var err error
c.perfDataCollectorHTTPProxy, err = pdh.NewCollector[perfDataCounterValuesHTTPProxy](pdh.CounterTypeRaw, "MSExchange HttpProxy", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchange HttpProxy collector: %w", err)
}
c.mailboxServerLocatorAverageLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_mailbox_server_locator_avg_latency_sec"),
"Average latency (sec) of MailboxServerLocator web service calls",
[]string{"name"},
nil,
)
c.averageAuthenticationLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_avg_auth_latency"),
"Average time spent authenticating CAS requests over the last 200 samples",
[]string{"name"},
nil,
)
c.outstandingProxyRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_outstanding_proxy_requests"),
"Number of concurrent outstanding proxy requests",
[]string{"name"},
nil,
)
c.proxyRequestsPerSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_requests_total"),
"Number of proxy requests processed each second",
[]string{"name"},
nil,
)
c.averageCASProcessingLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_avg_cas_processing_latency_sec"),
"Average latency (sec) of CAS processing time over the last 200 reqs",
[]string{"name"},
nil,
)
c.mailboxServerProxyFailureRate = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_mailbox_proxy_failure_rate"),
"% of failures between this CAS and MBX servers over the last 200 samples",
[]string{"name"},
nil,
)
return nil
}
func (c *Collector) collectHTTPProxy(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorHTTPProxy.Collect(&c.perfDataObjectHTTPProxy)
if err != nil {
return fmt.Errorf("failed to collect MSExchange HttpProxy Service metrics: %w", err)
}
for _, data := range c.perfDataObjectHTTPProxy {
labelName := c.toLabelName(data.Name)
ch <- prometheus.MustNewConstMetric(
c.mailboxServerLocatorAverageLatency,
prometheus.GaugeValue,
utils.MilliSecToSec(data.MailboxServerLocatorAverageLatency),
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.averageAuthenticationLatency,
prometheus.GaugeValue,
data.AverageAuthenticationLatency,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.averageCASProcessingLatency,
prometheus.GaugeValue,
utils.MilliSecToSec(data.AverageCASProcessingLatency),
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.mailboxServerProxyFailureRate,
prometheus.GaugeValue,
data.MailboxServerProxyFailureRate,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.outstandingProxyRequests,
prometheus.GaugeValue,
data.OutstandingProxyRequests,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.proxyRequestsPerSec,
prometheus.CounterValue,
data.ProxyRequestsPerSec,
labelName,
)
}
return nil
}

View File

@@ -0,0 +1,70 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
type collectorMapiHttpEmsmdb struct {
perfDataCollectorMapiHttpEmsmdb *pdh.Collector
perfDataObjectMapiHttpEmsmdb []perfDataCounterValuesMapiHttpEmsmdb
activeUserCountMapiHttpEmsMDB *prometheus.Desc
}
type perfDataCounterValuesMapiHttpEmsmdb struct {
ActiveUserCount float64 `perfdata:"Active User Count"`
}
func (c *Collector) buildMapiHttpEmsmdb() error {
var err error
c.perfDataCollectorMapiHttpEmsmdb, err = pdh.NewCollector[perfDataCounterValuesMapiHttpEmsmdb](pdh.CounterTypeRaw, "MSExchange MapiHttp Emsmdb", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchange MapiHttp Emsmdb: %w", err)
}
c.activeUserCountMapiHttpEmsMDB = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "mapihttp_emsmdb_active_user_count"),
"Number of unique outlook users that have shown some kind of activity in the last 2 minutes",
nil,
nil,
)
return nil
}
func (c *Collector) collectMapiHttpEmsmdb(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorMapiHttpEmsmdb.Collect(&c.perfDataObjectMapiHttpEmsmdb)
if err != nil {
return fmt.Errorf("failed to collect MSExchange MapiHttp Emsmdb metrics: %w", err)
}
for _, data := range c.perfDataObjectMapiHttpEmsmdb {
ch <- prometheus.MustNewConstMetric(
c.activeUserCountMapiHttpEmsMDB,
prometheus.GaugeValue,
data.ActiveUserCount,
)
}
return nil
}

View File

@@ -0,0 +1,83 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
type collectorOWA struct {
perfDataCollectorOWA *pdh.Collector
perfDataObjectOWA []perfDataCounterValuesOWA
currentUniqueUsers *prometheus.Desc
owaRequestsPerSec *prometheus.Desc
}
type perfDataCounterValuesOWA struct {
CurrentUniqueUsers float64 `perfdata:"Current Unique Users"`
RequestsPerSec float64 `perfdata:"Requests/sec"`
}
func (c *Collector) buildOWA() error {
var err error
c.perfDataCollectorOWA, err = pdh.NewCollector[perfDataCounterValuesOWA](pdh.CounterTypeRaw, "MSExchange OWA", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchange OWA collector: %w", err)
}
c.currentUniqueUsers = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "owa_current_unique_users"),
"Number of unique users currently logged on to Outlook Web App",
nil,
nil,
)
c.owaRequestsPerSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "owa_requests_total"),
"Number of requests handled by Outlook Web App per second",
nil,
nil,
)
return nil
}
func (c *Collector) collectOWA(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorOWA.Collect(&c.perfDataObjectOWA)
if err != nil {
return fmt.Errorf("failed to collect MSExchange OWA metrics: %w", err)
}
for _, data := range c.perfDataObjectOWA {
ch <- prometheus.MustNewConstMetric(
c.currentUniqueUsers,
prometheus.GaugeValue,
data.CurrentUniqueUsers,
)
ch <- prometheus.MustNewConstMetric(
c.owaRequestsPerSec,
prometheus.CounterValue,
data.RequestsPerSec,
)
}
return nil
}

View File

@@ -0,0 +1,136 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
)
type collectorRpcClientAccess struct {
perfDataCollectorRpcClientAccess *pdh.Collector
perfDataObjectRpcClientAccess []perfDataCounterValuesRpcClientAccess
activeUserCount *prometheus.Desc
connectionCount *prometheus.Desc
rpcAveragedLatency *prometheus.Desc
rpcOperationsPerSec *prometheus.Desc
rpcRequests *prometheus.Desc
userCount *prometheus.Desc
}
type perfDataCounterValuesRpcClientAccess struct {
RpcAveragedLatency float64 `perfdata:"RPC Averaged Latency"`
RpcRequests float64 `perfdata:"RPC Requests"`
ActiveUserCount float64 `perfdata:"Active User Count"`
ConnectionCount float64 `perfdata:"Connection Count"`
RpcOperationsPerSec float64 `perfdata:"RPC Operations/sec"`
UserCount float64 `perfdata:"User Count"`
}
func (c *Collector) buildRpcClientAccess() error {
var err error
c.perfDataCollectorRpcClientAccess, err = pdh.NewCollector[perfDataCounterValuesRpcClientAccess](pdh.CounterTypeRaw, "MSExchange RpcClientAccess", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchange RpcClientAccess collector: %w", err)
}
c.rpcAveragedLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "rpc_avg_latency_sec"),
"The latency (sec) averaged for the past 1024 packets",
nil,
nil,
)
c.rpcRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "rpc_requests"),
"Number of client requests currently being processed by the RPC Client Access service",
nil,
nil,
)
c.activeUserCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "rpc_active_user_count"),
"Number of unique users that have shown some kind of activity in the last 2 minutes",
nil,
nil,
)
c.connectionCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "rpc_connection_count"),
"Total number of client connections maintained",
nil,
nil,
)
c.rpcOperationsPerSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "rpc_operations_total"),
"The rate at which RPC operations occur",
nil,
nil,
)
c.userCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "rpc_user_count"),
"Number of users",
nil,
nil,
)
return nil
}
func (c *Collector) collectRpcClientAccess(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorRpcClientAccess.Collect(&c.perfDataObjectRpcClientAccess)
if err != nil {
return fmt.Errorf("failed to collect MSExchange RpcClientAccess: %w", err)
}
for _, data := range c.perfDataObjectRpcClientAccess {
ch <- prometheus.MustNewConstMetric(
c.rpcAveragedLatency,
prometheus.GaugeValue,
utils.MilliSecToSec(data.RpcAveragedLatency),
)
ch <- prometheus.MustNewConstMetric(
c.rpcRequests,
prometheus.GaugeValue,
data.RpcRequests,
)
ch <- prometheus.MustNewConstMetric(
c.activeUserCount,
prometheus.GaugeValue,
data.ActiveUserCount,
)
ch <- prometheus.MustNewConstMetric(
c.connectionCount,
prometheus.GaugeValue,
data.ConnectionCount,
)
ch <- prometheus.MustNewConstMetric(
c.rpcOperationsPerSec,
prometheus.CounterValue,
data.RpcOperationsPerSec,
)
ch <- prometheus.MustNewConstMetric(
c.userCount,
prometheus.GaugeValue,
data.UserCount,
)
}
return nil
}

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/exchange"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, exchange.Name, exchange.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, exchange.New, nil)
}

View File

@@ -0,0 +1,327 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
type collectorTransportQueues struct {
perfDataCollectorTransportQueues *pdh.Collector
perfDataObjectTransportQueues []perfDataCounterValuesTransportQueues
activeMailboxDeliveryQueueLength *prometheus.Desc
externalActiveRemoteDeliveryQueueLength *prometheus.Desc
externalLargestDeliveryQueueLength *prometheus.Desc
internalActiveRemoteDeliveryQueueLength *prometheus.Desc
internalLargestDeliveryQueueLength *prometheus.Desc
poisonQueueLength *prometheus.Desc
retryMailboxDeliveryQueueLength *prometheus.Desc
unreachableQueueLength *prometheus.Desc
messagesQueuedForDeliveryTotal *prometheus.Desc
messagesSubmittedTotal *prometheus.Desc
messagesDelayedTotal *prometheus.Desc
messagesCompletedDeliveryTotal *prometheus.Desc
shadowQueueLength *prometheus.Desc
submissionQueueLength *prometheus.Desc
delayQueueLength *prometheus.Desc
itemsCompletedDeliveryTotal *prometheus.Desc
itemsQueuedForDeliveryExpiredTotal *prometheus.Desc
itemsQueuedForDeliveryTotal *prometheus.Desc
itemsResubmittedTotal *prometheus.Desc
}
type perfDataCounterValuesTransportQueues struct {
Name string
ExternalActiveRemoteDeliveryQueueLength float64 `perfdata:"External Active Remote Delivery Queue Length"`
InternalActiveRemoteDeliveryQueueLength float64 `perfdata:"Internal Active Remote Delivery Queue Length"`
ActiveMailboxDeliveryQueueLength float64 `perfdata:"Active Mailbox Delivery Queue Length"`
RetryMailboxDeliveryQueueLength float64 `perfdata:"Retry Mailbox Delivery Queue Length"`
UnreachableQueueLength float64 `perfdata:"Unreachable Queue Length"`
ExternalLargestDeliveryQueueLength float64 `perfdata:"External Largest Delivery Queue Length"`
InternalLargestDeliveryQueueLength float64 `perfdata:"Internal Largest Delivery Queue Length"`
PoisonQueueLength float64 `perfdata:"Poison Queue Length"`
MessagesQueuedForDeliveryTotal float64 `perfdata:"Messages Queued For Delivery Total"`
MessagesSubmittedTotal float64 `perfdata:"Messages Submitted Total"`
MessagesDelayedTotal float64 `perfdata:"Messages Delayed Total"`
MessagesCompletedDeliveryTotal float64 `perfdata:"Messages Completed Delivery Total"`
ShadowQueueLength float64 `perfdata:"Shadow Queue Length"`
SubmissionQueueLength float64 `perfdata:"Submission Queue Length"`
DelayQueueLength float64 `perfdata:"Delay Queue Length"`
ItemsCompletedDeliveryTotal float64 `perfdata:"Items Completed Delivery Total"`
ItemsQueuedForDeliveryExpiredTotal float64 `perfdata:"Items Queued For Delivery Expired Total"`
ItemsQueuedForDeliveryTotal float64 `perfdata:"Items Queued For Delivery Total"`
ItemsResubmittedTotal float64 `perfdata:"Items Resubmitted Total"`
}
func (c *Collector) buildTransportQueues() error {
var err error
c.perfDataCollectorTransportQueues, err = pdh.NewCollector[perfDataCounterValuesTransportQueues](pdh.CounterTypeRaw, "MSExchangeTransport Queues", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchangeTransport Queues collector: %w", err)
}
c.externalActiveRemoteDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_external_active_remote_delivery"),
"External Active Remote Delivery Queue length",
[]string{"name"},
nil,
)
c.internalActiveRemoteDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_internal_active_remote_delivery"),
"Internal Active Remote Delivery Queue length",
[]string{"name"},
nil,
)
c.activeMailboxDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_active_mailbox_delivery"),
"Active Mailbox Delivery Queue length",
[]string{"name"},
nil,
)
c.retryMailboxDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_retry_mailbox_delivery"),
"Retry Mailbox Delivery Queue length",
[]string{"name"},
nil,
)
c.unreachableQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_unreachable"),
"Unreachable Queue length",
[]string{"name"},
nil,
)
c.externalLargestDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_external_largest_delivery"),
"External Largest Delivery Queue length",
[]string{"name"},
nil,
)
c.internalLargestDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_internal_largest_delivery"),
"Internal Largest Delivery Queue length",
[]string{"name"},
nil,
)
c.poisonQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_poison"),
"Poison Queue length",
[]string{"name"},
nil,
)
c.messagesQueuedForDeliveryTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_messages_queued_for_delivery_total"),
"Messages Queued For Delivery Total",
[]string{"name"},
nil,
)
c.messagesSubmittedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_messages_submitted_total"),
"Messages Submitted Total",
[]string{"name"},
nil,
)
c.messagesDelayedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_messages_delayed_total"),
"Messages Delayed Total",
[]string{"name"},
nil,
)
c.messagesCompletedDeliveryTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_messages_completed_delivery_total"),
"Messages Completed Delivery Total",
[]string{"name"},
nil,
)
c.shadowQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_shadow_queue_length"),
"Shadow Queue Length",
[]string{"name"},
nil,
)
c.submissionQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_submission_queue_length"),
"Submission Queue Length",
[]string{"name"},
nil,
)
c.delayQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_delay_queue_length"),
"Delay Queue Length",
[]string{"name"},
nil,
)
c.itemsCompletedDeliveryTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_items_completed_delivery_total"),
"Items Completed Delivery Total",
[]string{"name"},
nil,
)
c.itemsQueuedForDeliveryExpiredTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_items_queued_for_delivery_expired_total"),
"Items Queued For Delivery Expired Total",
[]string{"name"},
nil,
)
c.itemsQueuedForDeliveryTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_items_queued_for_delivery_total"),
"Items Queued For Delivery Total",
[]string{"name"},
nil,
)
c.itemsResubmittedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_items_resubmitted_total"),
"Items Resubmitted Total",
[]string{"name"},
nil,
)
return nil
}
func (c *Collector) collectTransportQueues(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorTransportQueues.Collect(&c.perfDataObjectTransportQueues)
if err != nil {
return fmt.Errorf("failed to collect MSExchangeTransport Queues: %w", err)
}
for _, data := range c.perfDataObjectTransportQueues {
labelName := c.toLabelName(data.Name)
ch <- prometheus.MustNewConstMetric(
c.externalActiveRemoteDeliveryQueueLength,
prometheus.GaugeValue,
data.ExternalActiveRemoteDeliveryQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.internalActiveRemoteDeliveryQueueLength,
prometheus.GaugeValue,
data.InternalActiveRemoteDeliveryQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.activeMailboxDeliveryQueueLength,
prometheus.GaugeValue,
data.ActiveMailboxDeliveryQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.retryMailboxDeliveryQueueLength,
prometheus.GaugeValue,
data.RetryMailboxDeliveryQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.unreachableQueueLength,
prometheus.GaugeValue,
data.UnreachableQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.externalLargestDeliveryQueueLength,
prometheus.GaugeValue,
data.ExternalLargestDeliveryQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.internalLargestDeliveryQueueLength,
prometheus.GaugeValue,
data.InternalLargestDeliveryQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.poisonQueueLength,
prometheus.GaugeValue,
data.PoisonQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.messagesQueuedForDeliveryTotal,
prometheus.CounterValue,
data.MessagesQueuedForDeliveryTotal,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.messagesSubmittedTotal,
prometheus.CounterValue,
data.MessagesSubmittedTotal,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.messagesDelayedTotal,
prometheus.CounterValue,
data.MessagesDelayedTotal,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.messagesCompletedDeliveryTotal,
prometheus.CounterValue,
data.MessagesCompletedDeliveryTotal,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.shadowQueueLength,
prometheus.GaugeValue,
data.ShadowQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.submissionQueueLength,
prometheus.GaugeValue,
data.SubmissionQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.delayQueueLength,
prometheus.GaugeValue,
data.DelayQueueLength,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.itemsCompletedDeliveryTotal,
prometheus.CounterValue,
data.ItemsCompletedDeliveryTotal,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.itemsQueuedForDeliveryExpiredTotal,
prometheus.CounterValue,
data.ItemsQueuedForDeliveryExpiredTotal,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.itemsQueuedForDeliveryTotal,
prometheus.CounterValue,
data.ItemsQueuedForDeliveryTotal,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.itemsResubmittedTotal,
prometheus.CounterValue,
data.ItemsResubmittedTotal,
labelName,
)
}
return nil
}

View File

@@ -0,0 +1,131 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package exchange
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
type collectorWorkloadManagementWorkloads struct {
perfDataCollectorWorkloadManagementWorkloads *pdh.Collector
perfDataObjectWorkloadManagementWorkloads []perfDataCounterValuesWorkloadManagementWorkloads
activeTasks *prometheus.Desc
isActive *prometheus.Desc
completedTasks *prometheus.Desc
queuedTasks *prometheus.Desc
yieldedTasks *prometheus.Desc
}
type perfDataCounterValuesWorkloadManagementWorkloads struct {
Name string
ActiveTasks float64 `perfdata:"ActiveTasks"`
CompletedTasks float64 `perfdata:"CompletedTasks"`
QueuedTasks float64 `perfdata:"QueuedTasks"`
YieldedTasks float64 `perfdata:"YieldedTasks"`
IsActive float64 `perfdata:"Active"`
}
func (c *Collector) buildWorkloadManagementWorkloads() error {
var err error
c.perfDataCollectorWorkloadManagementWorkloads, err = pdh.NewCollector[perfDataCounterValuesWorkloadManagementWorkloads](pdh.CounterTypeRaw, "MSExchange WorkloadManagement Workloads", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create MSExchange WorkloadManagement Workloads collector: %w", err)
}
c.activeTasks = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_active_tasks"),
"Number of active tasks currently running in the background for workload management",
[]string{"name"},
nil,
)
c.completedTasks = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_completed_tasks"),
"Number of workload management tasks that have been completed",
[]string{"name"},
nil,
)
c.queuedTasks = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_queued_tasks"),
"Number of workload management tasks that are currently queued up waiting to be processed",
[]string{"name"},
nil,
)
c.yieldedTasks = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_yielded_tasks"),
"The total number of tasks that have been yielded by a workload",
[]string{"name"},
nil,
)
c.isActive = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_is_active"),
"Active indicates whether the workload is in an active (1) or paused (0) state",
[]string{"name"},
nil,
)
return nil
}
func (c *Collector) collectWorkloadManagementWorkloads(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorWorkloadManagementWorkloads.Collect(&c.perfDataObjectWorkloadManagementWorkloads)
if err != nil {
return fmt.Errorf("failed to collect MSExchange WorkloadManagement Workloads: %w", err)
}
for _, data := range c.perfDataObjectWorkloadManagementWorkloads {
labelName := c.toLabelName(data.Name)
ch <- prometheus.MustNewConstMetric(
c.activeTasks,
prometheus.GaugeValue,
data.ActiveTasks,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.completedTasks,
prometheus.CounterValue,
data.CompletedTasks,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.queuedTasks,
prometheus.CounterValue,
data.QueuedTasks,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.yieldedTasks,
prometheus.CounterValue,
data.YieldedTasks,
labelName,
)
ch <- prometheus.MustNewConstMetric(
c.isActive,
prometheus.GaugeValue,
data.IsActive,
labelName,
)
}
return nil
}

View File

@@ -1,3 +1,16 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package filetime
@@ -12,25 +25,27 @@ import (
"github.com/alecthomas/kingpin/v2"
"github.com/bmatcuk/doublestar/v4"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "filetime"
type Config struct {
filePatterns []string
FilePatterns []string
}
//nolint:gochecknoglobals
var ConfigDefaults = Config{
filePatterns: []string{},
FilePatterns: []string{},
}
// A Collector is a Prometheus Collector for collecting file times.
type Collector struct {
config Config
logger *slog.Logger
fileMTime *prometheus.Desc
}
@@ -39,8 +54,8 @@ func New(config *Config) *Collector {
config = &ConfigDefaults
}
if config.filePatterns == nil {
config.filePatterns = ConfigDefaults.filePatterns
if config.FilePatterns == nil {
config.FilePatterns = ConfigDefaults.FilePatterns
}
c := &Collector{
@@ -54,18 +69,18 @@ func NewWithFlags(app *kingpin.Application) *Collector {
c := &Collector{
config: ConfigDefaults,
}
c.config.filePatterns = make([]string, 0)
c.config.FilePatterns = make([]string, 0)
var filePatterns string
app.Flag(
"collectors.filetime.file-patterns",
"collector.filetime.file-patterns",
"Comma-separated list of file patterns. Each pattern is a glob pattern that can contain `*`, `?`, and `**` (recursive). See https://github.com/bmatcuk/doublestar#patterns",
).Default(strings.Join(ConfigDefaults.filePatterns, ",")).StringVar(&filePatterns)
).Default(strings.Join(ConfigDefaults.FilePatterns, ",")).StringVar(&filePatterns)
app.Action(func(*kingpin.ParseContext) error {
// doublestar.Glob() requires forward slashes
c.config.filePatterns = strings.Split(filepath.ToSlash(filePatterns), ",")
c.config.FilePatterns = strings.Split(filepath.ToSlash(filePatterns), ",")
return nil
})
@@ -77,18 +92,14 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{}, nil
}
func (c *Collector) Close(_ *slog.Logger) error {
func (c *Collector) Close() error {
return nil
}
func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
logger.Info("filetime collector is in an experimental state! It may subject to change.",
slog.String("collector", Name),
)
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
c.logger = logger.With(slog.String("collector", Name))
c.logger.Info("filetime collector is in an experimental state! It may subject to change.")
c.fileMTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "mtime_timestamp_seconds"),
@@ -97,7 +108,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
nil,
)
for _, filePattern := range c.config.filePatterns {
for _, filePattern := range c.config.FilePatterns {
basePath, pattern := doublestar.SplitPattern(filePattern)
_, err := doublestar.Glob(os.DirFS(basePath), pattern, doublestar.WithFilesOnly())
@@ -111,24 +122,17 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
return c.collectGlob(logger, ch)
}
// collectWin32 collects file times for each file path in the config. It using Win32 FindFirstFile and FindNextFile.
func (c *Collector) collectGlob(logger *slog.Logger, ch chan<- prometheus.Metric) error {
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
wg := sync.WaitGroup{}
for _, filePattern := range c.config.filePatterns {
for _, filePattern := range c.config.FilePatterns {
wg.Add(1)
go func(filePattern string) {
defer wg.Done()
if err := c.collectGlobFilePath(logger, ch, filePattern); err != nil {
logger.Error("failed collecting metrics for filepath",
if err := c.collectGlobFilePath(ch, filePattern); err != nil {
c.logger.Error("failed collecting metrics for filepath",
slog.String("filepath", filePattern),
slog.Any("err", err),
)
@@ -141,7 +145,7 @@ func (c *Collector) collectGlob(logger *slog.Logger, ch chan<- prometheus.Metric
return nil
}
func (c *Collector) collectGlobFilePath(logger *slog.Logger, ch chan<- prometheus.Metric, filePattern string) error {
func (c *Collector) collectGlobFilePath(ch chan<- prometheus.Metric, filePattern string) error {
basePath, pattern := doublestar.SplitPattern(filePattern)
basePathFS := os.DirFS(basePath)
@@ -155,7 +159,7 @@ func (c *Collector) collectGlobFilePath(logger *slog.Logger, ch chan<- prometheu
fileInfo, err := os.Stat(filePath)
if err != nil {
logger.Warn("failed to state file",
c.logger.Warn("failed to state file",
slog.String("file", filePath),
slog.Any("err", err),
)

View File

@@ -0,0 +1,33 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package filetime_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/filetime"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, filetime.Name, filetime.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, filetime.New, &filetime.Config{
FilePatterns: []string{"*.*"},
})
}

View File

@@ -1,27 +1,43 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package fsrmquota
import (
"errors"
"fmt"
"log/slog"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/pkg/utils"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi"
)
const Name = "fsrmquota"
type Config struct{}
//nolint:gochecknoglobals
var ConfigDefaults = Config{}
type Collector struct {
config Config
wmiClient *wmi.Client
miSession *mi.Session
miQuery mi.Query
quotasCount *prometheus.Desc
peakUsage *prometheus.Desc
@@ -55,20 +71,22 @@ func (c *Collector) GetName() string {
return Name
}
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
return []string{}, nil
}
func (c *Collector) Close(_ *slog.Logger) error {
func (c *Collector) Close() error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
if wmiClient == nil || wmiClient.SWbemServicesClient == nil {
return errors.New("wmiClient or SWbemServicesClient is nil")
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
if miSession == nil {
return errors.New("miSession is nil")
}
c.wmiClient = wmiClient
miQuery, err := mi.NewQuery("SELECT * FROM MSFT_FSRMQuota")
if err != nil {
return fmt.Errorf("failed to create WMI query: %w", err)
}
c.miQuery = miQuery
c.miSession = miSession
c.quotasCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "count"),
@@ -125,19 +143,9 @@ func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
nil,
)
return nil
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
logger = logger.With(slog.String("collector", Name))
if err := c.collect(ch); err != nil {
logger.Error("failed collecting fsrmquota metrics",
slog.Any("err", err),
)
return err
var dst []msftFSRMQuota
if err := c.miSession.Query(&dst, mi.NamespaceRootWindowsFSRM, c.miQuery); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
return nil
@@ -145,30 +153,28 @@ func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan
// MSFT_FSRMQuota docs:
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/fsrm/msft-fsrmquota
type MSFT_FSRMQuota struct {
Name string
Path string
PeakUsage uint64
Size uint64
Usage uint64
Description string
Template string
// Threshold string
Disabled bool
MatchesTemplate bool
SoftLimit bool
type msftFSRMQuota struct {
Path string `mi:"Path"`
PeakUsage uint64 `mi:"PeakUsage"`
Size uint64 `mi:"Size"`
Usage uint64 `mi:"Usage"`
Description string `mi:"Description"`
Template string `mi:"Template"`
Disabled bool `mi:"Disabled"`
MatchesTemplate bool `mi:"MatchesTemplate"`
SoftLimit bool `mi:"SoftLimit"`
}
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
var dst []MSFT_FSRMQuota
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
var dst []msftFSRMQuota
if err := c.miSession.Query(&dst, mi.NamespaceRootWindowsFSRM, c.miQuery); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
var count int
if err := c.wmiClient.Query("SELECT * FROM MSFT_FSRMQuota", &dst, nil, "root/microsoft/windows/fsrm"); err != nil {
return err
}
for _, quota := range dst {
count++
path := quota.Path

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package fsrmquota_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/fsrmquota"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, fsrmquota.Name, fsrmquota.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, fsrmquota.New, nil)
}

View File

@@ -0,0 +1,304 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"errors"
"fmt"
"log/slog"
"sort"
"strings"
"sync"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/windows"
)
const (
Name = "hyperv"
subCollectorDataStore = "datastore"
subCollectorDynamicMemoryBalancer = "dynamic_memory_balancer"
subCollectorDynamicMemoryVM = "dynamic_memory_vm"
subCollectorHypervisorLogicalProcessor = "hypervisor_logical_processor"
subCollectorHypervisorRootPartition = "hypervisor_root_partition"
subCollectorHypervisorRootVirtualProcessor = "hypervisor_root_virtual_processor"
subCollectorHypervisorVirtualProcessor = "hypervisor_virtual_processor"
subCollectorLegacyNetworkAdapter = "legacy_network_adapter"
subCollectorVirtualMachineHealthSummary = "virtual_machine_health_summary"
subCollectorVirtualMachineVidPartition = "virtual_machine_vid_partition"
subCollectorVirtualNetworkAdapter = "virtual_network_adapter"
subCollectorVirtualNetworkAdapterDropReasons = "virtual_network_adapter_drop_reasons"
subCollectorVirtualSMB = "virtual_smb"
subCollectorVirtualStorageDevice = "virtual_storage_device"
subCollectorVirtualSwitch = "virtual_switch"
)
type Config struct {
CollectorsEnabled []string `yaml:"collectors_enabled"`
}
//nolint:gochecknoglobals
var ConfigDefaults = Config{
CollectorsEnabled: []string{
subCollectorDataStore,
subCollectorDynamicMemoryBalancer,
subCollectorDynamicMemoryVM,
subCollectorHypervisorLogicalProcessor,
subCollectorHypervisorRootPartition,
subCollectorHypervisorRootVirtualProcessor,
subCollectorHypervisorVirtualProcessor,
subCollectorLegacyNetworkAdapter,
subCollectorVirtualMachineHealthSummary,
subCollectorVirtualMachineVidPartition,
subCollectorVirtualNetworkAdapter,
subCollectorVirtualNetworkAdapterDropReasons,
subCollectorVirtualSMB,
subCollectorVirtualStorageDevice,
subCollectorVirtualSwitch,
},
}
// Collector is a Prometheus Collector for hyper-v.
type Collector struct {
config Config
collectorFns []func(ch chan<- prometheus.Metric) error
closeFns []func()
collectorDataStore
collectorDynamicMemoryBalancer
collectorDynamicMemoryVM
collectorHypervisorLogicalProcessor
collectorHypervisorRootPartition
collectorHypervisorRootVirtualProcessor
collectorHypervisorVirtualProcessor
collectorLegacyNetworkAdapter
collectorVirtualMachineHealthSummary
collectorVirtualMachineVidPartition
collectorVirtualNetworkAdapter
collectorVirtualNetworkAdapterDropReasons
collectorVirtualSMB
collectorVirtualStorageDevice
collectorVirtualSwitch
}
func New(config *Config) *Collector {
if config == nil {
config = &ConfigDefaults
}
if config.CollectorsEnabled == nil {
config.CollectorsEnabled = ConfigDefaults.CollectorsEnabled
}
c := &Collector{
config: *config,
}
return c
}
func NewWithFlags(app *kingpin.Application) *Collector {
c := &Collector{
config: ConfigDefaults,
}
c.config.CollectorsEnabled = make([]string, 0)
var collectorsEnabled string
app.Flag(
"collector.hyperv.enabled",
"Comma-separated list of collectors to use.",
).Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
app.Action(func(*kingpin.ParseContext) error {
c.config.CollectorsEnabled = strings.Split(collectorsEnabled, ",")
return nil
})
return c
}
func (c *Collector) GetName() string {
return Name
}
func (c *Collector) Close() error {
for _, fn := range c.closeFns {
fn()
}
return nil
}
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
c.collectorFns = make([]func(ch chan<- prometheus.Metric) error, 0, len(c.config.CollectorsEnabled))
c.closeFns = make([]func(), 0, len(c.config.CollectorsEnabled))
if len(c.config.CollectorsEnabled) == 0 {
return nil
}
version := windows.RtlGetVersion()
subCollectors := map[string]struct {
build func() error
collect func(ch chan<- prometheus.Metric) error
close func()
minBuildNumber uint32
}{
subCollectorDataStore: {
build: c.buildDataStore,
collect: c.collectDataStore,
close: c.perfDataCollectorDataStore.Close,
minBuildNumber: types.BuildNumberWindowsServer2022,
},
subCollectorDynamicMemoryBalancer: {
build: c.buildDynamicMemoryBalancer,
collect: c.collectDynamicMemoryBalancer,
close: c.perfDataCollectorDynamicMemoryBalancer.Close,
},
subCollectorDynamicMemoryVM: {
build: c.buildDynamicMemoryVM,
collect: c.collectDynamicMemoryVM,
close: c.perfDataCollectorDynamicMemoryVM.Close,
},
subCollectorHypervisorLogicalProcessor: {
build: c.buildHypervisorLogicalProcessor,
collect: c.collectHypervisorLogicalProcessor,
close: c.perfDataCollectorHypervisorLogicalProcessor.Close,
},
subCollectorHypervisorRootPartition: {
build: c.buildHypervisorRootPartition,
collect: c.collectHypervisorRootPartition,
close: c.perfDataCollectorHypervisorRootPartition.Close,
},
subCollectorHypervisorRootVirtualProcessor: {
build: c.buildHypervisorRootVirtualProcessor,
collect: c.collectHypervisorRootVirtualProcessor,
close: c.perfDataCollectorHypervisorRootVirtualProcessor.Close,
},
subCollectorHypervisorVirtualProcessor: {
build: c.buildHypervisorVirtualProcessor,
collect: c.collectHypervisorVirtualProcessor,
close: c.perfDataCollectorHypervisorVirtualProcessor.Close,
},
subCollectorLegacyNetworkAdapter: {
build: c.buildLegacyNetworkAdapter,
collect: c.collectLegacyNetworkAdapter,
close: c.perfDataCollectorLegacyNetworkAdapter.Close,
},
subCollectorVirtualMachineHealthSummary: {
build: c.buildVirtualMachineHealthSummary,
collect: c.collectVirtualMachineHealthSummary,
close: c.perfDataCollectorVirtualMachineHealthSummary.Close,
},
subCollectorVirtualMachineVidPartition: {
build: c.buildVirtualMachineVidPartition,
collect: c.collectVirtualMachineVidPartition,
close: c.perfDataCollectorVirtualMachineVidPartition.Close,
},
subCollectorVirtualNetworkAdapter: {
build: c.buildVirtualNetworkAdapter,
collect: c.collectVirtualNetworkAdapter,
close: c.perfDataCollectorVirtualNetworkAdapter.Close,
},
subCollectorVirtualNetworkAdapterDropReasons: {
build: c.buildVirtualNetworkAdapterDropReasons,
collect: c.collectVirtualNetworkAdapterDropReasons,
close: c.perfDataCollectorVirtualNetworkAdapterDropReasons.Close,
},
subCollectorVirtualSMB: {
build: c.buildVirtualSMB,
collect: c.collectVirtualSMB,
close: c.perfDataCollectorVirtualSMB.Close,
},
subCollectorVirtualStorageDevice: {
build: c.buildVirtualStorageDevice,
collect: c.collectVirtualStorageDevice,
close: c.perfDataCollectorVirtualStorageDevice.Close,
},
subCollectorVirtualSwitch: {
build: c.buildVirtualSwitch,
collect: c.collectVirtualSwitch,
close: c.perfDataCollectorVirtualSwitch.Close,
},
}
// Result must order, to prevent test failures.
sort.Strings(c.config.CollectorsEnabled)
errs := make([]error, 0, len(c.config.CollectorsEnabled))
for _, name := range c.config.CollectorsEnabled {
if _, ok := subCollectors[name]; !ok {
return fmt.Errorf("unknown collector: %s", name)
}
if version.BuildNumber < subCollectors[name].minBuildNumber {
errs = append(errs, fmt.Errorf("collector %s requires Windows Server 2022 or newer", name))
continue
}
if err := subCollectors[name].build(); err != nil {
errs = append(errs, fmt.Errorf("failed to build %s collector: %w", name, err))
continue
}
c.collectorFns = append(c.collectorFns, subCollectors[name].collect)
c.closeFns = append(c.closeFns, subCollectors[name].close)
}
return errors.Join(errs...)
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
errCh := make(chan error, len(c.collectorFns))
errs := make([]error, 0, len(c.collectorFns))
wg := sync.WaitGroup{}
for _, fn := range c.collectorFns {
wg.Add(1)
go func(fn func(ch chan<- prometheus.Metric) error) {
defer wg.Done()
if err := fn(ch); err != nil {
errCh <- err
}
}(fn)
}
wg.Wait()
close(errCh)
for err := range errCh {
errs = append(errs, err)
}
return errors.Join(errs...)
}

View File

@@ -0,0 +1,749 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
// collectorDataStore Hyper-V DataStore metrics
type collectorDataStore struct {
perfDataCollectorDataStore *pdh.Collector
perfDataObjectDataStore []perfDataCounterValuesDataStore
dataStoreFragmentationRatio *prometheus.Desc // \Hyper-V DataStore(*)\Fragmentation ratio
dataStoreSectorSize *prometheus.Desc // \Hyper-V DataStore(*)\Sector size
dataStoreDataAlignment *prometheus.Desc // \Hyper-V DataStore(*)\Data alignment
dataStoreCurrentReplayLogSize *prometheus.Desc // \Hyper-V DataStore(*)\Current replay logSize
dataStoreAvailableEntries *prometheus.Desc // \Hyper-V DataStore(*)\Number of available entries inside object tables
dataStoreEmptyEntries *prometheus.Desc // \Hyper-V DataStore(*)\Number of empty entries inside object tables
dataStoreFreeBytes *prometheus.Desc // \Hyper-V DataStore(*)\Number of free bytes inside key tables
dataStoreDataEnd *prometheus.Desc // \Hyper-V DataStore(*)\Data end
dataStoreFileObjects *prometheus.Desc // \Hyper-V DataStore(*)\Number of file objects
dataStoreObjectTables *prometheus.Desc // \Hyper-V DataStore(*)\Number of object tables
dataStoreKeyTables *prometheus.Desc // \Hyper-V DataStore(*)\Number of key tables
dataStoreFileDataSize *prometheus.Desc // \Hyper-V DataStore(*)\File data size in bytes
dataStoreTableDataSize *prometheus.Desc // \Hyper-V DataStore(*)\Table data size in bytes
dataStoreNamesSize *prometheus.Desc // \Hyper-V DataStore(*)\Names size in bytes
dataStoreNumberOfKeys *prometheus.Desc // \Hyper-V DataStore(*)\Number of keys
dataStoreReconnectLatencyMicro *prometheus.Desc // \Hyper-V DataStore(*)\Reconnect latency microseconds
dataStoreDisconnectCount *prometheus.Desc // \Hyper-V DataStore(*)\Disconnect count
dataStoreWriteToFileByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Write to file byte latency microseconds
dataStoreWriteToFileByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Write to file byte count
dataStoreWriteToFileCount *prometheus.Desc // \Hyper-V DataStore(*)\Write to file count
dataStoreReadFromFileByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Read from file byte latency microseconds
dataStoreReadFromFileByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Read from file byte count
dataStoreReadFromFileCount *prometheus.Desc // \Hyper-V DataStore(*)\Read from file count
dataStoreWriteToStorageByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Write to storage byte latency microseconds
dataStoreWriteToStorageByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Write to storage byte count
dataStoreWriteToStorageCount *prometheus.Desc // \Hyper-V DataStore(*)\Write to storage count
dataStoreReadFromStorageByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Read from storage byte latency microseconds
dataStoreReadFromStorageByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Read from storage byte count
dataStoreReadFromStorageCount *prometheus.Desc // \Hyper-V DataStore(*)\Read from storage count
dataStoreCommitByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Commit byte latency microseconds
dataStoreCommitByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Commit byte count
dataStoreCommitCount *prometheus.Desc // \Hyper-V DataStore(*)\Commit count
dataStoreCacheUpdateOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Cache update operation latency microseconds
dataStoreCacheUpdateOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Cache update operation count
dataStoreCommitOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Commit operation latency microseconds
dataStoreCommitOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Commit operation count
dataStoreCompactOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Compact operation latency microseconds
dataStoreCompactOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Compact operation count
dataStoreLoadFileOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Load file operation latency microseconds
dataStoreLoadFileOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Load file operation count
dataStoreRemoveOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Remove operation latency microseconds
dataStoreRemoveOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Remove operation count
dataStoreQuerySizeOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Query size operation latency microseconds
dataStoreQuerySizeOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Query size operation count
dataStoreSetOperationLatencyMicro *prometheus.Desc // \Hyper-V DataStore(*)\Set operation latency microseconds
dataStoreSetOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Set operation count
}
type perfDataCounterValuesDataStore struct {
Name string
// Hyper-V DataStore metrics
DataStoreFragmentationRatio float64 `perfdata:"Fragmentation ratio"`
DataStoreSectorSize float64 `perfdata:"Sector size"`
DataStoreDataAlignment float64 `perfdata:"Data alignment"`
DataStoreCurrentReplayLogSize float64 `perfdata:"Current replay logSize"`
DataStoreAvailableEntries float64 `perfdata:"Number of available entries inside object tables"`
DataStoreEmptyEntries float64 `perfdata:"Number of empty entries inside object tables"`
DataStoreFreeBytes float64 `perfdata:"Number of free bytes inside key tables"`
DataStoreDataEnd float64 `perfdata:"Data end"`
DataStoreFileObjects float64 `perfdata:"Number of file objects"`
DataStoreObjectTables float64 `perfdata:"Number of object tables"`
DataStoreKeyTables float64 `perfdata:"Number of key tables"`
DataStoreFileDataSize float64 `perfdata:"File data size in bytes"`
DataStoreTableDataSize float64 `perfdata:"Table data size in bytes"`
DataStoreNamesSize float64 `perfdata:"Names size in bytes"`
DataStoreNumberOfKeys float64 `perfdata:"Number of keys"`
DataStoreReconnectLatencyMicro float64 `perfdata:"Reconnect latency microseconds"`
DataStoreDisconnectCount float64 `perfdata:"Disconnect count"`
DataStoreWriteToFileByteLatency float64 `perfdata:"Write to file byte latency microseconds"`
DataStoreWriteToFileByteCount float64 `perfdata:"Write to file byte count"`
DataStoreWriteToFileCount float64 `perfdata:"Write to file count"`
DataStoreReadFromFileByteLatency float64 `perfdata:"Read from file byte latency microseconds"`
DataStoreReadFromFileByteCount float64 `perfdata:"Read from file byte count"`
DataStoreReadFromFileCount float64 `perfdata:"Read from file count"`
DataStoreWriteToStorageByteLatency float64 `perfdata:"Write to storage byte latency microseconds"`
DataStoreWriteToStorageByteCount float64 `perfdata:"Write to storage byte count"`
DataStoreWriteToStorageCount float64 `perfdata:"Write to storage count"`
DataStoreReadFromStorageByteLatency float64 `perfdata:"Read from storage byte latency microseconds"`
DataStoreReadFromStorageByteCount float64 `perfdata:"Read from storage byte count"`
DataStoreReadFromStorageCount float64 `perfdata:"Read from storage count"`
DataStoreCommitByteLatency float64 `perfdata:"Commit byte latency microseconds"`
DataStoreCommitByteCount float64 `perfdata:"Commit byte count"`
DataStoreCommitCount float64 `perfdata:"Commit count"`
DataStoreCacheUpdateOperationLatency float64 `perfdata:"Cache update operation latency microseconds"`
DataStoreCacheUpdateOperationCount float64 `perfdata:"Cache update operation count"`
DataStoreCommitOperationLatency float64 `perfdata:"Commit operation latency microseconds"`
DataStoreCommitOperationCount float64 `perfdata:"Commit operation count"`
DataStoreCompactOperationLatency float64 `perfdata:"Compact operation latency microseconds"`
DataStoreCompactOperationCount float64 `perfdata:"Compact operation count"`
DataStoreLoadFileOperationLatency float64 `perfdata:"Load file operation latency microseconds"`
DataStoreLoadFileOperationCount float64 `perfdata:"Load file operation count"`
DataStoreRemoveOperationLatency float64 `perfdata:"Remove operation latency microseconds"`
DataStoreRemoveOperationCount float64 `perfdata:"Remove operation count"`
DataStoreQuerySizeOperationLatency float64 `perfdata:"Query size operation latency microseconds"`
DataStoreQuerySizeOperationCount float64 `perfdata:"Query size operation count"`
DataStoreSetOperationLatencyMicro float64 `perfdata:"Set operation latency microseconds"`
DataStoreSetOperationCount float64 `perfdata:"Set operation count"`
}
func (c *Collector) buildDataStore() error {
var err error
c.perfDataCollectorDataStore, err = pdh.NewCollector[perfDataCounterValuesDataStore](pdh.CounterTypeRaw, "Hyper-V DataStore", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Hyper-V DataStore collector: %w", err)
}
c.dataStoreFragmentationRatio = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_fragmentation_ratio"),
"Represents the fragmentation ratio of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreSectorSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_sector_size_bytes"),
"Represents the sector size of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreDataAlignment = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_data_alignment_bytes"),
"Represents the data alignment of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCurrentReplayLogSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_current_replay_log_size_bytes"),
"Represents the current replay log size of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreAvailableEntries = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_available_entries"),
"Represents the number of available entries inside object tables.",
[]string{"datastore"},
nil,
)
c.dataStoreEmptyEntries = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_empty_entries"),
"Represents the number of empty entries inside object tables.",
[]string{"datastore"},
nil,
)
c.dataStoreFreeBytes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_free_bytes"),
"Represents the number of free bytes inside key tables.",
[]string{"datastore"},
nil,
)
c.dataStoreDataEnd = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_data_end_bytes"),
"Represents the data end of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreFileObjects = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_file_objects"),
"Represents the number of file objects in the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreObjectTables = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_object_tables"),
"Represents the number of object tables in the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreKeyTables = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_key_tables"),
"Represents the number of key tables in the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreFileDataSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_file_data_size_bytes"),
"Represents the file data size in bytes of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreTableDataSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_table_data_size_bytes"),
"Represents the table data size in bytes of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreNamesSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_names_size_bytes"),
"Represents the names size in bytes of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreNumberOfKeys = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_number_of_keys"),
"Represents the number of keys in the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreReconnectLatencyMicro = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_reconnect_latency_microseconds"),
"Represents the reconnect latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreDisconnectCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_disconnect_count"),
"Represents the disconnect count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreWriteToFileByteLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_file_byte_latency_microseconds"),
"Represents the write to file byte latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreWriteToFileByteCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_file_byte_count"),
"Represents the write to file byte count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreWriteToFileCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_file_count"),
"Represents the write to file count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreReadFromFileByteLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_file_byte_latency_microseconds"),
"Represents the read from file byte latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreReadFromFileByteCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_file_byte_count"),
"Represents the read from file byte count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreReadFromFileCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_file_count"),
"Represents the read from file count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreWriteToStorageByteLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_storage_byte_latency_microseconds"),
"Represents the write to storage byte latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreWriteToStorageByteCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_storage_byte_count"),
"Represents the write to storage byte count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreWriteToStorageCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_storage_count"),
"Represents the write to storage count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreReadFromStorageByteLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_storage_byte_latency_microseconds"),
"Represents the read from storage byte latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreReadFromStorageByteCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_storage_byte_count"),
"Represents the read from storage byte count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreReadFromStorageCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_storage_count"),
"Represents the read from storage count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCommitByteLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_byte_latency_microseconds"),
"Represents the commit byte latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCommitByteCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_byte_count"),
"Represents the commit byte count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCommitCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_count"),
"Represents the commit count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCacheUpdateOperationLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_cache_update_operation_latency_microseconds"),
"Represents the cache update operation latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCacheUpdateOperationCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_cache_update_operation_count"),
"Represents the cache update operation count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCommitOperationLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_operation_latency_microseconds"),
"Represents the commit operation latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCommitOperationCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_operation_count"),
"Represents the commit operation count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCompactOperationLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_compact_operation_latency_microseconds"),
"Represents the compact operation latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreCompactOperationCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_compact_operation_count"),
"Represents the compact operation count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreLoadFileOperationLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_load_file_operation_latency_microseconds"),
"Represents the load file operation latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreLoadFileOperationCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_load_file_operation_count"),
"Represents the load file operation count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreRemoveOperationLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_remove_operation_latency_microseconds"),
"Represents the remove operation latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreRemoveOperationCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_remove_operation_count"),
"Represents the remove operation count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreQuerySizeOperationLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_query_size_operation_latency_microseconds"),
"Represents the query size operation latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreQuerySizeOperationCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_query_size_operation_count"),
"Represents the query size operation count of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreSetOperationLatencyMicro = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_set_operation_latency_microseconds"),
"Represents the set operation latency in microseconds of the DataStore.",
[]string{"datastore"},
nil,
)
c.dataStoreSetOperationCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "datastore_set_operation_count"),
"Represents the set operation count of the DataStore.",
[]string{"datastore"},
nil,
)
return nil
}
func (c *Collector) collectDataStore(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorDataStore.Collect(&c.perfDataObjectDataStore)
if err != nil {
return fmt.Errorf("failed to collect Hyper-V DataStore metrics: %w", err)
}
for _, data := range c.perfDataObjectDataStore {
ch <- prometheus.MustNewConstMetric(
c.dataStoreFragmentationRatio,
prometheus.GaugeValue,
data.DataStoreFragmentationRatio,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreSectorSize,
prometheus.GaugeValue,
data.DataStoreSectorSize,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreDataAlignment,
prometheus.GaugeValue,
data.DataStoreDataAlignment,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCurrentReplayLogSize,
prometheus.GaugeValue,
data.DataStoreCurrentReplayLogSize,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreAvailableEntries,
prometheus.GaugeValue,
data.DataStoreAvailableEntries,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreEmptyEntries,
prometheus.GaugeValue,
data.DataStoreEmptyEntries,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreFreeBytes,
prometheus.GaugeValue,
data.DataStoreFreeBytes,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreDataEnd,
prometheus.GaugeValue,
data.DataStoreDataEnd,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreFileObjects,
prometheus.GaugeValue,
data.DataStoreFileObjects,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreObjectTables,
prometheus.GaugeValue,
data.DataStoreObjectTables,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreKeyTables,
prometheus.GaugeValue,
data.DataStoreKeyTables,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreFileDataSize,
prometheus.GaugeValue,
data.DataStoreFileDataSize,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreTableDataSize,
prometheus.GaugeValue,
data.DataStoreTableDataSize,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreNamesSize,
prometheus.GaugeValue,
data.DataStoreNamesSize,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreNumberOfKeys,
prometheus.GaugeValue,
data.DataStoreNumberOfKeys,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreReconnectLatencyMicro,
prometheus.GaugeValue,
data.DataStoreReconnectLatencyMicro,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreDisconnectCount,
prometheus.CounterValue,
data.DataStoreDisconnectCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreWriteToFileByteLatency,
prometheus.GaugeValue,
data.DataStoreWriteToFileByteLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreWriteToFileByteCount,
prometheus.CounterValue,
data.DataStoreWriteToFileByteCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreWriteToFileCount,
prometheus.CounterValue,
data.DataStoreWriteToFileCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreReadFromFileByteLatency,
prometheus.GaugeValue,
data.DataStoreReadFromFileByteLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreReadFromFileByteCount,
prometheus.CounterValue,
data.DataStoreReadFromFileByteCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreReadFromFileCount,
prometheus.CounterValue,
data.DataStoreReadFromFileCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreWriteToStorageByteLatency,
prometheus.GaugeValue,
data.DataStoreWriteToStorageByteLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreWriteToStorageByteCount,
prometheus.CounterValue,
data.DataStoreWriteToStorageByteCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreWriteToStorageCount,
prometheus.CounterValue,
data.DataStoreWriteToStorageCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreReadFromStorageByteLatency,
prometheus.GaugeValue,
data.DataStoreReadFromStorageByteLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreReadFromStorageByteCount,
prometheus.CounterValue,
data.DataStoreReadFromStorageByteCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreReadFromStorageCount,
prometheus.CounterValue,
data.DataStoreReadFromStorageCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCommitByteLatency,
prometheus.GaugeValue,
data.DataStoreCommitByteLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCommitByteCount,
prometheus.CounterValue,
data.DataStoreCommitByteCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCommitCount,
prometheus.CounterValue,
data.DataStoreCommitCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCacheUpdateOperationLatency,
prometheus.GaugeValue,
data.DataStoreCacheUpdateOperationLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCacheUpdateOperationCount,
prometheus.CounterValue,
data.DataStoreCacheUpdateOperationCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCommitOperationLatency,
prometheus.GaugeValue,
data.DataStoreCommitOperationLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCommitOperationCount,
prometheus.CounterValue,
data.DataStoreCommitOperationCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCompactOperationLatency,
prometheus.GaugeValue,
data.DataStoreCompactOperationLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreCompactOperationCount,
prometheus.CounterValue,
data.DataStoreCompactOperationCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreLoadFileOperationLatency,
prometheus.GaugeValue,
data.DataStoreLoadFileOperationLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreLoadFileOperationCount,
prometheus.CounterValue,
data.DataStoreLoadFileOperationCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreRemoveOperationLatency,
prometheus.GaugeValue,
data.DataStoreRemoveOperationLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreRemoveOperationCount,
prometheus.CounterValue,
data.DataStoreRemoveOperationCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreQuerySizeOperationLatency,
prometheus.GaugeValue,
data.DataStoreQuerySizeOperationLatency,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreQuerySizeOperationCount,
prometheus.CounterValue,
data.DataStoreQuerySizeOperationCount,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreSetOperationLatencyMicro,
prometheus.GaugeValue,
data.DataStoreSetOperationLatencyMicro,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.dataStoreSetOperationCount,
prometheus.CounterValue,
data.DataStoreSetOperationCount,
data.Name,
)
}
return nil
}

View File

@@ -0,0 +1,122 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
)
// collectorDynamicMemoryBalancer Hyper-V Dynamic Memory Balancer metrics
type collectorDynamicMemoryBalancer struct {
perfDataCollectorDynamicMemoryBalancer *pdh.Collector
perfDataObjectDynamicMemoryBalancer []perfDataCounterValuesDynamicMemoryBalancer
vmDynamicMemoryBalancerAvailableMemoryForBalancing *prometheus.Desc // \Hyper-V Dynamic Memory Balancer(*)\Available Memory For Balancing
vmDynamicMemoryBalancerSystemCurrentPressure *prometheus.Desc // \Hyper-V Dynamic Memory Balancer(*)\System Current Pressure
vmDynamicMemoryBalancerAvailableMemory *prometheus.Desc // \Hyper-V Dynamic Memory Balancer(*)\Available Memory
vmDynamicMemoryBalancerAveragePressure *prometheus.Desc // \Hyper-V Dynamic Memory Balancer(*)\Average Pressure
}
type perfDataCounterValuesDynamicMemoryBalancer struct {
Name string
// Hyper-V Dynamic Memory Balancer metrics
VmDynamicMemoryBalancerAvailableMemory float64 `perfdata:"Available Memory"`
VmDynamicMemoryBalancerAvailableMemoryForBalancing float64 `perfdata:"Available Memory For Balancing"`
VmDynamicMemoryBalancerAveragePressure float64 `perfdata:"Average Pressure"`
VmDynamicMemoryBalancerSystemCurrentPressure float64 `perfdata:"System Current Pressure"`
}
func (c *Collector) buildDynamicMemoryBalancer() error {
var err error
// https://learn.microsoft.com/en-us/archive/blogs/chrisavis/monitoring-dynamic-memory-in-windows-server-hyper-v-2012
c.perfDataCollectorDynamicMemoryBalancer, err = pdh.NewCollector[perfDataCounterValuesDynamicMemoryBalancer](pdh.CounterTypeRaw, "Hyper-V Dynamic Memory Balancer", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Hyper-V Virtual Machine Health Summary collector: %w", err)
}
c.vmDynamicMemoryBalancerAvailableMemory = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_balancer_available_memory_bytes"),
"Represents the amount of memory left on the node.",
[]string{"balancer"},
nil,
)
c.vmDynamicMemoryBalancerAvailableMemoryForBalancing = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_balancer_available_memory_for_balancing_bytes"),
"Represents the available memory for balancing purposes.",
[]string{"balancer"},
nil,
)
c.vmDynamicMemoryBalancerAveragePressure = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_balancer_average_pressure_ratio"),
"Represents the average system pressure on the balancer node among all balanced objects.",
[]string{"balancer"},
nil,
)
c.vmDynamicMemoryBalancerSystemCurrentPressure = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_balancer_system_current_pressure_ratio"),
"Represents the current pressure in the system.",
[]string{"balancer"},
nil,
)
return nil
}
func (c *Collector) collectDynamicMemoryBalancer(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorDynamicMemoryBalancer.Collect(&c.perfDataObjectDynamicMemoryBalancer)
if err != nil {
return fmt.Errorf("failed to collect Hyper-V Dynamic Memory Balancer metrics: %w", err)
}
for _, data := range c.perfDataObjectDynamicMemoryBalancer {
ch <- prometheus.MustNewConstMetric(
c.vmDynamicMemoryBalancerAvailableMemory,
prometheus.GaugeValue,
utils.MBToBytes(data.VmDynamicMemoryBalancerAvailableMemory),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmDynamicMemoryBalancerAvailableMemoryForBalancing,
prometheus.GaugeValue,
utils.MBToBytes(data.VmDynamicMemoryBalancerAvailableMemoryForBalancing),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmDynamicMemoryBalancerAveragePressure,
prometheus.GaugeValue,
utils.PercentageToRatio(data.VmDynamicMemoryBalancerAveragePressure),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmDynamicMemoryBalancerSystemCurrentPressure,
prometheus.GaugeValue,
utils.PercentageToRatio(data.VmDynamicMemoryBalancerSystemCurrentPressure),
data.Name,
)
}
return nil
}

View File

@@ -0,0 +1,211 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
)
// collectorDynamicMemoryVM Hyper-V Dynamic Memory VM metrics
type collectorDynamicMemoryVM struct {
perfDataCollectorDynamicMemoryVM *pdh.Collector
perfDataObjectDynamicMemoryVM []perfDataCounterValuesDynamicMemoryVM
vmMemoryAddedMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Added Memory
vmMemoryCurrentPressure *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Current Pressure
vmMemoryGuestVisiblePhysicalMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Guest Visible Physical Memory
vmMemoryMaximumPressure *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Maximum Pressure
vmMemoryMemoryAddOperations *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Memory Add Operations
vmMemoryMemoryRemoveOperations *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Memory Remove Operations
vmMemoryMinimumPressure *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Minimum Pressure
vmMemoryPhysicalMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Physical Memory
vmMemoryRemovedMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Removed Memory
vmMemoryGuestAvailableMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Guest Available Memory
}
type perfDataCounterValuesDynamicMemoryVM struct {
Name string
// Hyper-V Dynamic Memory VM metrics
VmMemoryAddedMemory float64 `perfdata:"Added Memory"`
VmMemoryCurrentPressure float64 `perfdata:"Current Pressure"`
VmMemoryGuestAvailableMemory float64 `perfdata:"Guest Available Memory"`
VmMemoryGuestVisiblePhysicalMemory float64 `perfdata:"Guest Visible Physical Memory"`
VmMemoryMaximumPressure float64 `perfdata:"Maximum Pressure"`
VmMemoryMemoryAddOperations float64 `perfdata:"Memory Add Operations"`
VmMemoryMemoryRemoveOperations float64 `perfdata:"Memory Remove Operations"`
VmMemoryMinimumPressure float64 `perfdata:"Minimum Pressure"`
VmMemoryPhysicalMemory float64 `perfdata:"Physical Memory"`
VmMemoryRemovedMemory float64 `perfdata:"Removed Memory"`
}
func (c *Collector) buildDynamicMemoryVM() error {
var err error
c.perfDataCollectorDynamicMemoryVM, err = pdh.NewCollector[perfDataCounterValuesDynamicMemoryVM](pdh.CounterTypeRaw, "Hyper-V Dynamic Memory VM", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Hyper-V Dynamic Memory VM collector: %w", err)
}
c.vmMemoryAddedMemory = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_added_total"),
"Represents the cumulative amount of memory added to the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryCurrentPressure = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_pressure_current_ratio"),
"Represents the current pressure in the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryGuestAvailableMemory = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_guest_available_bytes"),
"Represents the current amount of available memory in the VM (reported by the VM).",
[]string{"vm"},
nil,
)
c.vmMemoryGuestVisiblePhysicalMemory = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_guest_visible_physical_memory_bytes"),
"Represents the amount of memory visible in the VM.'",
[]string{"vm"},
nil,
)
c.vmMemoryMaximumPressure = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_pressure_maximum_ratio"),
"Represents the maximum pressure band in the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryMemoryAddOperations = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_add_operations_total"),
"Represents the total number of add operations for the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryMemoryRemoveOperations = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_remove_operations_total"),
"Represents the total number of remove operations for the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryMinimumPressure = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_pressure_minimum_ratio"),
"Represents the minimum pressure band in the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryPhysicalMemory = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_physical_bytes"),
"Represents the current amount of memory in the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryRemovedMemory = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_removed_bytes_total"),
"Represents the cumulative amount of memory removed from the VM.",
[]string{"vm"},
nil,
)
return nil
}
func (c *Collector) collectDynamicMemoryVM(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorDynamicMemoryVM.Collect(&c.perfDataObjectDynamicMemoryVM)
if err != nil {
return fmt.Errorf("failed to collect Hyper-V Dynamic Memory VM metrics: %w", err)
}
for _, data := range c.perfDataObjectDynamicMemoryVM {
ch <- prometheus.MustNewConstMetric(
c.vmMemoryAddedMemory,
prometheus.CounterValue,
utils.MBToBytes(data.VmMemoryAddedMemory),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryCurrentPressure,
prometheus.GaugeValue,
utils.PercentageToRatio(data.VmMemoryCurrentPressure),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryGuestAvailableMemory,
prometheus.GaugeValue,
utils.MBToBytes(data.VmMemoryGuestAvailableMemory),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryGuestVisiblePhysicalMemory,
prometheus.GaugeValue,
utils.MBToBytes(data.VmMemoryGuestVisiblePhysicalMemory),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryMaximumPressure,
prometheus.GaugeValue,
utils.PercentageToRatio(data.VmMemoryMaximumPressure),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryMemoryAddOperations,
prometheus.CounterValue,
data.VmMemoryMemoryAddOperations,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryMemoryRemoveOperations,
prometheus.CounterValue,
data.VmMemoryMemoryRemoveOperations,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryMinimumPressure,
prometheus.GaugeValue,
utils.PercentageToRatio(data.VmMemoryMinimumPressure),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryPhysicalMemory,
prometheus.GaugeValue,
utils.MBToBytes(data.VmMemoryPhysicalMemory),
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryRemovedMemory,
prometheus.CounterValue,
utils.MBToBytes(data.VmMemoryRemovedMemory),
data.Name,
)
}
return nil
}

View File

@@ -0,0 +1,133 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"fmt"
"strings"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
// collectorHypervisorLogicalProcessor Hyper-V Hypervisor Logical Processor metrics
type collectorHypervisorLogicalProcessor struct {
perfDataCollectorHypervisorLogicalProcessor *pdh.Collector
perfDataObjectHypervisorLogicalProcessor []perfDataCounterValuesHypervisorLogicalProcessor
// \Hyper-V Hypervisor Logical Processor(*)\% Guest Run Time
// \Hyper-V Hypervisor Logical Processor(*)\% Hypervisor Run Time
// \Hyper-V Hypervisor Logical Processor(*)\% Idle Time
hypervisorLogicalProcessorTimeTotal *prometheus.Desc
hypervisorLogicalProcessorTotalRunTimeTotal *prometheus.Desc // \Hyper-V Hypervisor Logical Processor(*)\% Total Run Time
hypervisorLogicalProcessorContextSwitches *prometheus.Desc // \Hyper-V Hypervisor Logical Processor(*)\Context Switches/sec
}
type perfDataCounterValuesHypervisorLogicalProcessor struct {
Name string
HypervisorLogicalProcessorGuestRunTimePercent float64 `perfdata:"% Guest Run Time"`
HypervisorLogicalProcessorHypervisorRunTimePercent float64 `perfdata:"% Hypervisor Run Time"`
HypervisorLogicalProcessorTotalRunTimePercent float64 `perfdata:"% Total Run Time"`
HypervisorLogicalProcessorIdleRunTimePercent float64 `perfdata:"% Idle Time"`
HypervisorLogicalProcessorContextSwitches float64 `perfdata:"Context Switches/sec"`
}
func (c *Collector) buildHypervisorLogicalProcessor() error {
var err error
c.perfDataCollectorHypervisorLogicalProcessor, err = pdh.NewCollector[perfDataCounterValuesHypervisorLogicalProcessor](pdh.CounterTypeRaw, "Hyper-V Hypervisor Logical Processor", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Hyper-V Hypervisor Logical Processor collector: %w", err)
}
c.hypervisorLogicalProcessorTimeTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "hypervisor_logical_processor_time_total"),
"Time that processor spent in different modes (hypervisor, guest, idle)",
[]string{"core", "state"},
nil,
)
c.hypervisorLogicalProcessorTotalRunTimeTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "hypervisor_logical_processor_total_run_time_total"),
"Time that processor spent",
[]string{"core"},
nil,
)
c.hypervisorLogicalProcessorContextSwitches = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "hypervisor_logical_processor_context_switches_total"),
"The rate of virtual processor context switches on the processor.",
[]string{"core"},
nil,
)
return nil
}
func (c *Collector) collectHypervisorLogicalProcessor(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorHypervisorLogicalProcessor.Collect(&c.perfDataObjectHypervisorLogicalProcessor)
if err != nil {
return fmt.Errorf("failed to collect Hyper-V Hypervisor Logical Processor metrics: %w", err)
}
for _, data := range c.perfDataObjectHypervisorLogicalProcessor {
// The name format is Hv LP <core id>
parts := strings.Split(data.Name, " ")
if len(parts) != 3 {
return fmt.Errorf("unexpected Hyper-V Hypervisor Logical Processor name format: %s", data.Name)
}
coreID := parts[2]
ch <- prometheus.MustNewConstMetric(
c.hypervisorLogicalProcessorTimeTotal,
prometheus.CounterValue,
data.HypervisorLogicalProcessorGuestRunTimePercent,
coreID, "guest",
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorLogicalProcessorTimeTotal,
prometheus.CounterValue,
data.HypervisorLogicalProcessorHypervisorRunTimePercent,
coreID, "hypervisor",
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorLogicalProcessorTimeTotal,
prometheus.CounterValue,
data.HypervisorLogicalProcessorIdleRunTimePercent,
coreID, "idle",
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorLogicalProcessorTotalRunTimeTotal,
prometheus.CounterValue,
data.HypervisorLogicalProcessorTotalRunTimePercent,
coreID,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorLogicalProcessorContextSwitches,
prometheus.CounterValue,
data.HypervisorLogicalProcessorContextSwitches,
coreID,
)
}
return nil
}

View File

@@ -0,0 +1,338 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
// collectorHypervisorRootPartition Hyper-V Hypervisor Root Partition metrics
type collectorHypervisorRootPartition struct {
perfDataCollectorHypervisorRootPartition *pdh.Collector
perfDataObjectHypervisorRootPartition []perfDataCounterValuesHypervisorRootPartition
hypervisorRootPartitionAddressSpaces *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Address Spaces
hypervisorRootPartitionAttachedDevices *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Attached Devices
hypervisorRootPartitionDepositedPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Deposited Pages
hypervisorRootPartitionDeviceDMAErrors *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Device DMA Errors
hypervisorRootPartitionDeviceInterruptErrors *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Device Interrupt Errors
hypervisorRootPartitionDeviceInterruptMappings *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Device Interrupt Mappings
hypervisorRootPartitionDeviceInterruptThrottleEvents *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Device Interrupt Throttle Events
hypervisorRootPartitionGPAPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\GPA Pages
hypervisorRootPartitionGPASpaceModifications *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\GPA Space Modifications/sec
hypervisorRootPartitionIOTLBFlushCost *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\I/O TLB Flush Cost
hypervisorRootPartitionIOTLBFlushes *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\I/O TLB Flushes/sec
hypervisorRootPartitionRecommendedVirtualTLBSize *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Recommended Virtual TLB Size
hypervisorRootPartitionSkippedTimerTicks *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Skipped Timer Ticks
hypervisorRootPartition1GDevicePages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\1G device pages
hypervisorRootPartition1GGPAPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\1G GPA pages
hypervisorRootPartition2MDevicePages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\2M device pages
hypervisorRootPartition2MGPAPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\2M GPA pages
hypervisorRootPartition4KDevicePages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\4K device pages
hypervisorRootPartition4KGPAPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\4K GPA pages
hypervisorRootPartitionVirtualTLBFlushEntries *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Virtual TLB Flush Entries/sec
hypervisorRootPartitionVirtualTLBPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Virtual TLB Pages
}
type perfDataCounterValuesHypervisorRootPartition struct {
HypervisorRootPartitionAddressSpaces float64 `perfdata:"Address Spaces"`
HypervisorRootPartitionAttachedDevices float64 `perfdata:"Attached Devices"`
HypervisorRootPartitionDepositedPages float64 `perfdata:"Deposited Pages"`
HypervisorRootPartitionDeviceDMAErrors float64 `perfdata:"Device DMA Errors"`
HypervisorRootPartitionDeviceInterruptErrors float64 `perfdata:"Device Interrupt Errors"`
HypervisorRootPartitionDeviceInterruptMappings float64 `perfdata:"Device Interrupt Mappings"`
HypervisorRootPartitionDeviceInterruptThrottleEvents float64 `perfdata:"Device Interrupt Throttle Events"`
HypervisorRootPartitionGPAPages float64 `perfdata:"GPA Pages"`
HypervisorRootPartitionGPASpaceModifications float64 `perfdata:"GPA Space Modifications/sec"`
HypervisorRootPartitionIOTLBFlushCost float64 `perfdata:"I/O TLB Flush Cost"`
HypervisorRootPartitionIOTLBFlushes float64 `perfdata:"I/O TLB Flushes/sec"`
HypervisorRootPartitionRecommendedVirtualTLBSize float64 `perfdata:"Recommended Virtual TLB Size"`
HypervisorRootPartitionSkippedTimerTicks float64 `perfdata:"Skipped Timer Ticks"`
HypervisorRootPartition1GDevicePages float64 `perfdata:"1G device pages"`
HypervisorRootPartition1GGPAPages float64 `perfdata:"1G GPA pages"`
HypervisorRootPartition2MDevicePages float64 `perfdata:"2M device pages"`
HypervisorRootPartition2MGPAPages float64 `perfdata:"2M GPA pages"`
HypervisorRootPartition4KDevicePages float64 `perfdata:"4K device pages"`
HypervisorRootPartition4KGPAPages float64 `perfdata:"4K GPA pages"`
HypervisorRootPartitionVirtualTLBFlushEntries float64 `perfdata:"Virtual TLB Flush Entires/sec"`
HypervisorRootPartitionVirtualTLBPages float64 `perfdata:"Virtual TLB Pages"`
}
func (c *Collector) buildHypervisorRootPartition() error {
var err error
c.perfDataCollectorHypervisorRootPartition, err = pdh.NewCollector[perfDataCounterValuesHypervisorRootPartition](pdh.CounterTypeRaw, "Hyper-V Hypervisor Root Partition", []string{"Root"})
if err != nil {
return fmt.Errorf("failed to create Hyper-V Hypervisor Root Partition collector: %w", err)
}
c.hypervisorRootPartitionAddressSpaces = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_address_spaces"),
"The number of address spaces in the virtual TLB of the partition",
nil,
nil,
)
c.hypervisorRootPartitionAttachedDevices = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_attached_devices"),
"The number of devices attached to the partition",
nil,
nil,
)
c.hypervisorRootPartitionDepositedPages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_deposited_pages"),
"The number of pages deposited into the partition",
nil,
nil,
)
c.hypervisorRootPartitionDeviceDMAErrors = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_device_dma_errors"),
"An indicator of illegal DMA requests generated by all devices assigned to the partition",
nil,
nil,
)
c.hypervisorRootPartitionDeviceInterruptErrors = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_device_interrupt_errors"),
"An indicator of illegal interrupt requests generated by all devices assigned to the partition",
nil,
nil,
)
c.hypervisorRootPartitionDeviceInterruptMappings = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_device_interrupt_mappings"),
"The number of device interrupt mappings used by the partition",
nil,
nil,
)
c.hypervisorRootPartitionDeviceInterruptThrottleEvents = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_device_interrupt_throttle_events"),
"The number of times an interrupt from a device assigned to the partition was temporarily throttled because the device was generating too many interrupts",
nil,
nil,
)
c.hypervisorRootPartitionGPAPages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_preferred_numa_node_index"),
"The number of pages present in the GPA space of the partition (zero for root partition)",
nil,
nil,
)
c.hypervisorRootPartitionGPASpaceModifications = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_gpa_space_modifications"),
"The rate of modifications to the GPA space of the partition",
nil,
nil,
)
c.hypervisorRootPartitionIOTLBFlushCost = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_io_tlb_flush_cost"),
"The average time (in nanoseconds) spent processing an I/O TLB flush",
nil,
nil,
)
c.hypervisorRootPartitionIOTLBFlushes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_io_tlb_flush"),
"The rate of flushes of I/O TLBs of the partition",
nil,
nil,
)
c.hypervisorRootPartitionRecommendedVirtualTLBSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_recommended_virtual_tlb_size"),
"The recommended number of pages to be deposited for the virtual TLB",
nil,
nil,
)
c.hypervisorRootPartitionSkippedTimerTicks = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_physical_pages_allocated"),
"The number of timer interrupts skipped for the partition",
nil,
nil,
)
c.hypervisorRootPartition1GDevicePages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_1G_device_pages"),
"The number of 1G pages present in the device space of the partition",
nil,
nil,
)
c.hypervisorRootPartition1GGPAPages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_1G_gpa_pages"),
"The number of 1G pages present in the GPA space of the partition",
nil,
nil,
)
c.hypervisorRootPartition2MDevicePages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_2M_device_pages"),
"The number of 2M pages present in the device space of the partition",
nil,
nil,
)
c.hypervisorRootPartition2MGPAPages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_2M_gpa_pages"),
"The number of 2M pages present in the GPA space of the partition",
nil,
nil,
)
c.hypervisorRootPartition4KDevicePages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_4K_device_pages"),
"The number of 4K pages present in the device space of the partition",
nil,
nil,
)
c.hypervisorRootPartition4KGPAPages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_4K_gpa_pages"),
"The number of 4K pages present in the GPA space of the partition",
nil,
nil,
)
c.hypervisorRootPartitionVirtualTLBFlushEntries = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_virtual_tlb_flush_entries"),
"The rate of flushes of the entire virtual TLB",
nil,
nil,
)
c.hypervisorRootPartitionVirtualTLBPages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "root_partition_virtual_tlb_pages"),
"The number of pages used by the virtual TLB of the partition",
nil,
nil,
)
return nil
}
func (c *Collector) collectHypervisorRootPartition(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorHypervisorRootPartition.Collect(&c.perfDataObjectHypervisorRootPartition)
if err != nil {
return fmt.Errorf("failed to collect Hyper-V Hypervisor Root Partition metrics: %w", err)
}
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionAddressSpaces,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionAddressSpaces,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionAttachedDevices,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionAttachedDevices,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionDepositedPages,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionDepositedPages,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionDeviceDMAErrors,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionDeviceDMAErrors,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionDeviceInterruptErrors,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionDeviceInterruptErrors,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionDeviceInterruptThrottleEvents,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionDeviceInterruptThrottleEvents,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionGPAPages,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionGPAPages,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionGPASpaceModifications,
prometheus.CounterValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionGPASpaceModifications,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionIOTLBFlushCost,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionIOTLBFlushCost,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionIOTLBFlushes,
prometheus.CounterValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionIOTLBFlushes,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionRecommendedVirtualTLBSize,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionRecommendedVirtualTLBSize,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionSkippedTimerTicks,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionSkippedTimerTicks,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartition1GDevicePages,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartition1GDevicePages,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartition1GGPAPages,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartition1GGPAPages,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartition2MDevicePages,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartition2MDevicePages,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartition2MGPAPages,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartition2MGPAPages,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartition4KDevicePages,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartition4KDevicePages,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartition4KGPAPages,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartition4KGPAPages,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionVirtualTLBFlushEntries,
prometheus.CounterValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionVirtualTLBFlushEntries,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootPartitionVirtualTLBPages,
prometheus.GaugeValue,
c.perfDataObjectHypervisorRootPartition[0].HypervisorRootPartitionVirtualTLBPages,
)
return nil
}

View File

@@ -0,0 +1,135 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"fmt"
"strings"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
// collectorHypervisorRootVirtualProcessor Hyper-V Hypervisor Root Virtual Processor metrics
type collectorHypervisorRootVirtualProcessor struct {
perfDataCollectorHypervisorRootVirtualProcessor *pdh.Collector
perfDataObjectHypervisorRootVirtualProcessor []perfDataCounterValuesHypervisorRootVirtualProcessor
// \Hyper-V Hypervisor Root Virtual Processor(*)\% Guest Run Time
// \Hyper-V Hypervisor Root Virtual Processor(*)\% Hypervisor Run Time
// \Hyper-V Hypervisor Root Virtual Processor(*)\% Remote Run Time
// \Hyper-V Hypervisor Root Virtual Processor(*)\% Total Run Time
hypervisorRootVirtualProcessorTimeTotal *prometheus.Desc
hypervisorRootVirtualProcessorTotalRunTimeTotal *prometheus.Desc
hypervisorRootVirtualProcessorCPUWaitTimePerDispatch *prometheus.Desc // \Hyper-V Hypervisor Root Virtual Processor(*)\CPU Wait Time Per Dispatch
}
type perfDataCounterValuesHypervisorRootVirtualProcessor struct {
Name string
HypervisorRootVirtualProcessorGuestRunTimePercent float64 `perfdata:"% Guest Run Time"`
HypervisorRootVirtualProcessorHypervisorRunTimePercent float64 `perfdata:"% Hypervisor Run Time"`
HypervisorRootVirtualProcessorTotalRunTimePercent float64 `perfdata:"% Total Run Time"`
HypervisorRootVirtualProcessorRemoteRunTimePercent float64 `perfdata:"% Remote Run Time"`
HypervisorRootVirtualProcessorCPUWaitTimePerDispatch float64 `perfdata:"CPU Wait Time Per Dispatch"`
}
func (c *Collector) buildHypervisorRootVirtualProcessor() error {
var err error
c.perfDataCollectorHypervisorRootVirtualProcessor, err = pdh.NewCollector[perfDataCounterValuesHypervisorRootVirtualProcessor](pdh.CounterTypeRaw, "Hyper-V Hypervisor Root Virtual Processor", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Hyper-V Hypervisor Root Virtual Processor collector: %w", err)
}
c.hypervisorRootVirtualProcessorTimeTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "hypervisor_root_virtual_processor_time_total"),
"Time that processor spent in different modes (hypervisor, guest_run, guest_idle, remote)",
[]string{"core", "state"},
nil,
)
c.hypervisorRootVirtualProcessorTotalRunTimeTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "hypervisor_root_virtual_processor_total_run_time_total"),
"Time that processor spent",
[]string{"core"},
nil,
)
c.hypervisorRootVirtualProcessorCPUWaitTimePerDispatch = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "hypervisor_root_virtual_cpu_wait_time_per_dispatch_total"),
"The average time (in nanoseconds) spent waiting for a virtual processor to be dispatched onto a logical processor.",
[]string{"core"},
nil,
)
return nil
}
func (c *Collector) collectHypervisorRootVirtualProcessor(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorHypervisorRootVirtualProcessor.Collect(&c.perfDataObjectHypervisorRootVirtualProcessor)
if err != nil {
return fmt.Errorf("failed to collect Hyper-V Hypervisor Root Virtual Processor metrics: %w", err)
}
for _, data := range c.perfDataObjectHypervisorRootVirtualProcessor {
// The name format is Hv LP <core id>
parts := strings.Split(data.Name, " ")
if len(parts) != 3 {
return fmt.Errorf("unexpected Hyper-V Hypervisor Root Virtual Processor name format: %s", data.Name)
}
coreID := parts[2]
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootVirtualProcessorTimeTotal,
prometheus.CounterValue,
data.HypervisorRootVirtualProcessorGuestRunTimePercent,
coreID, "guest_run",
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootVirtualProcessorTimeTotal,
prometheus.CounterValue,
data.HypervisorRootVirtualProcessorHypervisorRunTimePercent,
coreID, "hypervisor",
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootVirtualProcessorTimeTotal,
prometheus.CounterValue,
data.HypervisorRootVirtualProcessorRemoteRunTimePercent,
coreID, "remote",
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootVirtualProcessorTotalRunTimeTotal,
prometheus.CounterValue,
data.HypervisorRootVirtualProcessorTotalRunTimePercent,
coreID,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorRootVirtualProcessorCPUWaitTimePerDispatch,
prometheus.CounterValue,
data.HypervisorRootVirtualProcessorCPUWaitTimePerDispatch,
coreID,
)
}
return nil
}

View File

@@ -0,0 +1,138 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"fmt"
"strings"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
// collectorHypervisorVirtualProcessor Hyper-V Hypervisor Virtual Processor metrics
type collectorHypervisorVirtualProcessor struct {
perfDataCollectorHypervisorVirtualProcessor *pdh.Collector
perfDataObjectHypervisorVirtualProcessor []perfDataCounterValuesHypervisorVirtualProcessor
// \Hyper-V Hypervisor Virtual Processor(*)\% Guest Run Time
// \Hyper-V Hypervisor Virtual Processor(*)\% Hypervisor Run Time
// \Hyper-V Hypervisor Virtual Processor(*)\% Remote Run Time
hypervisorVirtualProcessorTimeTotal *prometheus.Desc
hypervisorVirtualProcessorTotalRunTimeTotal *prometheus.Desc // \Hyper-V Hypervisor Virtual Processor(*)\% Total Run Time
hypervisorVirtualProcessorContextSwitches *prometheus.Desc // \Hyper-V Hypervisor Virtual Processor(*)\CPU Wait Time Per Dispatch
}
type perfDataCounterValuesHypervisorVirtualProcessor struct {
Name string
HypervisorVirtualProcessorGuestIdleTimePercent float64 `perfdata:"% Guest Idle Time"`
HypervisorVirtualProcessorHypervisorRunTimePercent float64 `perfdata:"% Hypervisor Run Time"`
HypervisorVirtualProcessorTotalRunTimePercent float64 `perfdata:"% Total Run Time"`
HypervisorVirtualProcessorRemoteRunTimePercent float64 `perfdata:"% Remote Run Time"`
HypervisorVirtualProcessorCPUWaitTimePerDispatch float64 `perfdata:"CPU Wait Time Per Dispatch"`
}
func (c *Collector) buildHypervisorVirtualProcessor() error {
var err error
c.perfDataCollectorHypervisorVirtualProcessor, err = pdh.NewCollector[perfDataCounterValuesHypervisorVirtualProcessor](pdh.CounterTypeRaw, "Hyper-V Hypervisor Virtual Processor", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Hyper-V Hypervisor Virtual Processor collector: %w", err)
}
c.hypervisorVirtualProcessorTimeTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "hypervisor_virtual_processor_time_total"),
"Time that processor spent in different modes (hypervisor, guest_run, guest_idle, remote)",
[]string{"vm", "core", "state"},
nil,
)
c.hypervisorVirtualProcessorTotalRunTimeTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "hypervisor_virtual_processor_total_run_time_total"),
"Time that processor spent",
[]string{"vm", "core"},
nil,
)
c.hypervisorVirtualProcessorContextSwitches = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "hypervisor_virtual_processor_cpu_wait_time_per_dispatch_total"),
"The average time (in nanoseconds) spent waiting for a virtual processor to be dispatched onto a logical processor.",
[]string{"vm", "core"},
nil,
)
return nil
}
func (c *Collector) collectHypervisorVirtualProcessor(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorHypervisorVirtualProcessor.Collect(&c.perfDataObjectHypervisorVirtualProcessor)
if err != nil {
return fmt.Errorf("failed to collect Hyper-V Hypervisor Virtual Processor metrics: %w", err)
}
for _, data := range c.perfDataObjectHypervisorVirtualProcessor {
// The name format is <VM Name>:Hv VP <vcore id>
parts := strings.Split(data.Name, ":")
if len(parts) != 2 {
return fmt.Errorf("unexpected format of Name in Hyper-V Hypervisor Virtual Processor: %q, expected %q", data.Name, "<VM Name>:Hv VP <vcore id>")
}
coreParts := strings.Split(parts[1], " ")
if len(coreParts) != 3 {
return fmt.Errorf("unexpected format of core identifier in Hyper-V Hypervisor Virtual Processor: %q, expected %q", parts[1], "Hv VP <vcore id>")
}
vmName := parts[0]
coreID := coreParts[2]
ch <- prometheus.MustNewConstMetric(
c.hypervisorVirtualProcessorTimeTotal,
prometheus.CounterValue,
data.HypervisorVirtualProcessorHypervisorRunTimePercent,
vmName, coreID, "hypervisor",
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorVirtualProcessorTimeTotal,
prometheus.CounterValue,
data.HypervisorVirtualProcessorGuestIdleTimePercent,
vmName, coreID, "guest_idle",
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorVirtualProcessorTimeTotal,
prometheus.CounterValue,
data.HypervisorVirtualProcessorGuestIdleTimePercent,
vmName, coreID, "guest_idle",
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorVirtualProcessorTotalRunTimeTotal,
prometheus.CounterValue,
data.HypervisorVirtualProcessorTotalRunTimePercent,
vmName, coreID,
)
ch <- prometheus.MustNewConstMetric(
c.hypervisorVirtualProcessorContextSwitches,
prometheus.CounterValue,
data.HypervisorVirtualProcessorCPUWaitTimePerDispatch,
vmName, coreID,
)
}
return nil
}

View File

@@ -0,0 +1,149 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
// collectorLegacyNetworkAdapter Hyper-V Legacy Network Adapter metrics
type collectorLegacyNetworkAdapter struct {
perfDataCollectorLegacyNetworkAdapter *pdh.Collector
perfDataObjectLegacyNetworkAdapter []perfDataCounterValuesLegacyNetworkAdapter
legacyNetworkAdapterBytesDropped *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Bytes Dropped
legacyNetworkAdapterBytesReceived *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Bytes Received/sec
legacyNetworkAdapterBytesSent *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Bytes Sent/sec
legacyNetworkAdapterFramesDropped *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Frames Dropped
legacyNetworkAdapterFramesReceived *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Frames Received/sec
legacyNetworkAdapterFramesSent *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Frames Sent/sec
}
type perfDataCounterValuesLegacyNetworkAdapter struct {
Name string
LegacyNetworkAdapterBytesDropped float64 `perfdata:"Bytes Dropped"`
LegacyNetworkAdapterBytesReceived float64 `perfdata:"Bytes Received/sec"`
LegacyNetworkAdapterBytesSent float64 `perfdata:"Bytes Sent/sec"`
LegacyNetworkAdapterFramesDropped float64 `perfdata:"Frames Dropped"`
LegacyNetworkAdapterFramesReceived float64 `perfdata:"Frames Received/sec"`
LegacyNetworkAdapterFramesSent float64 `perfdata:"Frames Sent/sec"`
}
func (c *Collector) buildLegacyNetworkAdapter() error {
var err error
c.perfDataCollectorLegacyNetworkAdapter, err = pdh.NewCollector[perfDataCounterValuesLegacyNetworkAdapter](pdh.CounterTypeRaw, "Hyper-V Legacy Network Adapter", pdh.InstancesAll)
if err != nil {
return fmt.Errorf("failed to create Hyper-V Legacy Network Adapter collector: %w", err)
}
c.legacyNetworkAdapterBytesDropped = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_bytes_dropped_total"),
"Bytes Dropped is the number of bytes dropped on the network adapter",
[]string{"adapter"},
nil,
)
c.legacyNetworkAdapterBytesReceived = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_bytes_received_total"),
"Bytes received is the number of bytes received on the network adapter",
[]string{"adapter"},
nil,
)
c.legacyNetworkAdapterBytesSent = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_bytes_sent_total"),
"Bytes sent is the number of bytes sent over the network adapter",
[]string{"adapter"},
nil,
)
c.legacyNetworkAdapterFramesDropped = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_frames_dropped_total"),
"Frames Dropped is the number of frames dropped on the network adapter",
[]string{"adapter"},
nil,
)
c.legacyNetworkAdapterFramesReceived = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_frames_received_total"),
"Frames received is the number of frames received on the network adapter",
[]string{"adapter"},
nil,
)
c.legacyNetworkAdapterFramesSent = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_frames_sent_total"),
"Frames sent is the number of frames sent over the network adapter",
[]string{"adapter"},
nil,
)
return nil
}
func (c *Collector) collectLegacyNetworkAdapter(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorLegacyNetworkAdapter.Collect(&c.perfDataObjectLegacyNetworkAdapter)
if err != nil {
return fmt.Errorf("failed to collect Hyper-V Legacy Network Adapter metrics: %w", err)
}
for _, data := range c.perfDataObjectLegacyNetworkAdapter {
ch <- prometheus.MustNewConstMetric(
c.legacyNetworkAdapterBytesDropped,
prometheus.GaugeValue,
data.LegacyNetworkAdapterBytesDropped,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.legacyNetworkAdapterBytesReceived,
prometheus.CounterValue,
data.LegacyNetworkAdapterBytesReceived,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.legacyNetworkAdapterBytesSent,
prometheus.CounterValue,
data.LegacyNetworkAdapterBytesSent,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.legacyNetworkAdapterFramesReceived,
prometheus.CounterValue,
data.LegacyNetworkAdapterFramesReceived,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.legacyNetworkAdapterFramesDropped,
prometheus.CounterValue,
data.LegacyNetworkAdapterFramesDropped,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.legacyNetworkAdapterFramesSent,
prometheus.CounterValue,
data.LegacyNetworkAdapterFramesSent,
data.Name,
)
}
return nil
}

View File

@@ -0,0 +1,31 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv_test
import (
"testing"
"github.com/prometheus-community/windows_exporter/internal/collector/hyperv"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
)
func BenchmarkCollector(b *testing.B) {
testutils.FuncBenchmarkCollector(b, hyperv.Name, hyperv.NewWithFlags)
}
func TestCollector(t *testing.T) {
testutils.TestCollector(t, hyperv.New, nil)
}

View File

@@ -0,0 +1,81 @@
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package hyperv
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
// collectorVirtualMachineHealthSummary Hyper-V Virtual Machine Health Summary metrics
type collectorVirtualMachineHealthSummary struct {
perfDataCollectorVirtualMachineHealthSummary *pdh.Collector
perfDataObjectVirtualMachineHealthSummary []perfDataCounterValuesVirtualMachineHealthSummary
// \Hyper-V Virtual Machine Health Summary\Health Critical
// \Hyper-V Virtual Machine Health Summary\Health Ok
health *prometheus.Desc
}
type perfDataCounterValuesVirtualMachineHealthSummary struct {
// Hyper-V Virtual Machine Health Summary
HealthCritical float64 `perfdata:"Health Critical"`
HealthOk float64 `perfdata:"Health Ok"`
}
func (c *Collector) buildVirtualMachineHealthSummary() error {
var err error
c.perfDataCollectorVirtualMachineHealthSummary, err = pdh.NewCollector[perfDataCounterValuesVirtualMachineHealthSummary](pdh.CounterTypeRaw, "Hyper-V Virtual Machine Health Summary", nil)
if err != nil {
return fmt.Errorf("failed to create Hyper-V Virtual Machine Health Summary collector: %w", err)
}
c.health = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_machine_health_total_count"),
"Represents the number of virtual machines with critical health",
[]string{"state"},
nil,
)
return nil
}
func (c *Collector) collectVirtualMachineHealthSummary(ch chan<- prometheus.Metric) error {
err := c.perfDataCollectorVirtualMachineHealthSummary.Collect(&c.perfDataObjectVirtualMachineHealthSummary)
if err != nil {
return fmt.Errorf("failed to collect Hyper-V Virtual Machine Health Summary metrics: %w", err)
}
ch <- prometheus.MustNewConstMetric(
c.health,
prometheus.GaugeValue,
c.perfDataObjectVirtualMachineHealthSummary[0].HealthCritical,
"critical",
)
ch <- prometheus.MustNewConstMetric(
c.health,
prometheus.GaugeValue,
c.perfDataObjectVirtualMachineHealthSummary[0].HealthOk,
"ok",
)
return nil
}

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