mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-08 05:56:37 +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:
|
||||
test:
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
run: make e2e-test
|
||||
|
||||
promtool:
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- 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
|
||||
run: |
|
||||
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
|
||||
fi
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ var (
|
||||
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 = make(chan struct{})
|
||||
serviceManagerFinishedCh = make(chan struct{}, 1)
|
||||
)
|
||||
|
||||
// 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
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `dns`
|
||||
Classes | [`Win32_PerfRawData_DNS_DNS`](https://technet.microsoft.com/en-us/library/cc977686.aspx)
|
||||
Enabled by default? | No
|
||||
-|-|-
|
||||
Metric name prefix | `dns` |
|
||||
Classes | [`Win32_PerfRawData_DNS_DNS`](https://technet.microsoft.com/en-us/library/cc977686.aspx) |
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@@ -38,12 +43,56 @@ Name | Description | Type | Labels
|
||||
`windows_dns_wins_queries_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_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
|
||||
_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
|
||||
_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!_
|
||||
_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_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_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_delay_queue_length` | Delay Queue Length |
|
||||
| `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_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_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_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 |
|
||||
@@ -77,4 +77,3 @@ _This collector does not yet have any useful queries added, we would appreciate
|
||||
|
||||
## Alerting examples
|
||||
_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 (
|
||||
github.com/Microsoft/hcsshim v0.12.9
|
||||
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/go-ole/go-ole v1.3.0
|
||||
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/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.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
|
||||
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bmatcuk/doublestar/v4 v4.9.0 h1:DBvuZxjdKkRP/dr4GVV4w2fnmrk5Hxc90T51LZjv0JA=
|
||||
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/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
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/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/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/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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
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-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.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/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.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/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
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-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.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/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
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-20220715151400-c0bba94af5f8/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/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
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.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/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
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-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-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/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
||||
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.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
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/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
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)
|
||||
if err != nil {
|
||||
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(
|
||||
|
||||
@@ -385,6 +385,8 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||
if err != nil {
|
||||
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(
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
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(
|
||||
|
||||
@@ -403,6 +403,8 @@ func (c *Collector) collectServerMetrics(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)
|
||||
} else if len(c.perfDataObject) == 0 {
|
||||
return fmt.Errorf("failed to collect DHCP Server metrics: %w", types.ErrNoDataUnexpected)
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
|
||||
@@ -36,7 +36,9 @@ var ConfigDefaults = Config{}
|
||||
|
||||
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_DiskDrive.
|
||||
type Collector struct {
|
||||
config Config
|
||||
config Config
|
||||
logger *slog.Logger
|
||||
|
||||
miSession *mi.Session
|
||||
miQuery mi.Query
|
||||
|
||||
@@ -71,7 +73,9 @@ func (c *Collector) Close() error {
|
||||
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(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||
"General drive information",
|
||||
@@ -146,7 +150,7 @@ var (
|
||||
"Error",
|
||||
"Degraded",
|
||||
"Unknown",
|
||||
"Pred fail",
|
||||
"Pred Fail",
|
||||
"Starting",
|
||||
"Stopping",
|
||||
"Service",
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
@@ -26,12 +29,23 @@ import (
|
||||
"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
|
||||
var ConfigDefaults = Config{}
|
||||
var ConfigDefaults = Config{
|
||||
CollectorsEnabled: []string{
|
||||
subCollectorMetrics,
|
||||
subCollectorWMIStats,
|
||||
},
|
||||
}
|
||||
|
||||
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics.
|
||||
type Collector struct {
|
||||
@@ -40,6 +54,9 @@ type Collector struct {
|
||||
perfDataCollector *pdh.Collector
|
||||
perfDataObject []perfDataCounterValues
|
||||
|
||||
miSession *mi.Session
|
||||
miQuery mi.Query
|
||||
|
||||
dynamicUpdatesFailures *prometheus.Desc
|
||||
dynamicUpdatesQueued *prometheus.Desc
|
||||
dynamicUpdatesReceived *prometheus.Desc
|
||||
@@ -62,6 +79,7 @@ type Collector struct {
|
||||
zoneTransferResponsesReceived *prometheus.Desc
|
||||
zoneTransferSuccessReceived *prometheus.Desc
|
||||
zoneTransferSuccessSent *prometheus.Desc
|
||||
dnsWMIStats *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
@@ -69,6 +87,10 @@ func New(config *Config) *Collector {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
if config.CollectorsEnabled == nil {
|
||||
config.CollectorsEnabled = ConfigDefaults.CollectorsEnabled
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
@@ -76,8 +98,26 @@ func New(config *Config) *Collector {
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(_ *kingpin.Application) *Collector {
|
||||
return &Collector{}
|
||||
func NewWithFlags(app *kingpin.Application) *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 {
|
||||
@@ -90,7 +130,31 @@ func (c *Collector) Close() error {
|
||||
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(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_received_total"),
|
||||
"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,
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
// to the provided prometheus Metric channel.
|
||||
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)
|
||||
if err != nil {
|
||||
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(
|
||||
@@ -493,3 +600,24 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
|
||||
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 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 {
|
||||
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 {
|
||||
return fmt.Errorf("failed to create MSExchange Autodiscover collector: %w", err)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ type collectorAvailabilityService struct {
|
||||
}
|
||||
|
||||
type perfDataCounterValuesAvailabilityService struct {
|
||||
RequestsPerSec float64 `perfdata:"Requests/sec"`
|
||||
AvailabilityRequestsPerSec float64 `perfdata:"Availability Requests (sec)"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildAvailabilityService() error {
|
||||
@@ -43,7 +43,7 @@ func (c *Collector) buildAvailabilityService() error {
|
||||
}
|
||||
|
||||
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",
|
||||
nil,
|
||||
nil,
|
||||
@@ -62,7 +62,7 @@ func (c *Collector) collectAvailabilityService(ch chan<- prometheus.Metric) erro
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.availabilityRequestsSec,
|
||||
prometheus.CounterValue,
|
||||
data.RequestsPerSec,
|
||||
data.AvailabilityRequestsPerSec,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ type collectorTransportQueues struct {
|
||||
messagesSubmittedTotal *prometheus.Desc
|
||||
messagesDelayedTotal *prometheus.Desc
|
||||
messagesCompletedDeliveryTotal *prometheus.Desc
|
||||
shadowQueueLength *prometheus.Desc
|
||||
aggregateShadowQueueLength *prometheus.Desc
|
||||
submissionQueueLength *prometheus.Desc
|
||||
delayQueueLength *prometheus.Desc
|
||||
itemsCompletedDeliveryTotal *prometheus.Desc
|
||||
@@ -63,7 +63,7 @@ type perfDataCounterValuesTransportQueues struct {
|
||||
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"`
|
||||
AggregateShadowQueueLength float64 `perfdata:"Aggregate Shadow Queue Length"`
|
||||
SubmissionQueueLength float64 `perfdata:"Submission Queue Length"`
|
||||
DelayQueueLength float64 `perfdata:"Delay Queue Length"`
|
||||
ItemsCompletedDeliveryTotal float64 `perfdata:"Items Completed Delivery Total"`
|
||||
@@ -152,9 +152,9 @@ func (c *Collector) buildTransportQueues() error {
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
c.shadowQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_shadow_queue_length"),
|
||||
"Shadow Queue Length",
|
||||
c.aggregateShadowQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_aggregate_shadow_queue_length"),
|
||||
"The current number of messages in shadow queues.",
|
||||
[]string{"name"},
|
||||
nil,
|
||||
)
|
||||
@@ -280,9 +280,9 @@ func (c *Collector) collectTransportQueues(ch chan<- prometheus.Metric) error {
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.shadowQueueLength,
|
||||
c.aggregateShadowQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data.ShadowQueueLength,
|
||||
data.AggregateShadowQueueLength,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
|
||||
@@ -149,7 +149,7 @@ func (c *Collector) collectGlobFilePath(ch chan<- prometheus.Metric, filePattern
|
||||
basePath, pattern := doublestar.SplitPattern(filePattern)
|
||||
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 {
|
||||
return fmt.Errorf("failed to glob: %w", err)
|
||||
}
|
||||
|
||||
@@ -505,10 +505,6 @@ func (c *Collector) collectW3SVCW3WPv7(ch chan<- prometheus.Metric) error {
|
||||
deduplicateIISNames(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>
|
||||
pid := workerProcessNameExtractor.ReplaceAllString(data.Name, "$1")
|
||||
|
||||
|
||||
@@ -62,8 +62,6 @@ type collectorWebServiceCache struct {
|
||||
}
|
||||
|
||||
type perfDataCounterServiceCache struct {
|
||||
Name string
|
||||
|
||||
ServiceCacheActiveFlushedEntries float64 `perfdata:"Active Flushed Entries"`
|
||||
ServiceCacheCurrentFileCacheMemoryUsage float64 `perfdata:"Current 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"`
|
||||
}
|
||||
|
||||
func (p perfDataCounterServiceCache) GetName() string {
|
||||
return p.Name
|
||||
}
|
||||
|
||||
func (c *Collector) buildWebServiceCache() 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)
|
||||
}
|
||||
|
||||
deduplicateIISNames(c.perfDataObjectServiceCache)
|
||||
|
||||
for _, data := range c.perfDataObjectServiceCache {
|
||||
if c.config.SiteExclude.MatchString(data.Name) || !c.config.SiteInclude.MatchString(data.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheActiveFlushedEntries,
|
||||
prometheus.GaugeValue,
|
||||
|
||||
@@ -588,6 +588,11 @@ func getAllMountedVolumes() (map[string]string, error) {
|
||||
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) {
|
||||
rootPathBuf = make([]uint16, (rootPathLen+1)/2)
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ type perfDataCounterValuesAccessMethods struct {
|
||||
AccessMethodsWorkfilesCreatedPerSec float64 `perfdata:"Workfiles Created/sec"`
|
||||
AccessMethodsWorktablesCreatedPerSec float64 `perfdata:"Worktables Created/sec"`
|
||||
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 {
|
||||
|
||||
@@ -56,7 +56,7 @@ type collectorBufferManager struct {
|
||||
type perfDataCounterValuesBufMan struct {
|
||||
BufManBackgroundWriterPagesPerSec float64 `perfdata:"Background writer pages/sec"`
|
||||
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"`
|
||||
BufManDatabasePages float64 `perfdata:"Database pages"`
|
||||
BufManExtensionAllocatedPages float64 `perfdata:"Extension allocated pages"`
|
||||
|
||||
@@ -93,7 +93,7 @@ type perfDataCounterValuesDatabases struct {
|
||||
DatabasesGroupCommitTimePerSec float64 `perfdata:"Group Commit Time/sec"`
|
||||
DatabasesLogBytesFlushedPerSec float64 `perfdata:"Log Bytes Flushed/sec"`
|
||||
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"`
|
||||
DatabasesLogFilesSizeKB float64 `perfdata:"Log File(s) Size (KB)"`
|
||||
DatabasesLogFilesUsedSizeKB float64 `perfdata:"Log File(s) Used Size (KB)"`
|
||||
|
||||
@@ -43,7 +43,7 @@ type perfDataCounterValuesLocks struct {
|
||||
Name string
|
||||
|
||||
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"`
|
||||
LocksLockTimeoutsPerSec float64 `perfdata:"Lock Timeouts/sec"`
|
||||
LocksLockTimeoutsTimeout0PerSec float64 `perfdata:"Lock Timeouts (timeout > 0)/sec"`
|
||||
|
||||
@@ -27,7 +27,7 @@ func newMssqlInstance(key, name string) (mssqlInstance, error) {
|
||||
_ = key.Close()
|
||||
}(k)
|
||||
|
||||
patchVersion, _, err := k.GetStringValue("Version")
|
||||
patchVersion, _, err := k.GetStringValue("PatchLevel")
|
||||
if err != nil {
|
||||
return mssqlInstance{}, fmt.Errorf("couldn't get version from registry: %w", err)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"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/psapi"
|
||||
"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"
|
||||
@@ -48,7 +49,9 @@ type Collector struct {
|
||||
hostname *prometheus.Desc
|
||||
osInformation *prometheus.Desc
|
||||
|
||||
// users
|
||||
// Deprecated: Use windows_system_processes instead.
|
||||
processes *prometheus.Desc
|
||||
|
||||
// Deprecated: Use windows_system_process_limit instead.
|
||||
processesLimit *prometheus.Desc
|
||||
|
||||
@@ -166,6 +169,12 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.processes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "processes"),
|
||||
"Deprecated: Use `windows_system_processes` instead.",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.processesLimit = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "processes_limit"),
|
||||
"Deprecated: Use `windows_system_process_limit` instead.",
|
||||
@@ -213,6 +222,10 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
timeZoneInfo, err := kernel32.GetDynamicTimeZoneInformation()
|
||||
if err != nil {
|
||||
|
||||
@@ -248,7 +248,7 @@ func getScheduledTasks() (ScheduledTasks, error) {
|
||||
runtime.LockOSThread()
|
||||
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
|
||||
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != S_FALSE {
|
||||
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(
|
||||
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) {
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -371,6 +382,8 @@ func (c *Collector) queryAllServices() ([]windows.ENUM_SERVICE_STATUS_PROCESS, e
|
||||
err error
|
||||
)
|
||||
|
||||
clear(c.queryAllServicesBuffer)
|
||||
|
||||
for {
|
||||
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)
|
||||
}
|
||||
|
||||
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 (
|
||||
creation 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)
|
||||
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
c.serviceConfigPoolBytes.Put(buf)
|
||||
defer c.serviceConfigPoolBytes.Put(buf)
|
||||
|
||||
return mgr.Config{
|
||||
BinaryPathName: windows.UTF16PtrToString(serviceConfig.BinaryPathName),
|
||||
|
||||
@@ -157,6 +157,8 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||
if err != nil {
|
||||
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(
|
||||
|
||||
@@ -437,7 +437,7 @@ func (c *Collector) collectWTSSessions(ch chan<- prometheus.Metric) error {
|
||||
for _, session := range sessions {
|
||||
// only connect metrics for remote named sessions
|
||||
n := strings.ReplaceAll(session.SessionName, "#", " ")
|
||||
if n == "" || n == "Services" {
|
||||
if n == "Services" {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -245,7 +245,9 @@ func (c *Collector) collectTime(ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collectNTP(ch chan<- prometheus.Metric) error {
|
||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||
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(
|
||||
|
||||
@@ -37,14 +37,14 @@ import (
|
||||
const Name = "update"
|
||||
|
||||
type Config struct {
|
||||
online bool `yaml:"online"`
|
||||
scrapeInterval time.Duration `yaml:"scrape_interval"`
|
||||
Online bool `yaml:"online"`
|
||||
ScrapeInterval time.Duration `yaml:"scrape_interval"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var ConfigDefaults = Config{
|
||||
online: false,
|
||||
scrapeInterval: 6 * time.Hour,
|
||||
Online: false,
|
||||
ScrapeInterval: 6 * time.Hour,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -85,12 +85,12 @@ func NewWithFlags(app *kingpin.Application) *Collector {
|
||||
app.Flag(
|
||||
"collector.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(
|
||||
"collector.updates.scrape-interval",
|
||||
"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
|
||||
}
|
||||
@@ -109,7 +109,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
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
|
||||
|
||||
@@ -166,7 +166,7 @@ func (c *Collector) scheduleUpdateStatus(ctx context.Context, logger *slog.Logge
|
||||
runtime.LockOSThread()
|
||||
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
|
||||
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != 0x00000001 {
|
||||
initErrCh <- fmt.Errorf("CoInitializeEx: %w", err)
|
||||
@@ -178,17 +178,17 @@ func (c *Collector) scheduleUpdateStatus(ctx context.Context, logger *slog.Logge
|
||||
defer ole.CoUninitialize()
|
||||
|
||||
// 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 {
|
||||
initErrCh <- fmt.Errorf("create Microsoft.Update.Session: %w", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
defer mus.Release()
|
||||
defer sessionObj.Release()
|
||||
|
||||
// Query the IDispatch interface of the object
|
||||
musQueryInterface, err := mus.QueryInterface(ole.IID_IDispatch)
|
||||
musQueryInterface, err := sessionObj.QueryInterface(ole.IID_IDispatch)
|
||||
if err != nil {
|
||||
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
|
||||
us, err := oleutil.CallMethod(musQueryInterface, "CreateUpdateSearcher")
|
||||
defer func(hc *ole.VARIANT) {
|
||||
defer func(us *ole.VARIANT) {
|
||||
if us != nil {
|
||||
_ = hc.Clear()
|
||||
_ = us.Clear()
|
||||
}
|
||||
}(us)
|
||||
|
||||
@@ -268,7 +268,7 @@ func (c *Collector) scheduleUpdateStatus(ctx context.Context, logger *slog.Logge
|
||||
c.mu.Unlock()
|
||||
|
||||
select {
|
||||
case <-time.After(c.config.scrapeInterval):
|
||||
case <-time.After(c.config.ScrapeInterval):
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func (s *ScheduleService) Connect() error {
|
||||
runtime.LockOSThread()
|
||||
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
|
||||
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != 0x00000001 {
|
||||
return err
|
||||
|
||||
@@ -40,9 +40,8 @@ type MetricsHTTPHandler struct {
|
||||
// the exporter itself.
|
||||
exporterMetricsRegistry *prometheus.Registry
|
||||
|
||||
logger *slog.Logger
|
||||
options Options
|
||||
concurrencyCh chan struct{}
|
||||
logger *slog.Logger
|
||||
options Options
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
@@ -62,9 +61,6 @@ func New(logger *slog.Logger, metricCollectors *collector.Collection, options *O
|
||||
metricCollectors: metricCollectors,
|
||||
logger: logger,
|
||||
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 {
|
||||
|
||||
@@ -51,6 +51,7 @@ var (
|
||||
NamespaceRootWindowsFSRM = utils.Must(NewNamespace("root/microsoft/windows/fsrm"))
|
||||
NamespaceRootWebAdministration = utils.Must(NewNamespace("root/WebAdministration"))
|
||||
NamespaceRootMSCluster = utils.Must(NewNamespace("root/MSCluster"))
|
||||
NamespaceRootMicrosoftDNS = utils.Must(NewNamespace("root/MicrosoftDNS"))
|
||||
)
|
||||
|
||||
type Query *uint16
|
||||
|
||||
@@ -18,6 +18,7 @@ package collector
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@@ -26,6 +27,12 @@ import (
|
||||
// Interface guard.
|
||||
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.
|
||||
type Handler struct {
|
||||
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
|
||||
// prometheus.
|
||||
func (p *Handler) Collect(ch chan<- prometheus.Metric) {
|
||||
concurrencyMu.Lock()
|
||||
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
|
||||
# HELP windows_os_process_memory_limit_bytes Deprecated: Use `windows_memory_process_memory_limit_bytes` instead.
|
||||
# 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.
|
||||
# TYPE windows_os_processes_limit gauge
|
||||
# HELP windows_os_time Deprecated: Use windows_time_current_timestamp_seconds instead.
|
||||
|
||||
Reference in New Issue
Block a user