mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-10 06:56:38 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66d207b0e2 | ||
|
|
15156ce444 | ||
|
|
716362d2ee | ||
|
|
1f0880b998 | ||
|
|
0f7f8f2583 | ||
|
|
7fa029a403 | ||
|
|
fb9f1fe141 | ||
|
|
bf281d9e08 | ||
|
|
d451acbd63 | ||
|
|
7c14a79ef2 | ||
|
|
3d7b16d61d | ||
|
|
a3131dc087 | ||
|
|
93940569fa | ||
|
|
1e24d7b2c9 | ||
|
|
109f537c14 | ||
|
|
62b796e6f6 | ||
|
|
8bae1abe20 |
4
.github/workflows/lint.yml
vendored
4
.github/workflows/lint.yml
vendored
@@ -18,7 +18,7 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2022
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-go@v5
|
- uses: actions/setup-go@v5
|
||||||
@@ -41,7 +41,7 @@ jobs:
|
|||||||
run: make e2e-test
|
run: make e2e-test
|
||||||
|
|
||||||
promtool:
|
promtool:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2022
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-go@v5
|
- uses: actions/setup-go@v5
|
||||||
|
|||||||
2
.github/workflows/pr-check.yaml
vendored
2
.github/workflows/pr-check.yaml
vendored
@@ -37,7 +37,7 @@ jobs:
|
|||||||
- name: check
|
- name: check
|
||||||
run: |
|
run: |
|
||||||
PR_TITLE_PREFIX=$(echo "$PR_TITLE" | cut -d':' -f1)
|
PR_TITLE_PREFIX=$(echo "$PR_TITLE" | cut -d':' -f1)
|
||||||
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" == "fix(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "feat" ]] || [[ "$PR_TITLE_PREFIX" == "chore" ]] || [[ "$PR_TITLE_PREFIX" == "chore(docs)" ]] || [[ "$PR_TITLE_PREFIX" == "chore(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "*" ]] || [[ "$PR_TITLE_PREFIX" == "Release"* ]] || [[ "$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" == "fix(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "feat" ]] || [[ "$PR_TITLE_PREFIX" == "chore" ]] || [[ "$PR_TITLE_PREFIX" == "chore(docs)" ]] || [[ "$PR_TITLE_PREFIX" == "chore(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "*" ]] || [[ "$PR_TITLE_PREFIX" == "Release"* ]] || [[ "$PR_TITLE_PREFIX" == "Synchronize common files from prometheus/prometheus" ]] || [[ "$PR_TITLE_PREFIX" == "[0."* ]] || [[ "$PR_TITLE_PREFIX" == "[1."* ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ var (
|
|||||||
stopCh = make(chan struct{})
|
stopCh = make(chan struct{})
|
||||||
|
|
||||||
// serviceManagerFinishedCh is a channel to send a signal to the main function that the service manager has stopped the service.
|
// serviceManagerFinishedCh is a channel to send a signal to the main function that the service manager has stopped the service.
|
||||||
serviceManagerFinishedCh = make(chan struct{})
|
serviceManagerFinishedCh = make(chan struct{}, 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsService variable declaration allows initiating time-sensitive components like registering the Windows service
|
// IsService variable declaration allows initiating time-sensitive components like registering the Windows service
|
||||||
|
|||||||
@@ -3,14 +3,19 @@
|
|||||||
The dns collector exposes metrics about the DNS server
|
The dns collector exposes metrics about the DNS server
|
||||||
|
|
||||||
|||
|
|||
|
||||||
-|-
|
-|-|-
|
||||||
Metric name prefix | `dns`
|
Metric name prefix | `dns` |
|
||||||
Classes | [`Win32_PerfRawData_DNS_DNS`](https://technet.microsoft.com/en-us/library/cc977686.aspx)
|
Classes | [`Win32_PerfRawData_DNS_DNS`](https://technet.microsoft.com/en-us/library/cc977686.aspx) |
|
||||||
Enabled by default? | No
|
Enabled by default | Yes |
|
||||||
|
Metric name prefix (error stats) | `windows_dns` |
|
||||||
|
Classes | [`MicrosoftDNS_Statistic`](https://learn.microsoft.com/en-us/windows/win32/dns/dns-wmi-provider-overview) |
|
||||||
|
Enabled by default (error stats)? | Yes |
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
None
|
Name | Description
|
||||||
|
-----|------------
|
||||||
|
`collector.dns.enabled` | Comma-separated list of collectors to use. Available collectors: `metrics`, `error_stats`. Defaults to all collectors if not specified.
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
||||||
@@ -38,12 +43,56 @@ Name | Description | Type | Labels
|
|||||||
`windows_dns_wins_queries_total` | _Not yet documented_ | counter | `direction`
|
`windows_dns_wins_queries_total` | _Not yet documented_ | counter | `direction`
|
||||||
`windows_dns_wins_responses_total` | _Not yet documented_ | counter | `direction`
|
`windows_dns_wins_responses_total` | _Not yet documented_ | counter | `direction`
|
||||||
`windows_dns_unmatched_responses_total` | _Not yet documented_ | counter | None
|
`windows_dns_unmatched_responses_total` | _Not yet documented_ | counter | None
|
||||||
|
`windows_dns_error_stats_total` | DNS error statistics from MicrosoftDNS_Statistic | counter | `name`, `collection_name`, `dns_server`
|
||||||
|
|
||||||
|
### Sub-collectors
|
||||||
|
|
||||||
|
The DNS collector is split into two sub-collectors:
|
||||||
|
|
||||||
|
1. `metrics` - Collects standard DNS performance metrics using PDH (Performance Data Helper)
|
||||||
|
2. `wmi_stats` - Collects DNS error statistics from the MicrosoftDNS_Statistic WMI class
|
||||||
|
|
||||||
|
By default, both sub-collectors are enabled. You can enable specific sub-collectors using the `collector.dns.enabled` flag.
|
||||||
|
|
||||||
|
### Example Usage
|
||||||
|
|
||||||
|
To enable only DNS error statistics collection:
|
||||||
|
```powershell
|
||||||
|
windows_exporter.exe --collector.dns.enabled=wmi_stats
|
||||||
|
```
|
||||||
|
|
||||||
|
To enable only standard DNS metrics:
|
||||||
|
```powershell
|
||||||
|
windows_exporter.exe --collector.dns.enabled=metrics
|
||||||
|
```
|
||||||
|
|
||||||
|
To enable both (default behavior):
|
||||||
|
```powershell
|
||||||
|
windows_exporter.exe --collector.dns.enabled=metrics,wmi_stats
|
||||||
|
```
|
||||||
|
|
||||||
### Example metric
|
### Example metric
|
||||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
```
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="BadKey"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="BadSig"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="BadTime"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="FormError"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="Max"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="NoError"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="NotAuth"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="NotImpl"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="NotZone"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="NxDomain"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="NxRRSet"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="Refused"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="ServFail"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="UnknownError"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="YxDomain"} 0
|
||||||
|
windows_dns_wmi_stats_total{collection_name="Error Stats",dns_server="EC2AMAZ-5NNM8M1",name="YxRRSet"} 0
|
||||||
|
```
|
||||||
|
|
||||||
## Useful queries
|
## Useful queries
|
||||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||||
|
|
||||||
## Alerting examples
|
## 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!_
|
||||||
@@ -43,7 +43,7 @@ Comma-separated list of collectors to use, for example: `--collectors.exchange.e
|
|||||||
| `windows_exchange_transport_queues_messages_submitted_total` | Messages Submitted 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_delayed_total` | Messages Delayed Total |
|
||||||
| `windows_exchange_transport_queues_messages_completed_delivery_total` | Messages Completed Delivery 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_aggregate_shadow_queue_length` | The current number of messages in shadow queues |
|
||||||
| `windows_exchange_transport_queues_submission_queue_length` | Submission 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_delay_queue_length` | Delay Queue Length |
|
||||||
| `windows_exchange_transport_queues_items_completed_delivery_total` | Items Completed Delivery Total |
|
| `windows_exchange_transport_queues_items_completed_delivery_total` | Items Completed Delivery Total |
|
||||||
@@ -54,7 +54,7 @@ Comma-separated list of collectors to use, for example: `--collectors.exchange.e
|
|||||||
| `windows_exchange_http_proxy_avg_auth_latency` | Average time spent authenticating CAS requests over the last 200 samples |
|
| `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_outstanding_proxy_requests` | Number of concurrent outstanding proxy requests |
|
||||||
| `windows_exchange_http_proxy_requests_total` | Number of proxy requests processed each second |
|
| `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_availability_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_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_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_autodiscover_requests_total` | Number of autodiscover service requests processed each second |
|
||||||
@@ -77,4 +77,3 @@ _This collector does not yet have any useful queries added, we would appreciate
|
|||||||
|
|
||||||
## Alerting examples
|
## 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!_
|
||||||
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -7,7 +7,7 @@ toolchain go1.23.4
|
|||||||
require (
|
require (
|
||||||
github.com/Microsoft/hcsshim v0.12.9
|
github.com/Microsoft/hcsshim v0.12.9
|
||||||
github.com/alecthomas/kingpin/v2 v2.4.0
|
github.com/alecthomas/kingpin/v2 v2.4.0
|
||||||
github.com/bmatcuk/doublestar/v4 v4.8.1
|
github.com/bmatcuk/doublestar/v4 v4.9.0
|
||||||
github.com/dimchansky/utfbom v1.1.1
|
github.com/dimchansky/utfbom v1.1.1
|
||||||
github.com/go-ole/go-ole v1.3.0
|
github.com/go-ole/go-ole v1.3.0
|
||||||
github.com/prometheus/client_golang v1.21.1
|
github.com/prometheus/client_golang v1.21.1
|
||||||
|
|||||||
22
go.sum
22
go.sum
@@ -10,8 +10,8 @@ github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vS
|
|||||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
|
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 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
|
github.com/bmatcuk/doublestar/v4 v4.9.0 h1:DBvuZxjdKkRP/dr4GVV4w2fnmrk5Hxc90T51LZjv0JA=
|
||||||
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
github.com/bmatcuk/doublestar/v4 v4.9.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
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 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
@@ -70,8 +70,6 @@ github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2E
|
|||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
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/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/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
@@ -128,8 +126,6 @@ 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-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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
|
||||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
|
||||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@@ -147,13 +143,9 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/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-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.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
|
||||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
|
||||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
|
||||||
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
|
||||||
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
||||||
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -161,8 +153,6 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
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.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
|
||||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
|
||||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -171,14 +161,10 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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.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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
|
||||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
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.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
|
||||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
|
||||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@@ -198,8 +184,6 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
|||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
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-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
@@ -207,8 +191,6 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
|||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
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.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
|
||||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
|
||||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
|
|||||||
@@ -520,6 +520,8 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to collect DirectoryServices (AD) metrics: %w", err)
|
return fmt.Errorf("failed to collect DirectoryServices (AD) metrics: %w", err)
|
||||||
|
} else if len(c.perfDataObject) == 0 {
|
||||||
|
return fmt.Errorf("failed to collect DirectoryServices (AD) metrics: %w", types.ErrNoDataUnexpected)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
|||||||
@@ -385,6 +385,8 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to collect ADFS metrics: %w", err)
|
return fmt.Errorf("failed to collect ADFS metrics: %w", err)
|
||||||
|
} else if len(c.perfDataObject) == 0 {
|
||||||
|
return fmt.Errorf("failed to collect ADFS metrics: %w", types.ErrNoDataUnexpected)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
|||||||
2
internal/collector/cache/cache.go
vendored
2
internal/collector/cache/cache.go
vendored
@@ -288,6 +288,8 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to collect Cache metrics: %w", err)
|
return fmt.Errorf("failed to collect Cache metrics: %w", err)
|
||||||
|
} else if len(c.perfDataObject) == 0 {
|
||||||
|
return fmt.Errorf("failed to collect Cache metrics: %w", types.ErrNoDataUnexpected)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
|||||||
@@ -403,6 +403,8 @@ func (c *Collector) collectServerMetrics(ch chan<- prometheus.Metric) error {
|
|||||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to collect DHCP Server metrics: %w", err)
|
return fmt.Errorf("failed to collect DHCP Server metrics: %w", err)
|
||||||
|
} else if len(c.perfDataObject) == 0 {
|
||||||
|
return fmt.Errorf("failed to collect DHCP Server metrics: %w", types.ErrNoDataUnexpected)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ var ConfigDefaults = Config{}
|
|||||||
|
|
||||||
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_DiskDrive.
|
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_DiskDrive.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
config Config
|
config Config
|
||||||
|
logger *slog.Logger
|
||||||
|
|
||||||
miSession *mi.Session
|
miSession *mi.Session
|
||||||
miQuery mi.Query
|
miQuery mi.Query
|
||||||
|
|
||||||
@@ -71,7 +73,9 @@ func (c *Collector) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
|
func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
|
||||||
|
c.logger = logger.With(slog.String("collector", Name))
|
||||||
|
|
||||||
c.diskInfo = prometheus.NewDesc(
|
c.diskInfo = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||||
"General drive information",
|
"General drive information",
|
||||||
@@ -146,7 +150,7 @@ var (
|
|||||||
"Error",
|
"Error",
|
||||||
"Degraded",
|
"Degraded",
|
||||||
"Unknown",
|
"Unknown",
|
||||||
"Pred fail",
|
"Pred Fail",
|
||||||
"Starting",
|
"Starting",
|
||||||
"Stopping",
|
"Stopping",
|
||||||
"Service",
|
"Service",
|
||||||
|
|||||||
@@ -16,8 +16,11 @@
|
|||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||||
@@ -26,12 +29,23 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const Name = "dns"
|
const (
|
||||||
|
Name = "dns"
|
||||||
|
subCollectorMetrics = "metrics"
|
||||||
|
subCollectorWMIStats = "wmi_stats"
|
||||||
|
)
|
||||||
|
|
||||||
type Config struct{}
|
type Config struct {
|
||||||
|
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{
|
||||||
|
CollectorsEnabled: []string{
|
||||||
|
subCollectorMetrics,
|
||||||
|
subCollectorWMIStats,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics.
|
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
@@ -40,6 +54,9 @@ type Collector struct {
|
|||||||
perfDataCollector *pdh.Collector
|
perfDataCollector *pdh.Collector
|
||||||
perfDataObject []perfDataCounterValues
|
perfDataObject []perfDataCounterValues
|
||||||
|
|
||||||
|
miSession *mi.Session
|
||||||
|
miQuery mi.Query
|
||||||
|
|
||||||
dynamicUpdatesFailures *prometheus.Desc
|
dynamicUpdatesFailures *prometheus.Desc
|
||||||
dynamicUpdatesQueued *prometheus.Desc
|
dynamicUpdatesQueued *prometheus.Desc
|
||||||
dynamicUpdatesReceived *prometheus.Desc
|
dynamicUpdatesReceived *prometheus.Desc
|
||||||
@@ -62,6 +79,7 @@ type Collector struct {
|
|||||||
zoneTransferResponsesReceived *prometheus.Desc
|
zoneTransferResponsesReceived *prometheus.Desc
|
||||||
zoneTransferSuccessReceived *prometheus.Desc
|
zoneTransferSuccessReceived *prometheus.Desc
|
||||||
zoneTransferSuccessSent *prometheus.Desc
|
zoneTransferSuccessSent *prometheus.Desc
|
||||||
|
dnsWMIStats *prometheus.Desc
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(config *Config) *Collector {
|
func New(config *Config) *Collector {
|
||||||
@@ -69,6 +87,10 @@ func New(config *Config) *Collector {
|
|||||||
config = &ConfigDefaults
|
config = &ConfigDefaults
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.CollectorsEnabled == nil {
|
||||||
|
config.CollectorsEnabled = ConfigDefaults.CollectorsEnabled
|
||||||
|
}
|
||||||
|
|
||||||
c := &Collector{
|
c := &Collector{
|
||||||
config: *config,
|
config: *config,
|
||||||
}
|
}
|
||||||
@@ -76,8 +98,26 @@ func New(config *Config) *Collector {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWithFlags(_ *kingpin.Application) *Collector {
|
func NewWithFlags(app *kingpin.Application) *Collector {
|
||||||
return &Collector{}
|
c := &Collector{
|
||||||
|
config: ConfigDefaults,
|
||||||
|
}
|
||||||
|
c.config.CollectorsEnabled = make([]string, 0)
|
||||||
|
|
||||||
|
var collectorsEnabled string
|
||||||
|
|
||||||
|
app.Flag(
|
||||||
|
"collector.dns.enabled",
|
||||||
|
"Comma-separated list of collectors to use. Defaults to all, if not specified.",
|
||||||
|
).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 {
|
func (c *Collector) GetName() string {
|
||||||
@@ -90,7 +130,31 @@ func (c *Collector) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
|
||||||
|
for _, collector := range c.config.CollectorsEnabled {
|
||||||
|
if !slices.Contains([]string{subCollectorMetrics, subCollectorWMIStats}, collector) {
|
||||||
|
return fmt.Errorf("unknown sub collector: %s. Possible values: %s", collector,
|
||||||
|
strings.Join([]string{subCollectorMetrics, subCollectorWMIStats}, ", "),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if slices.Contains(c.config.CollectorsEnabled, subCollectorMetrics) {
|
||||||
|
if err := c.buildMetricsCollector(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if slices.Contains(c.config.CollectorsEnabled, subCollectorWMIStats) {
|
||||||
|
if err := c.buildErrorStatsCollector(miSession); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Collector) buildMetricsCollector() error {
|
||||||
c.zoneTransferRequestsReceived = prometheus.NewDesc(
|
c.zoneTransferRequestsReceived = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_received_total"),
|
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_received_total"),
|
||||||
"Number of zone transfer requests (AXFR/IXFR) received by the master DNS server",
|
"Number of zone transfer requests (AXFR/IXFR) received by the master DNS server",
|
||||||
@@ -224,6 +288,13 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
c.dnsWMIStats = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "wmi_stats_total"),
|
||||||
|
"DNS WMI statistics from MicrosoftDNS_Statistic",
|
||||||
|
[]string{"name", "collection_name", "dns_server"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "DNS", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "DNS", pdh.InstancesAll)
|
||||||
@@ -234,12 +305,48 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Collector) buildErrorStatsCollector(miSession *mi.Session) error {
|
||||||
|
if miSession == nil {
|
||||||
|
return errors.New("miSession is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
query, err := mi.NewQuery("SELECT Name, CollectionName, Value, DnsServerName FROM MicrosoftDNS_Statistic WHERE CollectionName = 'Error Stats'")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create query: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.miSession = miSession
|
||||||
|
c.miQuery = query
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||||
|
errs := make([]error, 0)
|
||||||
|
|
||||||
|
if slices.Contains(c.config.CollectorsEnabled, subCollectorMetrics) {
|
||||||
|
if err := c.collectMetrics(ch); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("failed collecting metrics: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if slices.Contains(c.config.CollectorsEnabled, subCollectorWMIStats) {
|
||||||
|
if err := c.collectErrorStats(ch); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("failed collecting WMI statistics: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Collector) collectMetrics(ch chan<- prometheus.Metric) error {
|
||||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to collect DNS metrics: %w", err)
|
return fmt.Errorf("failed to collect DNS metrics: %w", err)
|
||||||
|
} else if len(c.perfDataObject) == 0 {
|
||||||
|
return fmt.Errorf("failed to collect DNS metrics: %w", types.ErrNoDataUnexpected)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -493,3 +600,24 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Collector) collectErrorStats(ch chan<- prometheus.Metric) error {
|
||||||
|
var stats []Statistic
|
||||||
|
if err := c.miSession.Query(&stats, mi.NamespaceRootMicrosoftDNS, c.miQuery); err != nil {
|
||||||
|
return fmt.Errorf("failed to query DNS statistics: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect DNS error statistics
|
||||||
|
for _, stat := range stats {
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.dnsWMIStats,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
float64(stat.Value),
|
||||||
|
stat.Name,
|
||||||
|
stat.CollectionName,
|
||||||
|
stat.DnsServerName,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,3 +105,11 @@ type perfDataCounterValues struct {
|
|||||||
_ float64 `perfdata:"Zone Transfer SOA Request Sent"`
|
_ float64 `perfdata:"Zone Transfer SOA Request Sent"`
|
||||||
_ float64 `perfdata:"Zone Transfer Success"`
|
_ float64 `perfdata:"Zone Transfer Success"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Statistic represents the structure for DNS error statistics
|
||||||
|
type Statistic struct {
|
||||||
|
Name string `mi:"Name"`
|
||||||
|
CollectionName string `mi:"CollectionName"`
|
||||||
|
Value uint64 `mi:"Value"`
|
||||||
|
DnsServerName string `mi:"DnsServerName"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ type perfDataCounterValuesAutoDiscover struct {
|
|||||||
func (c *Collector) buildAutoDiscover() error {
|
func (c *Collector) buildAutoDiscover() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorAutoDiscover, err = pdh.NewCollector[perfDataCounterValuesAutoDiscover](pdh.CounterTypeRaw, "MSExchange Autodiscover", pdh.InstancesAll)
|
c.perfDataCollectorAutoDiscover, err = pdh.NewCollector[perfDataCounterValuesAutoDiscover](pdh.CounterTypeRaw, "MSExchangeAutodiscover", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange Autodiscover collector: %w", err)
|
return fmt.Errorf("failed to create MSExchange Autodiscover collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type collectorAvailabilityService struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type perfDataCounterValuesAvailabilityService struct {
|
type perfDataCounterValuesAvailabilityService struct {
|
||||||
RequestsPerSec float64 `perfdata:"Requests/sec"`
|
AvailabilityRequestsPerSec float64 `perfdata:"Availability Requests (sec)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) buildAvailabilityService() error {
|
func (c *Collector) buildAvailabilityService() error {
|
||||||
@@ -43,7 +43,7 @@ func (c *Collector) buildAvailabilityService() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.availabilityRequestsSec = prometheus.NewDesc(
|
c.availabilityRequestsSec = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "avail_service_requests_per_sec"),
|
prometheus.BuildFQName(types.Namespace, Name, "availability_service_requests_per_sec"),
|
||||||
"Number of requests serviced per second",
|
"Number of requests serviced per second",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
@@ -62,7 +62,7 @@ func (c *Collector) collectAvailabilityService(ch chan<- prometheus.Metric) erro
|
|||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.availabilityRequestsSec,
|
c.availabilityRequestsSec,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
data.RequestsPerSec,
|
data.AvailabilityRequestsPerSec,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ type collectorTransportQueues struct {
|
|||||||
messagesSubmittedTotal *prometheus.Desc
|
messagesSubmittedTotal *prometheus.Desc
|
||||||
messagesDelayedTotal *prometheus.Desc
|
messagesDelayedTotal *prometheus.Desc
|
||||||
messagesCompletedDeliveryTotal *prometheus.Desc
|
messagesCompletedDeliveryTotal *prometheus.Desc
|
||||||
shadowQueueLength *prometheus.Desc
|
aggregateShadowQueueLength *prometheus.Desc
|
||||||
submissionQueueLength *prometheus.Desc
|
submissionQueueLength *prometheus.Desc
|
||||||
delayQueueLength *prometheus.Desc
|
delayQueueLength *prometheus.Desc
|
||||||
itemsCompletedDeliveryTotal *prometheus.Desc
|
itemsCompletedDeliveryTotal *prometheus.Desc
|
||||||
@@ -63,7 +63,7 @@ type perfDataCounterValuesTransportQueues struct {
|
|||||||
MessagesSubmittedTotal float64 `perfdata:"Messages Submitted Total"`
|
MessagesSubmittedTotal float64 `perfdata:"Messages Submitted Total"`
|
||||||
MessagesDelayedTotal float64 `perfdata:"Messages Delayed Total"`
|
MessagesDelayedTotal float64 `perfdata:"Messages Delayed Total"`
|
||||||
MessagesCompletedDeliveryTotal float64 `perfdata:"Messages Completed Delivery Total"`
|
MessagesCompletedDeliveryTotal float64 `perfdata:"Messages Completed Delivery Total"`
|
||||||
ShadowQueueLength float64 `perfdata:"Shadow Queue Length"`
|
AggregateShadowQueueLength float64 `perfdata:"Aggregate Shadow Queue Length"`
|
||||||
SubmissionQueueLength float64 `perfdata:"Submission Queue Length"`
|
SubmissionQueueLength float64 `perfdata:"Submission Queue Length"`
|
||||||
DelayQueueLength float64 `perfdata:"Delay Queue Length"`
|
DelayQueueLength float64 `perfdata:"Delay Queue Length"`
|
||||||
ItemsCompletedDeliveryTotal float64 `perfdata:"Items Completed Delivery Total"`
|
ItemsCompletedDeliveryTotal float64 `perfdata:"Items Completed Delivery Total"`
|
||||||
@@ -152,9 +152,9 @@ func (c *Collector) buildTransportQueues() error {
|
|||||||
[]string{"name"},
|
[]string{"name"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.shadowQueueLength = prometheus.NewDesc(
|
c.aggregateShadowQueueLength = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_shadow_queue_length"),
|
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_aggregate_shadow_queue_length"),
|
||||||
"Shadow Queue Length",
|
"The current number of messages in shadow queues.",
|
||||||
[]string{"name"},
|
[]string{"name"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
@@ -280,9 +280,9 @@ func (c *Collector) collectTransportQueues(ch chan<- prometheus.Metric) error {
|
|||||||
labelName,
|
labelName,
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.shadowQueueLength,
|
c.aggregateShadowQueueLength,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
data.ShadowQueueLength,
|
data.AggregateShadowQueueLength,
|
||||||
labelName,
|
labelName,
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ func (c *Collector) collectGlobFilePath(ch chan<- prometheus.Metric, filePattern
|
|||||||
basePath, pattern := doublestar.SplitPattern(filePattern)
|
basePath, pattern := doublestar.SplitPattern(filePattern)
|
||||||
basePathFS := os.DirFS(basePath)
|
basePathFS := os.DirFS(basePath)
|
||||||
|
|
||||||
matches, err := doublestar.Glob(basePathFS, pattern, doublestar.WithFilesOnly())
|
matches, err := doublestar.Glob(basePathFS, pattern, doublestar.WithFilesOnly(), doublestar.WithCaseInsensitive())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to glob: %w", err)
|
return fmt.Errorf("failed to glob: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -505,10 +505,6 @@ func (c *Collector) collectW3SVCW3WPv7(ch chan<- prometheus.Metric) error {
|
|||||||
deduplicateIISNames(c.perfDataObjectW3SVCW3WP)
|
deduplicateIISNames(c.perfDataObjectW3SVCW3WP)
|
||||||
|
|
||||||
for _, data := range c.perfDataObjectW3SVCW3WP {
|
for _, data := range c.perfDataObjectW3SVCW3WP {
|
||||||
if c.config.AppExclude.MatchString(data.Name) || !c.config.AppInclude.MatchString(data.Name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract the apppool name from the format <PID>_<NAME>
|
// Extract the apppool name from the format <PID>_<NAME>
|
||||||
pid := workerProcessNameExtractor.ReplaceAllString(data.Name, "$1")
|
pid := workerProcessNameExtractor.ReplaceAllString(data.Name, "$1")
|
||||||
|
|
||||||
|
|||||||
@@ -62,8 +62,6 @@ type collectorWebServiceCache struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type perfDataCounterServiceCache struct {
|
type perfDataCounterServiceCache struct {
|
||||||
Name string
|
|
||||||
|
|
||||||
ServiceCacheActiveFlushedEntries float64 `perfdata:"Active Flushed Entries"`
|
ServiceCacheActiveFlushedEntries float64 `perfdata:"Active Flushed Entries"`
|
||||||
ServiceCacheCurrentFileCacheMemoryUsage float64 `perfdata:"Current File Cache Memory Usage"`
|
ServiceCacheCurrentFileCacheMemoryUsage float64 `perfdata:"Current File Cache Memory Usage"`
|
||||||
ServiceCacheMaximumFileCacheMemoryUsage float64 `perfdata:"Maximum File Cache Memory Usage"`
|
ServiceCacheMaximumFileCacheMemoryUsage float64 `perfdata:"Maximum File Cache Memory Usage"`
|
||||||
@@ -100,10 +98,6 @@ type perfDataCounterServiceCache struct {
|
|||||||
ServiceCacheOutputCacheFlushesTotal float64 `perfdata:"Output Cache Total Flushes"`
|
ServiceCacheOutputCacheFlushesTotal float64 `perfdata:"Output Cache Total Flushes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p perfDataCounterServiceCache) GetName() string {
|
|
||||||
return p.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Collector) buildWebServiceCache() error {
|
func (c *Collector) buildWebServiceCache() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -291,13 +285,7 @@ func (c *Collector) collectWebServiceCache(ch chan<- prometheus.Metric) error {
|
|||||||
return fmt.Errorf("failed to collect Web Service Cache metrics: %w", err)
|
return fmt.Errorf("failed to collect Web Service Cache metrics: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
deduplicateIISNames(c.perfDataObjectServiceCache)
|
|
||||||
|
|
||||||
for _, data := range c.perfDataObjectServiceCache {
|
for _, data := range c.perfDataObjectServiceCache {
|
||||||
if c.config.SiteExclude.MatchString(data.Name) || !c.config.SiteInclude.MatchString(data.Name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.serviceCacheActiveFlushedEntries,
|
c.serviceCacheActiveFlushedEntries,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
|
|||||||
@@ -588,6 +588,11 @@ func getAllMountedVolumes() (map[string]string, error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if errors.Is(err, windows.ERROR_FILE_NOT_FOUND) {
|
||||||
|
// the volume is not mounted
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
if errors.Is(err, windows.ERROR_NO_MORE_FILES) {
|
if errors.Is(err, windows.ERROR_NO_MORE_FILES) {
|
||||||
rootPathBuf = make([]uint16, (rootPathLen+1)/2)
|
rootPathBuf = make([]uint16, (rootPathLen+1)/2)
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ type perfDataCounterValuesAccessMethods struct {
|
|||||||
AccessMethodsWorkfilesCreatedPerSec float64 `perfdata:"Workfiles Created/sec"`
|
AccessMethodsWorkfilesCreatedPerSec float64 `perfdata:"Workfiles Created/sec"`
|
||||||
AccessMethodsWorktablesCreatedPerSec float64 `perfdata:"Worktables Created/sec"`
|
AccessMethodsWorktablesCreatedPerSec float64 `perfdata:"Worktables Created/sec"`
|
||||||
AccessMethodsWorktablesFromCacheRatio float64 `perfdata:"Worktables From Cache Ratio"`
|
AccessMethodsWorktablesFromCacheRatio float64 `perfdata:"Worktables From Cache Ratio"`
|
||||||
AccessMethodsWorktablesFromCacheRatioBase float64 `perfdata:"Worktables From Cache Base,secondvalue"`
|
AccessMethodsWorktablesFromCacheRatioBase float64 `perfdata:"Worktables From Cache Ratio,secondvalue"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) buildAccessMethods() error {
|
func (c *Collector) buildAccessMethods() error {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ type collectorBufferManager struct {
|
|||||||
type perfDataCounterValuesBufMan struct {
|
type perfDataCounterValuesBufMan struct {
|
||||||
BufManBackgroundWriterPagesPerSec float64 `perfdata:"Background writer pages/sec"`
|
BufManBackgroundWriterPagesPerSec float64 `perfdata:"Background writer pages/sec"`
|
||||||
BufManBufferCacheHitRatio float64 `perfdata:"Buffer cache hit ratio"`
|
BufManBufferCacheHitRatio float64 `perfdata:"Buffer cache hit ratio"`
|
||||||
BufManBufferCacheHitRatioBase float64 `perfdata:"Buffer cache hit ratio base,secondvalue"`
|
BufManBufferCacheHitRatioBase float64 `perfdata:"Buffer cache hit ratio,secondvalue"`
|
||||||
BufManCheckpointPagesPerSec float64 `perfdata:"Checkpoint pages/sec"`
|
BufManCheckpointPagesPerSec float64 `perfdata:"Checkpoint pages/sec"`
|
||||||
BufManDatabasePages float64 `perfdata:"Database pages"`
|
BufManDatabasePages float64 `perfdata:"Database pages"`
|
||||||
BufManExtensionAllocatedPages float64 `perfdata:"Extension allocated pages"`
|
BufManExtensionAllocatedPages float64 `perfdata:"Extension allocated pages"`
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ type perfDataCounterValuesDatabases struct {
|
|||||||
DatabasesGroupCommitTimePerSec float64 `perfdata:"Group Commit Time/sec"`
|
DatabasesGroupCommitTimePerSec float64 `perfdata:"Group Commit Time/sec"`
|
||||||
DatabasesLogBytesFlushedPerSec float64 `perfdata:"Log Bytes Flushed/sec"`
|
DatabasesLogBytesFlushedPerSec float64 `perfdata:"Log Bytes Flushed/sec"`
|
||||||
DatabasesLogCacheHitRatio float64 `perfdata:"Log Cache Hit Ratio"`
|
DatabasesLogCacheHitRatio float64 `perfdata:"Log Cache Hit Ratio"`
|
||||||
DatabasesLogCacheHitRatioBase float64 `perfdata:"Log Cache Hit Ratio Base,secondvalue"`
|
DatabasesLogCacheHitRatioBase float64 `perfdata:"Log Cache Hit Ratio,secondvalue"`
|
||||||
DatabasesLogCacheReadsPerSec float64 `perfdata:"Log Cache Reads/sec"`
|
DatabasesLogCacheReadsPerSec float64 `perfdata:"Log Cache Reads/sec"`
|
||||||
DatabasesLogFilesSizeKB float64 `perfdata:"Log File(s) Size (KB)"`
|
DatabasesLogFilesSizeKB float64 `perfdata:"Log File(s) Size (KB)"`
|
||||||
DatabasesLogFilesUsedSizeKB float64 `perfdata:"Log File(s) Used Size (KB)"`
|
DatabasesLogFilesUsedSizeKB float64 `perfdata:"Log File(s) Used Size (KB)"`
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ type perfDataCounterValuesLocks struct {
|
|||||||
Name string
|
Name string
|
||||||
|
|
||||||
LocksAverageWaitTimeMS float64 `perfdata:"Average Wait Time (ms)"`
|
LocksAverageWaitTimeMS float64 `perfdata:"Average Wait Time (ms)"`
|
||||||
LocksAverageWaitTimeMSBase float64 `perfdata:"Average Wait Time Base,secondvalue"`
|
LocksAverageWaitTimeMSBase float64 `perfdata:"Average Wait Time (ms),secondvalue"`
|
||||||
LocksLockRequestsPerSec float64 `perfdata:"Lock Requests/sec"`
|
LocksLockRequestsPerSec float64 `perfdata:"Lock Requests/sec"`
|
||||||
LocksLockTimeoutsPerSec float64 `perfdata:"Lock Timeouts/sec"`
|
LocksLockTimeoutsPerSec float64 `perfdata:"Lock Timeouts/sec"`
|
||||||
LocksLockTimeoutsTimeout0PerSec float64 `perfdata:"Lock Timeouts (timeout > 0)/sec"`
|
LocksLockTimeoutsTimeout0PerSec float64 `perfdata:"Lock Timeouts (timeout > 0)/sec"`
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func newMssqlInstance(key, name string) (mssqlInstance, error) {
|
|||||||
_ = key.Close()
|
_ = key.Close()
|
||||||
}(k)
|
}(k)
|
||||||
|
|
||||||
patchVersion, _, err := k.GetStringValue("Version")
|
patchVersion, _, err := k.GetStringValue("PatchLevel")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mssqlInstance{}, fmt.Errorf("couldn't get version from registry: %w", err)
|
return mssqlInstance{}, fmt.Errorf("couldn't get version from registry: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/headers/kernel32"
|
"github.com/prometheus-community/windows_exporter/internal/headers/kernel32"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/headers/netapi32"
|
"github.com/prometheus-community/windows_exporter/internal/headers/netapi32"
|
||||||
|
"github.com/prometheus-community/windows_exporter/internal/headers/psapi"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/headers/sysinfoapi"
|
"github.com/prometheus-community/windows_exporter/internal/headers/sysinfoapi"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||||
@@ -48,7 +49,9 @@ type Collector struct {
|
|||||||
hostname *prometheus.Desc
|
hostname *prometheus.Desc
|
||||||
osInformation *prometheus.Desc
|
osInformation *prometheus.Desc
|
||||||
|
|
||||||
// users
|
// Deprecated: Use windows_system_processes instead.
|
||||||
|
processes *prometheus.Desc
|
||||||
|
|
||||||
// Deprecated: Use windows_system_process_limit instead.
|
// Deprecated: Use windows_system_process_limit instead.
|
||||||
processesLimit *prometheus.Desc
|
processesLimit *prometheus.Desc
|
||||||
|
|
||||||
@@ -166,6 +169,12 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
|||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
c.processes = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "processes"),
|
||||||
|
"Deprecated: Use `windows_system_processes` instead.",
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
c.processesLimit = prometheus.NewDesc(
|
c.processesLimit = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "processes_limit"),
|
prometheus.BuildFQName(types.Namespace, Name, "processes_limit"),
|
||||||
"Deprecated: Use `windows_system_process_limit` instead.",
|
"Deprecated: Use `windows_system_process_limit` instead.",
|
||||||
@@ -213,6 +222,10 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
|
|
||||||
c.collect(ch)
|
c.collect(ch)
|
||||||
|
|
||||||
|
if err := c.collectProcessCount(ch); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("failed to collect process count metrics: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
if err := c.collectHostname(ch); err != nil {
|
if err := c.collectHostname(ch); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to collect hostname metrics: %w", err))
|
errs = append(errs, fmt.Errorf("failed to collect hostname metrics: %w", err))
|
||||||
}
|
}
|
||||||
@@ -275,6 +288,20 @@ func (c *Collector) collectHostname(ch chan<- prometheus.Metric) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Collector) collectProcessCount(ch chan<- prometheus.Metric) error {
|
||||||
|
gpi, err := psapi.GetPerformanceInfo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(c.processes,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(gpi.ProcessCount),
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Collector) collectTime(ch chan<- prometheus.Metric) error {
|
func (c *Collector) collectTime(ch chan<- prometheus.Metric) error {
|
||||||
timeZoneInfo, err := kernel32.GetDynamicTimeZoneInformation()
|
timeZoneInfo, err := kernel32.GetDynamicTimeZoneInformation()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ func getScheduledTasks() (ScheduledTasks, error) {
|
|||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
if err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil {
|
if err := ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED|ole.COINIT_DISABLE_OLE1DDE); err != nil {
|
||||||
var oleCode *ole.OleError
|
var oleCode *ole.OleError
|
||||||
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != S_FALSE {
|
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != S_FALSE {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
c.queryAllServicesBuffer = make([]byte, 1024*100)
|
c.queryAllServicesBuffer = make([]byte, 1024*200)
|
||||||
|
|
||||||
c.info = prometheus.NewDesc(
|
c.info = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||||
@@ -240,6 +240,15 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) collectWorker(ch chan<- prometheus.Metric, service windows.ENUM_SERVICE_STATUS_PROCESS) {
|
func (c *Collector) collectWorker(ch chan<- prometheus.Metric, service windows.ENUM_SERVICE_STATUS_PROCESS) {
|
||||||
|
if uintptr(unsafe.Pointer(service.ServiceName)) == uintptr(windows.InvalidHandle) {
|
||||||
|
c.logger.Log(context.Background(), slog.LevelWarn, "failed collecting service info",
|
||||||
|
slog.String("err", "ServiceName is 0xffffffffffffffff"),
|
||||||
|
slog.String("service", fmt.Sprintf("%+v", service)),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
serviceName := windows.UTF16PtrToString(service.ServiceName)
|
serviceName := windows.UTF16PtrToString(service.ServiceName)
|
||||||
|
|
||||||
if c.config.ServiceExclude.MatchString(serviceName) || !c.config.ServiceInclude.MatchString(serviceName) {
|
if c.config.ServiceExclude.MatchString(serviceName) || !c.config.ServiceInclude.MatchString(serviceName) {
|
||||||
@@ -350,7 +359,9 @@ func (c *Collector) collectService(ch chan<- prometheus.Metric, serviceName stri
|
|||||||
|
|
||||||
logLevel := slog.LevelWarn
|
logLevel := slog.LevelWarn
|
||||||
|
|
||||||
if errors.Is(err, windows.ERROR_ACCESS_DENIED) {
|
// ERROR_INVALID_PARAMETER returns when the process is not running. This can be happened
|
||||||
|
// if the service terminated after query the service API.
|
||||||
|
if errors.Is(err, windows.ERROR_ACCESS_DENIED) || errors.Is(err, windows.ERROR_INVALID_PARAMETER) {
|
||||||
logLevel = slog.LevelDebug
|
logLevel = slog.LevelDebug
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,6 +382,8 @@ func (c *Collector) queryAllServices() ([]windows.ENUM_SERVICE_STATUS_PROCESS, e
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
clear(c.queryAllServicesBuffer)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
currentBufferSize := uint32(cap(c.queryAllServicesBuffer))
|
currentBufferSize := uint32(cap(c.queryAllServicesBuffer))
|
||||||
|
|
||||||
@@ -420,15 +433,6 @@ func (c *Collector) getProcessStartTime(pid uint32) (uint64, error) {
|
|||||||
return 0, fmt.Errorf("failed to open process %w", err)
|
return 0, fmt.Errorf("failed to open process %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func(handle windows.Handle) {
|
|
||||||
err := windows.CloseHandle(handle)
|
|
||||||
if err != nil {
|
|
||||||
c.logger.Warn("failed to close process handle",
|
|
||||||
slog.Any("err", err),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}(handle)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
creation windows.Filetime
|
creation windows.Filetime
|
||||||
exit windows.Filetime
|
exit windows.Filetime
|
||||||
@@ -437,6 +441,14 @@ func (c *Collector) getProcessStartTime(pid uint32) (uint64, error) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
err = windows.GetProcessTimes(handle, &creation, &exit, &krn, &user)
|
err = windows.GetProcessTimes(handle, &creation, &exit, &krn, &user)
|
||||||
|
|
||||||
|
if err := windows.CloseHandle(handle); err != nil {
|
||||||
|
c.logger.LogAttrs(context.Background(), slog.LevelWarn, "failed to close process handle",
|
||||||
|
slog.Any("err", err),
|
||||||
|
slog.Uint64("pid", uint64(pid)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("failed to get process times %w", err)
|
return 0, fmt.Errorf("failed to get process times %w", err)
|
||||||
}
|
}
|
||||||
@@ -477,7 +489,7 @@ func (c *Collector) getServiceConfig(service *mgr.Service) (mgr.Config, error) {
|
|||||||
*buf = make([]byte, bytesNeeded)
|
*buf = make([]byte, bytesNeeded)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.serviceConfigPoolBytes.Put(buf)
|
defer c.serviceConfigPoolBytes.Put(buf)
|
||||||
|
|
||||||
return mgr.Config{
|
return mgr.Config{
|
||||||
BinaryPathName: windows.UTF16PtrToString(serviceConfig.BinaryPathName),
|
BinaryPathName: windows.UTF16PtrToString(serviceConfig.BinaryPathName),
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to collect System metrics: %w", err)
|
return fmt.Errorf("failed to collect System metrics: %w", err)
|
||||||
|
} else if len(c.perfDataObject) == 0 {
|
||||||
|
return fmt.Errorf("failed to collect System metrics: %w", types.ErrNoDataUnexpected)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
|||||||
@@ -437,7 +437,7 @@ func (c *Collector) collectWTSSessions(ch chan<- prometheus.Metric) error {
|
|||||||
for _, session := range sessions {
|
for _, session := range sessions {
|
||||||
// only connect metrics for remote named sessions
|
// only connect metrics for remote named sessions
|
||||||
n := strings.ReplaceAll(session.SessionName, "#", " ")
|
n := strings.ReplaceAll(session.SessionName, "#", " ")
|
||||||
if n == "" || n == "Services" {
|
if n == "Services" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,9 @@ func (c *Collector) collectTime(ch chan<- prometheus.Metric) error {
|
|||||||
func (c *Collector) collectNTP(ch chan<- prometheus.Metric) error {
|
func (c *Collector) collectNTP(ch chan<- prometheus.Metric) error {
|
||||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to collect time metrics: %w", err)
|
return fmt.Errorf("failed to collect Windows Time Service metrics: %w", err)
|
||||||
|
} else if len(c.perfDataObject) == 0 {
|
||||||
|
return fmt.Errorf("failed to collect Windows Time Service metrics: %w", types.ErrNoDataUnexpected)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
|||||||
@@ -37,14 +37,14 @@ import (
|
|||||||
const Name = "update"
|
const Name = "update"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
online bool `yaml:"online"`
|
Online bool `yaml:"online"`
|
||||||
scrapeInterval time.Duration `yaml:"scrape_interval"`
|
ScrapeInterval time.Duration `yaml:"scrape_interval"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
var ConfigDefaults = Config{
|
var ConfigDefaults = Config{
|
||||||
online: false,
|
Online: false,
|
||||||
scrapeInterval: 6 * time.Hour,
|
ScrapeInterval: 6 * time.Hour,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -85,12 +85,12 @@ func NewWithFlags(app *kingpin.Application) *Collector {
|
|||||||
app.Flag(
|
app.Flag(
|
||||||
"collector.updates.online",
|
"collector.updates.online",
|
||||||
"Whether to search for updates online.",
|
"Whether to search for updates online.",
|
||||||
).Default(strconv.FormatBool(ConfigDefaults.online)).BoolVar(&c.config.online)
|
).Default(strconv.FormatBool(ConfigDefaults.Online)).BoolVar(&c.config.Online)
|
||||||
|
|
||||||
app.Flag(
|
app.Flag(
|
||||||
"collector.updates.scrape-interval",
|
"collector.updates.scrape-interval",
|
||||||
"Define the interval of scraping Windows Update information.",
|
"Define the interval of scraping Windows Update information.",
|
||||||
).Default(ConfigDefaults.scrapeInterval.String()).DurationVar(&c.config.scrapeInterval)
|
).Default(ConfigDefaults.ScrapeInterval.String()).DurationVar(&c.config.ScrapeInterval)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
initErrCh := make(chan error, 1)
|
initErrCh := make(chan error, 1)
|
||||||
go c.scheduleUpdateStatus(ctx, logger, initErrCh, c.config.online)
|
go c.scheduleUpdateStatus(ctx, logger, initErrCh, c.config.Online)
|
||||||
|
|
||||||
c.ctxCancelFn = cancel
|
c.ctxCancelFn = cancel
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ func (c *Collector) scheduleUpdateStatus(ctx context.Context, logger *slog.Logge
|
|||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
if err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil {
|
if err := ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED|ole.COINIT_DISABLE_OLE1DDE); err != nil {
|
||||||
var oleCode *ole.OleError
|
var oleCode *ole.OleError
|
||||||
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != 0x00000001 {
|
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != 0x00000001 {
|
||||||
initErrCh <- fmt.Errorf("CoInitializeEx: %w", err)
|
initErrCh <- fmt.Errorf("CoInitializeEx: %w", err)
|
||||||
@@ -178,17 +178,17 @@ func (c *Collector) scheduleUpdateStatus(ctx context.Context, logger *slog.Logge
|
|||||||
defer ole.CoUninitialize()
|
defer ole.CoUninitialize()
|
||||||
|
|
||||||
// Create a new instance of the WMI object
|
// Create a new instance of the WMI object
|
||||||
mus, err := oleutil.CreateObject("Microsoft.Update.Session")
|
sessionObj, err := oleutil.CreateObject("Microsoft.Update.Session")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
initErrCh <- fmt.Errorf("create Microsoft.Update.Session: %w", err)
|
initErrCh <- fmt.Errorf("create Microsoft.Update.Session: %w", err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
defer mus.Release()
|
defer sessionObj.Release()
|
||||||
|
|
||||||
// Query the IDispatch interface of the object
|
// Query the IDispatch interface of the object
|
||||||
musQueryInterface, err := mus.QueryInterface(ole.IID_IDispatch)
|
musQueryInterface, err := sessionObj.QueryInterface(ole.IID_IDispatch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
initErrCh <- fmt.Errorf("IID_IDispatch: %w", err)
|
initErrCh <- fmt.Errorf("IID_IDispatch: %w", err)
|
||||||
|
|
||||||
@@ -206,9 +206,9 @@ func (c *Collector) scheduleUpdateStatus(ctx context.Context, logger *slog.Logge
|
|||||||
|
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesession-createupdatesearcher
|
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesession-createupdatesearcher
|
||||||
us, err := oleutil.CallMethod(musQueryInterface, "CreateUpdateSearcher")
|
us, err := oleutil.CallMethod(musQueryInterface, "CreateUpdateSearcher")
|
||||||
defer func(hc *ole.VARIANT) {
|
defer func(us *ole.VARIANT) {
|
||||||
if us != nil {
|
if us != nil {
|
||||||
_ = hc.Clear()
|
_ = us.Clear()
|
||||||
}
|
}
|
||||||
}(us)
|
}(us)
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ func (c *Collector) scheduleUpdateStatus(ctx context.Context, logger *slog.Logge
|
|||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(c.config.scrapeInterval):
|
case <-time.After(c.config.ScrapeInterval):
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func (s *ScheduleService) Connect() error {
|
|||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
if err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED|ole.COINIT_DISABLE_OLE1DDE); err != nil {
|
if err := ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED|ole.COINIT_DISABLE_OLE1DDE); err != nil {
|
||||||
var oleCode *ole.OleError
|
var oleCode *ole.OleError
|
||||||
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != 0x00000001 {
|
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != 0x00000001 {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -40,9 +40,8 @@ type MetricsHTTPHandler struct {
|
|||||||
// the exporter itself.
|
// the exporter itself.
|
||||||
exporterMetricsRegistry *prometheus.Registry
|
exporterMetricsRegistry *prometheus.Registry
|
||||||
|
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
options Options
|
options Options
|
||||||
concurrencyCh chan struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
@@ -62,9 +61,6 @@ func New(logger *slog.Logger, metricCollectors *collector.Collection, options *O
|
|||||||
metricCollectors: metricCollectors,
|
metricCollectors: metricCollectors,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
options: *options,
|
options: *options,
|
||||||
|
|
||||||
// We are expose metrics directly from the memory region of the Win32 API. We should not allow more than one request at a time.
|
|
||||||
concurrencyCh: make(chan struct{}, 1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !options.DisableExporterMetrics {
|
if !options.DisableExporterMetrics {
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ var (
|
|||||||
NamespaceRootWindowsFSRM = utils.Must(NewNamespace("root/microsoft/windows/fsrm"))
|
NamespaceRootWindowsFSRM = utils.Must(NewNamespace("root/microsoft/windows/fsrm"))
|
||||||
NamespaceRootWebAdministration = utils.Must(NewNamespace("root/WebAdministration"))
|
NamespaceRootWebAdministration = utils.Must(NewNamespace("root/WebAdministration"))
|
||||||
NamespaceRootMSCluster = utils.Must(NewNamespace("root/MSCluster"))
|
NamespaceRootMSCluster = utils.Must(NewNamespace("root/MSCluster"))
|
||||||
|
NamespaceRootMicrosoftDNS = utils.Must(NewNamespace("root/MicrosoftDNS"))
|
||||||
)
|
)
|
||||||
|
|
||||||
type Query *uint16
|
type Query *uint16
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package collector
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
@@ -26,6 +27,12 @@ import (
|
|||||||
// Interface guard.
|
// Interface guard.
|
||||||
var _ prometheus.Collector = (*Handler)(nil)
|
var _ prometheus.Collector = (*Handler)(nil)
|
||||||
|
|
||||||
|
// We are expose metrics directly from the memory region of the Win32 API.
|
||||||
|
// We should not allow more than one request at a time.
|
||||||
|
//
|
||||||
|
//nolint:gochecknoglobals
|
||||||
|
var concurrencyMu sync.Mutex
|
||||||
|
|
||||||
// Handler implements [prometheus.Collector] for a set of Windows Collection.
|
// Handler implements [prometheus.Collector] for a set of Windows Collection.
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
maxScrapeDuration time.Duration
|
maxScrapeDuration time.Duration
|
||||||
@@ -58,5 +65,7 @@ func (p *Handler) Describe(_ chan<- *prometheus.Desc) {}
|
|||||||
// Collect sends the collected metrics from each of the Collection to
|
// Collect sends the collected metrics from each of the Collection to
|
||||||
// prometheus.
|
// prometheus.
|
||||||
func (p *Handler) Collect(ch chan<- prometheus.Metric) {
|
func (p *Handler) Collect(ch chan<- prometheus.Metric) {
|
||||||
|
concurrencyMu.Lock()
|
||||||
p.collection.collectAll(ch, p.logger, p.maxScrapeDuration)
|
p.collection.collectAll(ch, p.logger, p.maxScrapeDuration)
|
||||||
|
concurrencyMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -301,6 +301,8 @@ windows_exporter_collector_timeout{collector="udp"} 0
|
|||||||
# TYPE windows_os_physical_memory_free_bytes gauge
|
# TYPE windows_os_physical_memory_free_bytes gauge
|
||||||
# HELP windows_os_process_memory_limit_bytes Deprecated: Use `windows_memory_process_memory_limit_bytes` instead.
|
# HELP windows_os_process_memory_limit_bytes Deprecated: Use `windows_memory_process_memory_limit_bytes` instead.
|
||||||
# TYPE windows_os_process_memory_limit_bytes gauge
|
# TYPE windows_os_process_memory_limit_bytes gauge
|
||||||
|
# HELP windows_os_processes Deprecated: Use `windows_system_processes` instead.
|
||||||
|
# TYPE windows_os_processes gauge
|
||||||
# HELP windows_os_processes_limit Deprecated: Use `windows_system_process_limit` instead.
|
# HELP windows_os_processes_limit Deprecated: Use `windows_system_process_limit` instead.
|
||||||
# TYPE windows_os_processes_limit gauge
|
# TYPE windows_os_processes_limit gauge
|
||||||
# HELP windows_os_time Deprecated: Use windows_time_current_timestamp_seconds instead.
|
# HELP windows_os_time Deprecated: Use windows_time_current_timestamp_seconds instead.
|
||||||
|
|||||||
Reference in New Issue
Block a user